# HG changeset patch # User Francisco J Ballesteros # Date 1332270887 -3600 # Node ID 49746e1699e1a03bfce9e8a2fe82ada5c3ab8f2f # Parent bc7aa6acf2c206ac3259480f8dcf83284759ea48 creepy: auth added and a fix for a bug found after injecting write faults during the sync process; plus other fixes if I don't remember correctly. R=nixiedev, quanstro CC=nix-dev http://codereview.appspot.com/5861043 diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/9p.c --- a/sys/src/cmd/creepy/9p.c Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/9p.c Tue Mar 20 20:14:47 2012 +0100 @@ -1,17 +1,4 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "dbg.h" -#include "dk.h" -#include "ix.h" -#include "net.h" -#include "fns.h" +#include "all.h" /* * 9p server for creepy @@ -64,11 +51,23 @@ return s; } +/* + * Ok if f is nil, for auth files. + */ static Qid mkqid(Memblk *f) { Qid q; - + static uvlong authgen; + + if(f == nil){ + authgen++; + q.type = QTAUTH; + q.path = authgen; + q.vers = 0; + return q; + } + q.path = f->d.id; q.vers = f->d.mtime; q.type = 0; @@ -122,27 +121,99 @@ } static void -rauth(Rpc*) +rauth(Rpc *rpc) { - /* BUG */ - error("no auth required"); + Fid *fid; + static char spec[] = "proto=p9any role=server"; + + if(noauth) + error("no auth required"); + + fid = newfid(rpc->cli, rpc->t.afid); + rpc->fid = fid; + + setfiduid(fid, rpc->t.uname); + + fid->omode = ORDWR; + fid->afd = open("/mnt/factotum/rpc", ORDWR); + if(fid->afd < 0) + error("factotum: %r"); + fid->rpc = auth_allocrpc(fid->afd); + if(fid->rpc == nil){ + close(fid->afd); + error("auth rpc: %r"); + } + if(auth_rpc(fid->rpc, "start", spec, strlen(spec)) != ARok){ + auth_freerpc(fid->rpc); + close(fid->afd); + error("auth_rpc start failed"); + } + rpc->r.qid = mkqid(nil); + d9print("factotum rpc started\n"); +} + +static long +xauthread(Fid *fid, long count, void *data) +{ + AuthInfo *ai; + + switch(auth_rpc(fid->rpc, "read", nil, 0)){ + case ARdone: + ai = auth_getinfo(fid->rpc); + if(ai == nil) + error("authread: info: %r"); + auth_freeAI(ai); + d9print("auth: %s: ok\n", usrname(fid->uid)); + fid->authok = 1; + return 0; + case ARok: + if(count < fid->rpc->narg) + error("authread: count too small"); + count = fid->rpc->narg; + memmove(data, fid->rpc->arg, count); + return count; + } + error("authread: phase error"); + return -1; } static void rattach(Rpc *rpc) { - Fid *fid; + Fid *fid, *afid; Path *p; Memblk *f; + char buf[ERRMAX]; fid = newfid(rpc->cli, rpc->t.fid); rpc->fid = fid; + afid = nil; + if(!noauth){ + afid = getfid(rpc->cli, rpc->t.afid); + if(catcherror()){ + putfid(afid); + error(nil); + } + if(afid->rpc == nil) + error("afid is not an auth fid"); + if(afid->authok == 0) + xauthread(afid, 0, buf); + } fidattach(fid, rpc->t.aname, rpc->t.uname); + if(!noauth){ + if(fid->uid != afid->uid) + error("auth uid mismatch"); + noerror(); + putfid(afid); + } p = fid->p; f = p->f[p->nf-1]; rwlock(f, Rd); rpc->r.qid = mkqid(f); rwunlock(f, Rd); + + if(rpc->cli->uid == -1) + rpc->cli->uid = rpc->fid->uid; } static void @@ -201,6 +272,9 @@ rpc->fid = getfid(rpc->cli, rpc->t.fid); fid = rpc->fid; + if(fid->rpc != nil) /* auth fids are always open */ + return; + rpc->r.iounit = rpc->cli->msize - IOHDRSZ; fidopen(rpc->fid, rpc->t.mode); f = fid->p->f[fid->p->nf-1]; @@ -218,6 +292,8 @@ fid = getfid(rpc->cli, rpc->t.fid); rpc->fid = fid; + if(fid->rpc != nil) + error("create on auth fid"); fidcreate(fid, rpc->t.name, rpc->t.mode, rpc->t.perm); p = fid->p; @@ -249,6 +325,20 @@ } static void +authread(Rpc *rpc) +{ + Fid *fid; + + fid = rpc->fid; + if(fid->rpc == nil) + error("authread: not an auth fid"); + rpc->r.data = (char*)rpc->data; + rpc->r.count = xauthread(fid, rpc->t.count, rpc->r.data); + putfid(fid); + rpc->fid = nil; +} + +static void rread(Rpc *rpc) { Fid *fid; @@ -256,6 +346,10 @@ fid = getfid(rpc->cli, rpc->t.fid); rpc->fid = fid; + if(fid->rpc != nil){ + authread(rpc); + return; + } if(rpc->t.count > rpc->cli->msize-IOHDRSZ) rpc->r.count = rpc->cli->msize-IOHDRSZ; rpc->r.data = (char*)rpc->data; @@ -265,6 +359,21 @@ } static void +authwrite(Rpc *rpc) +{ + Fid *fid; + + fid = rpc->fid; + if(fid->rpc == nil) + error("authwrite: not an auth fid"); + if(auth_rpc(fid->rpc, "write", rpc->t.data, rpc->t.count) != ARok) + error("authwrite: %r"); + rpc->r.count = rpc->t.count; + putfid(fid); + rpc->fid = nil; +} + +static void rwrite(Rpc *rpc) { Fid *fid; @@ -274,6 +383,10 @@ error("negative offset"); fid = getfid(rpc->cli, rpc->t.fid); rpc->fid = fid; + if(fid->rpc != nil){ + authwrite(rpc); + return; + } off = rpc->t.offset; rpc->r.count = fidwrite(fid, rpc->t.data, rpc->t.count, &off); } @@ -285,7 +398,14 @@ fid = getfid(rpc->cli, rpc->t.fid); rpc->fid = fid; - if(fid->omode != -1) + if(fid->rpc != nil){ + fid->omode = -1; + if(fid->rpc != nil) + auth_freerpc(fid->rpc); + fid->rpc = nil; + close(fid->afd); + fid->afd = -1; + }else if(fid->omode != -1) fidclose(fid); putfid(fid); putfid(fid); @@ -299,6 +419,8 @@ fid = getfid(rpc->cli, rpc->t.fid); rpc->fid = fid; + if(fid->rpc != nil) + error("remove on auth fid"); if(catcherror()){ dEprint("clunking %X:\n\t%r\n", fid); putfid(fid); @@ -324,6 +446,8 @@ fid = getfid(rpc->cli, rpc->t.fid); rpc->fid = fid; + if(fid->rpc != nil) + error("stat on auth fid"); xqlock(fid); if(catcherror()){ xqunlock(fid); @@ -372,6 +496,8 @@ error("convM2D: bad stat"); fid = getfid(rpc->cli, rpc->t.fid); rpc->fid = fid; + if(fid->rpc != nil) + error("wstat on auth fid"); xqlock(fid); if(catcherror()){ xqunlock(fid); @@ -521,7 +647,8 @@ nerr = nerrors(); - fspolicy(); + if(fsmemfree() < Mzerofree || fsdiskfree() < Dzerofree) + fspolicy(); rpc->r.tag = rpc->t.tag; @@ -578,6 +705,9 @@ replied(rpc); freerpc(rpc); + + fspolicy(); + dPprint("%s exiting\n", threadgetname()); if(nerrors() != nerr) diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/all.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/src/cmd/creepy/all.h Tue Mar 20 20:14:47 2012 +0100 @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conf.h" +#include "dbg.h" +#include "dk.h" +#include "ix.h" +#include "net.h" +#include "fns.h" diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/attr.c --- a/sys/src/cmd/creepy/attr.c Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/attr.c Tue Mar 20 20:14:47 2012 +0100 @@ -1,16 +1,4 @@ -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "dbg.h" -#include "dk.h" -#include "ix.h" -#include "net.h" -#include "fns.h" +#include "all.h" /* * Attribute handling diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/cfg.c --- a/sys/src/cmd/creepy/cfg.c Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/cfg.c Tue Mar 20 20:14:47 2012 +0100 @@ -1,16 +1,4 @@ -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "dbg.h" -#include "dk.h" -#include "ix.h" -#include "net.h" -#include "fns.h" +#include "all.h" /* * Locking is coarse, only functions used from outside @@ -42,8 +30,6 @@ /* * The uid numbers are irrelevant, they are rewritten. - * XXX: There's code assuming the positions of these users... - * search for it and make it search the user if needed or use a global for it. */ static char *defaultusers = "1:none::\n" @@ -732,6 +718,12 @@ xrwunlock(&ulk, Rd); } +static void +cwho(int, char**) +{ + consprintclients(); +} + static void chelp(int, char**); static Cmd cmds[] = @@ -752,6 +744,7 @@ {"reclaim", creclaim, 1, "reclaim"}, {"allow", callow, 0, "allow [uid]"}, {"disallow", callow, 0, "disallow [uid]"}, + {"who", cwho, 1, "who"}, {"?", chelp, 1, "?"}, }; diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/dblk.c --- a/sys/src/cmd/creepy/dblk.c Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/dblk.c Tue Mar 20 20:14:47 2012 +0100 @@ -1,16 +1,4 @@ -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "dbg.h" -#include "dk.h" -#include "ix.h" -#include "net.h" -#include "fns.h" +#include "all.h" /* * disk blocks, built upon memory blocks provided by mblk.c @@ -76,20 +64,6 @@ } } -/* - * BUG: the free list of blocks using entries in the ref blocks - * shouldn't span all those blocks as it does now. To prevent - * massive loses of free blocks each DBref block should keep its own - * little free list, and all blocks with free entries should be linked - * in the global list. - * This would keep locality and make it less likely that a failure in the - * middle of a sync destroyes the entire list. - * - * TODO: If there's a bad address in the free list, we fatal. - * we could throw away the entire free list and continue operation, after - * issuing a warning so the user knows. - */ - static daddrt newblkaddr(void) { @@ -459,12 +433,12 @@ if(fs->fzsuper->d.oddrefs) addr += Dblksz; } - dWprint("dbwrite at d%#010ullx %H\n",addr, b); + dWprint("dbwriting at d%#010ullx %H\n",addr, b); nb = hosttodisk(b); - if(swwriteerr != 0 && ++nw % swwriteerr == 0){ + if(swwriteerr != 0 && ++nw > swwriteerr){ written(b); /* what can we do? */ mbput(nb); - fprint(2, "%s: dbwrite: software fault injected\n", argv0); + fprint(2, "%s: WRITE FAULT INJECTED\n", argv0); error("dbwrite: sw fault"); } if(pwrite(fs->fd, &nb->d, sizeof nb->d, addr) != Dblksz){ @@ -494,9 +468,9 @@ if(b->type == DBref && fs->super->d.oddrefs) addr += Dblksz; for(tot = 0; tot < Dblksz; tot += n){ - if(swreaderr != 0 && ++nr % swreaderr == 0){ - fprint(2, "%s: dbread: software fault injected\n", argv0); - error("dbwrite: sw fault"); + if(swreaderr != 0 && ++nr > swreaderr){ + fprint(2, "%s: READ FAULT INJECTED\n", argv0); + error("dbread: sw fault"); } n = pread(fs->fd, p+tot, Dblksz-tot, addr + tot); if(n == 0) diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/ix.c --- a/sys/src/cmd/creepy/ix.c Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/ix.c Tue Mar 20 20:14:47 2012 +0100 @@ -1,17 +1,4 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "dbg.h" -#include "dk.h" -#include "ix.h" -#include "net.h" -#include "fns.h" +#include "all.h" /* * ix server for creepy @@ -520,7 +507,8 @@ dPprint("%s started\n", threadgetname()); do{ - fspolicy(); + if(fsmemfree() < Mzerofree || fsdiskfree() < Dzerofree) + fspolicy(); nerr = nerrors(); rpc->xr.type = rpc->xt.type + 1; @@ -571,6 +559,9 @@ freeixrpc(rpc); replied(rpc0); freeixrpc(rpc0); + + fspolicy(); + dPprint("%s exiting\n", threadgetname()); return nil; } diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/ixcall.c --- a/sys/src/cmd/creepy/ixcall.c Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/ixcall.c Tue Mar 20 20:14:47 2012 +0100 @@ -1,12 +1,4 @@ -#include -#include -#include -#include - -#include "conf.h" -#include "dk.h" -#include "ix.h" -#include "net.h" +#include "all.h" static char* cname[CMAX] = { diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/mkfile --- a/sys/src/cmd/creepy/mkfile Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/mkfile Tue Mar 20 20:14:47 2012 +0100 @@ -28,6 +28,7 @@ fns.h\ ix.h\ net.h\ + all.h\ # not ready for install BIN=. diff -r bc7aa6acf2c2 -r 49746e1699e1 sys/src/cmd/creepy/tools.c --- a/sys/src/cmd/creepy/tools.c Tue Mar 20 20:14:04 2012 +0100 +++ b/sys/src/cmd/creepy/tools.c Tue Mar 20 20:14:47 2012 +0100 @@ -1,16 +1,4 @@ -#include -#include -#include -#include -#include -#include - -#include "conf.h" -#include "dbg.h" -#include "dk.h" -#include "ix.h" -#include "net.h" -#include "fns.h" +#include "all.h" /* * Misc tools.