static Auth * auth_plain(char *windom, char *keyp, uchar *chal, int len) { UserPasswd *up; static Auth *ap; USED(chal, len); up = auth_getuserpasswd(auth_getkey, "windom=%s proto=pass service=cifs %s", windom, keyp); if(! up) sysfatal("cannot get key - %r"); ap = emalloc9p(sizeof(Auth)); memset(ap, 0, sizeof(ap)); ap->user = estrdup9p(up->user); ap->windom = estrdup9p(windom); ap->resp[0] = estrdup9p(up->passwd); ap->len[0] = strlen(up->passwd); memset(up->passwd, 0, strlen(up->passwd)); free(up); return ap; }
static Auth * auth_lm_and_ntlm(char *windom, char *keyp, uchar *chal, int len) { int err; char user[64]; Auth *ap; MSchapreply mcr; err = auth_respond(chal, len, user, sizeof user, &mcr, sizeof mcr, auth_getkey, "windom=%s proto=mschap role=client service=cifs %s", windom, keyp); if(err == -1) sysfatal("cannot get key - %r"); ap = emalloc9p(sizeof(Auth)); memset(ap, 0, sizeof(ap)); ap->user = estrdup9p(user); ap->windom = estrdup9p(windom); /* LM response */ ap->len[0] = sizeof(mcr.LMresp); ap->resp[0] = emalloc9p(ap->len[0]); memcpy(ap->resp[0], mcr.LMresp, ap->len[0]); /* NTLM response */ ap->len[1] = sizeof(mcr.NTresp); ap->resp[1] = emalloc9p(ap->len[1]); memcpy(ap->resp[1], mcr.NTresp, ap->len[1]); return ap; }
static void I2D(Dir *d, Share *sp, char *path, FInfo *fi) { char *name; if((name = strrchr(fi->name, '\\')) != nil) name++; else name = fi->name; d->name = estrdup9p(name); d->type = 'C'; d->dev = sp->tid; d->uid = estrdup9p("bill"); d->gid = estrdup9p("trog"); d->muid = estrdup9p("boyd"); d->atime = fi->accessed; d->mtime = fi->written; if(fi->attribs & ATTR_READONLY) d->mode = 0444; else d->mode = 0666; d->length = fi->size; d->qid = mkqid(path, fi->attribs & ATTR_DIRECTORY, fi->changed, 0, 0); if(fi->attribs & ATTR_DIRECTORY){ d->length = 0; d->mode |= DMDIR|0111; } }
int fill(Dir *dir, int path) { ulong mode; if(grepstate == Waiting) mode = 0200; else mode = 0400; switch(path){ case Qroot: dir->qid = (Qid){Qroot, 0, QTDIR}; dir->mode = 0755 | DMDIR; dir->atime = starttime; dir->mtime = starttime; dir->name = estrdup9p("/"); break; case Qgrep: dir->qid = (Qid){Qgrep, grepvers, QTFILE}; dir->mode = mode; dir->atime = grepatime; dir->mtime = grepmtime; dir->name = estrdup9p(grepname); break; default: return -1; } dir->uid = estrdup9p(grepuser); dir->gid = estrdup9p("glenda"); dir->muid = estrdup9p("ron"); return 0; }
static void sstat(Srv *srv, Req *r) { if((r->fid = lookupfid(srv->fpool, r->ifcall.fid)) == nil){ respond(r, Eunknownfid); return; } if(r->fid->file){ /* should we rlock the file? */ r->d = r->fid->file->Dir; if(r->d.name) r->d.name = estrdup9p(r->d.name); if(r->d.uid) r->d.uid = estrdup9p(r->d.uid); if(r->d.gid) r->d.gid = estrdup9p(r->d.gid); if(r->d.muid) r->d.muid = estrdup9p(r->d.muid); } if(srv->stat) srv->stat(r); else if(r->fid->file) respond(r, nil); else respond(r, Enostat); }
void upd_names(Session *s, Share *sp, char *path, Dir *d) { int fh, result; char *usid, *gsid; FInfo fi; if(d->uid) free(d->uid); if(d->gid) free(d->gid); if((fh = CIFS_NT_opencreate(s, sp, path, 0, 0, 0, READ_CONTROL, FILE_SHARE_ALL, FILE_OPEN, &result, &fi)) == -1){ d->uid = estrdup9p("unknown"); d->gid = estrdup9p("unknown"); return; } usid = nil; gsid = nil; TNTquerysecurity(s, sp, fh, &usid, &gsid); d->uid = sid2name(usid); d->gid = sid2name(gsid); if(fh != -1) CIFSclose(s, sp, fh); }
void main(int argc, char **argv) { char *file; file = nil; quotefmtinstall(); time0 = time(0); if(NPTR != BLKSZ/sizeof(void*)) sysfatal("unexpected pointer size"); ARGBEGIN{ case 'D': chatty9p++; break; case 'f': file = EARGF(usage()); break; case 'r': rdonly = 1; break; case 's': srvname = EARGF(usage()); break; case 'm': mtpt = EARGF(usage()); break; default: usage(); }ARGEND if(argc > 1) usage(); if(argc == 1) sdname = argv[0]; if(file){ if((fd = open(file, rdonly ? OREAD : ORDWR)) < 0) sysfatal("open %s: %r", file); } inquiry = estrdup9p(inquiry); tab[0].name = estrdup9p("data"); tab[0].inuse = 1; tab[0].mode = 0666; postmountsrv(&fs, srvname, mtpt, MBEFORE); exits(nil); }
static void fscreate(Req* r) { File* file; Query* q; char* name; char* uid; int mode; File* f; file = r->fid->file; name = r->ifcall.name; uid = r->fid->uid; mode = r->fid->file->dir.mode & 0x777 & r->ifcall.perm; mode |= (r->ifcall.perm & ~0x777); if(mode&DMDIR){ respond(r, "queries cannot be directories"); return; } if(f = createfile(file, name, uid, mode, nil)){ q = emalloc9p(sizeof *q); q->text = estrdup9p(""); q->expr = nil; f->aux = q; closefile(r->fid->file); r->fid->file = f; r->ofcall.qid = f->dir.qid; respond(r, nil); } else respond(r, "problem creating file"); }
/* * used only for root dir and shares */ static void V2D(Dir *d, Qid qid, char *name) { memset(d, 0, sizeof(Dir)); d->type = 'C'; d->dev = 1; d->name = estrdup9p(name); d->uid = estrdup9p("bill"); d->muid = estrdup9p("boyd"); d->gid = estrdup9p("trog"); d->mode = 0755 | DMDIR; d->atime = time(nil); d->mtime = d->atime; d->length = 0; d->qid = qid; }
static char* fsclone(Fid *ofid, Fid *fid) { Aux *oa = ofid->aux; Aux *a = emalloc9p(sizeof(Aux)); fid->aux = a; memset(a, 0, sizeof(Aux)); a->sh = -1; a->fh = -1; a->sp = oa->sp; a->path = estrdup9p(oa->path); if(Auxroot){ a->prev = Auxroot; a->next = Auxroot->next; Auxroot->next->prev = a; Auxroot->next = a; } else { Auxroot = a; a->next = a; a->prev = a; } return nil; }
int addpart(char *name, vlong start, vlong end) { int i; if(start < 0 || start > end || end > nsect){ werrstr("bad partition boundaries"); return -1; } for(i=0; i<nelem(tab); i++) if(tab[i].inuse == 0) break; if(i == nelem(tab)){ werrstr("no free partition slots"); return -1; } free(tab[i].name); tab[i].inuse = 1; tab[i].name = estrdup9p(name); tab[i].offset = start; tab[i].length = end - start; tab[i].mode = ctlmode; tab[i].vers++; return 0; }
static void swalk(Srv *srv, Req *r) { if((r->fid = lookupfid(srv->fpool, r->ifcall.fid)) == nil){ respond(r, Eunknownfid); return; } if(r->fid->omode != -1){ respond(r, "cannot clone open fid"); return; } if(r->ifcall.nwname && !(r->fid->qid.type&QTDIR)){ respond(r, Ewalknodir); return; } if(r->ifcall.fid != r->ifcall.newfid){ if((r->newfid = allocfid(srv->fpool, r->ifcall.newfid)) == nil){ respond(r, Edupfid); return; } r->newfid->uid = estrdup9p(r->fid->uid); }else{ incref(&r->fid->ref); r->newfid = r->fid; } if(r->fid->file){ filewalk(r); }else if(srv->walk1) walkandclone(r, oldwalk1, oldclone, srv); else if(srv->walk) srv->walk(r); else sysfatal("no walk function, no file trees"); }
static void sattach(Srv *srv, Req *r) { if((r->fid = allocfid(srv->fpool, r->ifcall.fid)) == nil){ respond(r, Edupfid); return; } r->afid = nil; if(r->ifcall.afid != NOFID && (r->afid = lookupfid(srv->fpool, r->ifcall.afid)) == nil){ respond(r, Eunknownfid); return; } r->fid->uid = estrdup9p(r->ifcall.uname); if(srv->tree){ r->fid->file = srv->tree->root; incref(r->fid->file); r->ofcall.qid = r->fid->file->qid; r->fid->qid = r->ofcall.qid; } if(srv->attach) srv->attach(r); else respond(r, nil); return; }
void auth9p(Req *r) { char *spec; Afid *afid; afid = emalloc9p(sizeof(Afid)); afid->afd = open("/mnt/factotum/rpc", ORDWR); if(afid->afd < 0) goto error; if((afid->rpc = auth_allocrpc(afid->afd)) == nil) goto error; if(r->ifcall.uname[0] == 0) goto error; afid->uname = estrdup9p(r->ifcall.uname); afid->aname = estrdup9p(r->ifcall.aname); spec = r->srv->keyspec; if(spec == nil) spec = "proto=p9any role=server"; if(auth_rpc(afid->rpc, "start", spec, strlen(spec)) != ARok) goto error; r->afid->qid.type = QTAUTH; r->afid->qid.path = ++authgen; r->afid->qid.vers = 0; r->afid->omode = ORDWR; r->ofcall.qid = r->afid->qid; r->afid->aux = afid; respond(r, nil); return; error: if(afid->rpc) auth_freerpc(afid->rpc); if(afid->uname) free(afid->uname); if(afid->aname) free(afid->aname); if(afid->afd >= 0) close(afid->afd); free(afid); responderror(r); }
void fsattach(Req *r) { if(grepuser == nil) grepuser = estrdup9p(r->ifcall.uname); r->fid->qid = (Qid){Qroot, 0, QTDIR}; r->ofcall.qid = r->fid->qid; respond(r, nil); }
int rootgen(int off, Dir *d, void*) { memset(d, 0, sizeof *d); d->atime = time0; d->mtime = time0; if(off == 0){ d->name = estrdup9p(sdname); d->mode = DMDIR|0777; d->qid.path = Qdir; d->qid.type = QTDIR; d->uid = estrdup9p("disksim"); d->gid = estrdup9p("disksim"); d->muid = estrdup9p(""); return 0; } return -1; }
Tree* alloctree(char *uid, char *gid, uint32_t mode, void (*destroy)(File*)) { char *muid; Tree *t; File *f; t = emalloc9p(sizeof *t); f = allocfile(); f->Dir.name = estrdup9p("/"); if(uid == nil){ uid = getuser(); if(uid == nil) uid = "none"; } uid = estrdup9p(uid); if(gid == nil) gid = estrdup9p(uid); else gid = estrdup9p(gid); muid = estrdup9p(uid); f->Dir.qid = (Qid){0, 0, QTDIR}; f->Dir.length = 0; f->Dir.atime = f->Dir.mtime = time(0); f->Dir.mode = DMDIR | mode; f->tree = t; f->parent = f; f->Dir.uid = uid; f->Dir.gid = gid; f->Dir.muid = muid; incref(&f->Ref); t->root = f; t->qidgen = 0; t->dirqidgen = 1; if(destroy == nil) destroy = nop; t->destroy = destroy; return t; }
static void tfilestat(Req *r, char *path, vlong length) { memset(&r->d, 0, sizeof(r->d)); r->d.uid = estrdup9p("tftp"); r->d.gid = estrdup9p("tftp"); r->d.name = estrdup9p(basename(path)); r->d.atime = r->d.mtime = time0; r->d.length = length; r->d.qid.path = r->fid->qid.path; if(r->fid->qid.path & Qdata){ r->d.qid.type = 0; r->d.mode = 0555; } else { r->d.qid.type = QTDIR; r->d.mode = DMDIR|0555; } respond(r, nil); }
static int dirgen(int i, Dir *d, void*) { if(i >= ntab) return -1; memset(d, 0, sizeof *d); d->qid.type = QTDIR; d->uid = estrdup9p("sys"); d->gid = estrdup9p("sys"); d->mode = DMDIR|0555; d->length = 0; if(i == -1){ d->name = estrdup9p("/"); d->atime = d->mtime = time0; }else{ d->qid.path = tab[i].qid; d->name = estrdup9p(tab[i].name); d->atime = d->mtime = tab[i].time; } return 0; }
static char * sid2name(char *sid) { int i; char *rid; if(sid == nil || (rid = strrchr(sid, '-')) == nil || *++rid == 0) return estrdup9p("-"); for(i = 0; i < nelem(known); i++){ if(strcmp(known[i].auth, sid) == 0 && known[i].rid == nil) return estrdup9p(known[i].name); if(strlen(known[i].auth) < strlen(sid) && strncmp(known[i].auth, sid, strlen(known[i].auth)) == 0 && known[i].rid && strcmp(known[i].rid, rid) == 0) return estrdup9p(known[i].name); } return estrdup9p(rid); }
static char* fsmkuid(char *s) { if(s){ char *x; while(x = strchr(s, '<')) s = x+1; s = estrdup9p(s); if(x = strchr(s, '>')) *x = 0; if(x = strchr(s, '@')) *x = 0; if(x = strchr(s, '\n')) *x = 0; } if(s == nil || *s == 0){ free(s); s = estrdup9p("hgfs"); } return s; }
int dirgen(int off, Dir *d, void*) { int n, j; memset(d, 0, sizeof *d); d->atime = time0; d->mtime = time0; if(off == 0){ d->name = estrdup9p("ctl"); d->mode = ctlmode; d->qid.path = Qctl; goto Have; } off--; n = 0; for(j=0; j<nelem(tab); j++){ if(tab[j].inuse==0) continue; if(n == off){ d->name = estrdup9p(tab[j].name); d->length = tab[j].length*sectsize; d->mode = tab[j].mode; d->qid.path = Qpart+j; d->qid.vers = tab[j].vers; goto Have; } n++; } return -1; Have: d->uid = estrdup9p("disksim"); d->gid = estrdup9p("disksim"); d->muid = estrdup9p(""); return 0; }
int dirgen(int off, Dir *d, void*) { int n; Part *p; memset(d, 0, sizeof *d); d->atime = time0; d->mtime = time0; if(off == 0){ d->name = estrdup9p("ctl"); d->mode = ctlmode; d->qid.path = Qctl; goto Have; } off--; n = 0; for(p = tab; p < tab + nelem(tab); p++, n++){ if(!p->inuse) continue; if(off-- == 0){ d->name = estrdup9p(p->name); d->length = p->length*sectsize; d->mode = p->mode; d->qid.path = Qpart + p - tab; d->qid.vers = p->vers; goto Have; } } return -1; Have: d->uid = estrdup9p("partfs"); d->gid = estrdup9p("partfs"); d->muid = estrdup9p(""); return 0; }
int dirgeninfo(int slot, Dir *d) { if(slot < 0 || slot > nelem(Infdir)) return -1; memset(d, 0, sizeof(Dir)); d->type = 'N'; d->dev = 99; d->name = estrdup9p(Infdir[slot].name); d->uid = estrdup9p("other"); d->muid = estrdup9p("other"); d->gid = estrdup9p("other"); d->mode = 0666; d->atime = time(0); d->mtime = d->atime; d->qid = mkqid(Infdir[slot].name, 0, 1, Pinfo, slot); d->qid.vers = 1; d->qid.path = slot; d->qid.type = 0; return 0; }
static char* fswalk1(Fid *fid, char *name, void*) { int i; Tab *t; vlong h; if(fid->qid.path != 0){ /* nothing in child directory */ if(strcmp(name, "..") == 0){ if((t = findtab(fid->qid.path)) != nil) t->ref--; fid->qid.path = 0; return nil; } return "path not found"; } /* root */ if(strcmp(name, "..") == 0) return nil; for(i=0; i<ntab; i++) if(strcmp(tab[i].name, name) == 0){ tab[i].ref++; fid->qid.path = tab[i].qid; return nil; } h = hash(name); if(findtab(h) != nil) return "hash collision"; /* create it */ if(ntab == mtab){ if(mtab == 0) mtab = 16; else mtab *= 2; tab = erealloc9p(tab, sizeof(tab[0])*mtab); } tab[ntab].qid = h; fid->qid.path = tab[ntab].qid; tab[ntab].name = estrdup9p(name); tab[ntab].time = time(0); tab[ntab].ref = 1; ntab++; return nil; }
void fsstat(Req *r) { int q; Dir *d; Part *p; d = &r->d; memset(d, 0, sizeof *d); d->qid = r->fid->qid; d->atime = d->mtime = time0; q = r->fid->qid.path; switch(q){ case Qroot: d->name = estrdup9p("/"); d->mode = DMDIR|0777; break; case Qdir: d->name = estrdup9p(sdname); d->mode = DMDIR|0777; break; case Qctl: d->name = estrdup9p("ctl"); d->mode = 0666; break; default: q -= Qpart; if(q < 0 || q > nelem(tab) || tab[q].inuse == 0 || r->fid->qid.vers != tab[q].vers){ respond(r, "partition no longer exists"); return; } p = &tab[q]; d->name = estrdup9p(p->name); d->length = p->length * sectsize; d->mode = p->mode; break; } d->uid = estrdup9p("partfs"); d->gid = estrdup9p("partfs"); d->muid = estrdup9p(""); respond(r, nil); }
static char * newpath(char *path, char *name) { char *p, *q; assert((p = strrchr(path, '/')) != nil); if(strcmp(name, "..") == 0){ if(p == path) return estrdup9p("/"); q = emalloc9p((p-path)+1); strecpy(q, q+(p-path)+1, path); return q; } if(strcmp(path, "/") == 0) return smprint("/%s", name); return smprint("%s/%s", path, name); }
char* readhttphdr(Biobuf *netbio, vlong *size) { char *s, *stat; stat = nil; while((s = Brdstr(netbio, '\n', 1)) != nil && s[0] != '\r' && s[0] != '\0'){ if(stat == nil) stat = estrdup9p(s); if(strncmp(s, "Content-Length: ", 16) == 0 && size != nil) *size = atoll(s + 16); free(s); } if(stat) nocr(stat); return stat; }
static char* fsclone(Fid *oldfid, Fid *newfid) { Revfile *orf, *rf; rf = nil; if(orf = oldfid->aux){ rf = emalloc9p(sizeof(*rf)); *rf = *orf; if(rf->rlog) incref(rf->rlog); if(rf->tree) incref(rf->tree); if(rf->fd >= 0) rf->fd = dup(rf->fd, -1); if(rf->buf) rf->buf = estrdup9p(rf->buf); } newfid->aux = rf; return nil; }
File* walkfile(File *f, char *path) { char *os, *s, *nexts; if(strchr(path, '/') == nil) return walkfile1(f, path); /* avoid malloc */ os = s = estrdup9p(path); for(; *s; s=nexts){ if((nexts = strchr(s, '/')) != nil) *nexts++ = '\0'; else nexts = s+strlen(s); f = walkfile1(f, s); if(f == nil) break; } free(os); return f; }