void cmd_create(void) { int uid, gid, err; int32_t perm; char oelem[NAMELEN]; char name[NAMELEN]; if(err = con_clone(FID1, FID2)){ cprint("clone failed: %s\n", errstring[err]); return; } if(skipbl(1)){ cprint("skipbl\n"); return; } oelem[0] = 0; while(nextelem()) { if(oelem[0]) if(err = con_walk(FID2, oelem)){ cprint("walk failed: %s\n", errstring[err]); return; } memmove(oelem, elem, NAMELEN); } if(skipbl(1)) return; uid = strtouid(cname(name)); if(uid == 0){ cprint("unknown user %s\n", name); return; } gid = strtouid(cname(name)); if(gid == 0){ cprint("unknown group %s\n", name); return; } perm = number(0777, 8); skipbl(0); for(; *cons.arg; cons.arg++){ if(*cons.arg == 'l') perm |= PLOCK; else if(*cons.arg == 'a') perm |= PAPND; else if(*cons.arg == 'd') perm |= PDIR; else break; } err = con_create(FID2, elem, uid, gid, perm, 0); if(err) cprint("can't create %s: %s\n", elem, errstring[err]); }
int authread(File *file, uchar *data, int count) { AuthInfo *ai; AuthRpc *rpc; Chan *chan; chan = file->cp; if((rpc = file->auth) == nil){ snprint(chan->err, sizeof(chan->err), "not an auth fid"); return -1; } switch(auth_rpc(rpc, "read", nil, 0)){ default: snprint(chan->err, sizeof(chan->err), "authread: auth protocol not finished"); return -1; case ARdone: if((ai = auth_getinfo(rpc)) == nil) goto Phase; file->uid = strtouid(ai->cuid); if(file->uid < 0){ snprint(chan->err, sizeof(chan->err), "unknown user '%s'", ai->cuid); auth_freeAI(ai); return -1; } auth_freeAI(ai); return 0; case ARok: if(count < rpc->narg){ snprint(chan->err, sizeof(chan->err), "not enough data in auth read"); return -1; } memmove(data, rpc->arg, rpc->narg); return rpc->narg; case ARphase: Phase: rerrstr(chan->err, sizeof(chan->err)); return -1; } }
void cmd_users(int argc, char *argv[]) { Uid *ui; int u, g, o, line; char *file, *p, *uname, *ulead, *unext; file = "/adm/users"; if(argc > 1) file = argv[1]; if(strcmp(file, "default") == 0) { setminusers(); return; } uidgc.uidbuf = getbuf(devnone, Cuidbuf, 0); if(walkto(file) || con_open(FID2, 0)) { print("cmd_users: cannot access %s\n", file); putbuf(uidgc.uidbuf); return; } uidgc.flen = 0; uidgc.find = 0; cons.offset = 0; cons.nuid = 0; u = 0; line = 0; while(readln(buf, sizeof buf) != 0) { line++; p = getword(buf, L':', "no : after number", line); if(p == nil) continue; ulead = getword(p, L':', "no : after name", line); if(ulead == nil) continue; if(strlen(p) > NAMELEN-1) { print("%s: name too long\n", p); continue; } strcpy(uid[u].name, p); uid[u].uid = number(buf, 0, 10); uid[u].lead = 0; uid[u].ngrp = 0; u++; if(u >= conf.nuid) { print("conf.nuid too small (%ld)\n", conf.nuid); break; } } /* Sorted by uid for use in uidtostr */ wlock(&uidgc.uidlock); qsort(uid, u, sizeof(uid[0]), byuid); cons.nuid = u; wunlock(&uidgc.uidlock); /* Parse group table */ uidgc.flen = 0; uidgc.find = 0; cons.offset = 0; cons.ngid = 0; g = 0; line = 0; while(readln(buf, sizeof buf) != 0) { line++; uname = getword(buf, L':', 0, 0); /* skip number */ if(uname == nil) continue; ulead = getword(uname, L':', 0, 0); /* skip name */ if(ulead == nil) continue; p = getword(ulead, L':', "no : after leader", line); if(p == nil) continue; ui = uidpstr(uname); if(ui == nil) continue; /* set to owner if name not known */ ui->lead = 0; if(ulead[0]) { o = strtouid(ulead); if(o >= 0) ui->lead = o; else ui->lead = ui->uid; } ui->gtab = &gidspace[g]; ui->ngrp = 0; while (p != nil) { unext = getword(p, L',', 0, 0); o = strtouid(p); if(o >= 0) { gidspace[g++] = o; ui->ngrp++; } p = unext; } } cons.ngid = g; putbuf(uidgc.uidbuf); print("%d uids read, %d groups used\n", cons.nuid, cons.ngid); }
void f_attach(Chan *cp, Oldfcall *in, Oldfcall *ou) { Iobuf *p; Dentry *d; File *f; int u; Filsys *fs; int32_t raddr; if(CHAT(cp)) { print("c_attach %d\n", cp->chan); print(" fid = %d\n", in->fid); print(" uid = %s\n", in->uname); print(" arg = %s\n", in->aname); } ou->qid = QID9P1(0,0); ou->fid = in->fid; if(!in->aname[0]) /* default */ strncpy(in->aname, filesys[0].name, sizeof(in->aname)); p = 0; f = filep(cp, in->fid, 1); if(!f) { ou->err = Efid; goto out; } u = -1; if(cp != cons.chan){ if(authorize(cp, in, ou) == 0 || strcmp(in->uname, "adm") == 0){ ou->err = Eauth; goto out; } u = strtouid(in->uname); if(u < 0){ ou->err = Ebadu; goto out; } } fs = fsstr(in->aname); if(fs == 0) { ou->err = Ebadspc; goto out; } raddr = getraddr(fs->dev); p = getbuf(fs->dev, raddr, Bread); d = getdir(p, 0); if(!d || checktag(p, Tdir, QPROOT) || !(d->mode & DALLOC)) { ou->err = Ealloc; goto out; } f->uid = u; if(iaccess(f, d, DREAD)) { ou->err = Eaccess; goto out; } accessdir(p, d, FREAD); mkqid(&f->qid, d, 1); f->fs = fs; f->addr = raddr; f->slot = 0; f->open = 0; freewp(f->wpath); f->wpath = 0; mkqid9p1(&ou->qid, &f->qid); out: if(p) putbuf(p); if(f) { qunlock(f); if(ou->err) freefp(f); } }