diff options
| -rw-r--r-- | sys/man/8/fs | 6 | ||||
| -rw-r--r-- | sys/src/cmd/cwfs/9p1.c | 62 | ||||
| -rw-r--r-- | sys/src/cmd/cwfs/9p2.c | 59 | ||||
| -rw-r--r-- | sys/src/cmd/cwfs/all.h | 6 | ||||
| -rw-r--r-- | sys/src/cmd/cwfs/con.c | 26 | ||||
| -rw-r--r-- | sys/src/cmd/cwfs/config.c | 3 | ||||
| -rw-r--r-- | sys/src/cmd/cwfs/portfns.h | 3 | ||||
| -rw-r--r-- | sys/src/cmd/cwfs/sub.c | 35 |
8 files changed, 101 insertions, 99 deletions
diff --git a/sys/man/8/fs b/sys/man/8/fs index 7ec89abe7..e65d208cc 100644 --- a/sys/man/8/fs +++ b/sys/man/8/fs @@ -9,6 +9,7 @@ fs, exsort \- file server maintenance ] .PP .B allow +.RI [ uid ] .PP .B arp .I subcommand @@ -158,7 +159,10 @@ incorrect or incomplete parameters. .PP .I Allow disables permission checking and allows -.BR wstat . +.BR wstat +for the specified +.I uid +or for any user if omited. This may help in initializing a file system. Use this with caution. .PP diff --git a/sys/src/cmd/cwfs/9p1.c b/sys/src/cmd/cwfs/9p1.c index 3c9a0a190..827a541d7 100644 --- a/sys/src/cmd/cwfs/9p1.c +++ b/sys/src/cmd/cwfs/9p1.c @@ -57,7 +57,7 @@ f_session(Chan *cp, Fcall *in, Fcall *ou) memmove(aip->rchal, in->chal, sizeof(aip->rchal)); mkchallenge(aip); memmove(ou->chal, aip->chal, sizeof(ou->chal)); - if(noauth || wstatallow) + if(noauth) memset(ou->authid, 0, sizeof(ou->authid)); else memmove(ou->authid, nvr.authid, sizeof(ou->authid)); @@ -78,7 +78,7 @@ authorize(Chan *cp, Fcall *in, Fcall *ou) ulong bit; Authinfo *aip; - if(noauth || wstatallow) /* set to allow entry during boot */ + if(noauth) return 1; if(strcmp(in->uname, "none") == 0) @@ -245,7 +245,7 @@ f_attach(Chan *cp, Fcall *in, Fcall *ou) ou->err = Ealloc; goto out; } - if (iaccess(f, d, DEXEC) || + if(iaccess(f, d, DEXEC) || f->uid == 0 && fs->dev->type == Devro) { /* * 'none' not allowed on dump @@ -370,7 +370,7 @@ f_walk(Chan *cp, Fcall *in, Fcall *ou) } if(ou->err = mkqidcmp(&f->qid, d)) goto out; - if(cp != cons.chan && iaccess(f, d, DEXEC)) { + if(iaccess(f, d, DEXEC)) { ou->err = Eaccess; goto out; } @@ -469,7 +469,7 @@ f_open(Chan *cp, Fcall *in, Fcall *ou) File *f; Tlock *t; Qid qid; - int ro, fmod, wok; + int ro, fmod; if(CHAT(cp)) { fprint(2, "c_open %d\n", cp->chan); @@ -477,10 +477,6 @@ f_open(Chan *cp, Fcall *in, Fcall *ou) fprint(2, "\tmode = %o\n", in->mode); } - wok = 0; - if(cp == cons.chan || writeallow) - wok = 1; - p = 0; f = filep(cp, in->fid, 0); if(!f) { @@ -528,14 +524,13 @@ f_open(Chan *cp, Fcall *in, Fcall *ou) switch(in->mode & 7) { case OREAD: - if(iaccess(f, d, DREAD) && !wok) + if(iaccess(f, d, DREAD)) goto badaccess; fmod = FREAD; break; case OWRITE: - if((d->mode & DDIR) || - (iaccess(f, d, DWRITE) && !wok)) + if((d->mode & DDIR) || iaccess(f, d, DWRITE)) goto badaccess; if(ro) { ou->err = Eronly; @@ -545,9 +540,7 @@ f_open(Chan *cp, Fcall *in, Fcall *ou) break; case ORDWR: - if((d->mode & DDIR) || - (iaccess(f, d, DREAD) && !wok) || - (iaccess(f, d, DWRITE) && !wok)) + if((d->mode & DDIR) || iaccess(f, d, DREAD) || iaccess(f, d, DWRITE)) goto badaccess; if(ro) { ou->err = Eronly; @@ -557,8 +550,7 @@ f_open(Chan *cp, Fcall *in, Fcall *ou) break; case OEXEC: - if((d->mode & DDIR) || - (iaccess(f, d, DEXEC) && !wok)) + if((d->mode & DDIR) || iaccess(f, d, DEXEC)) goto badaccess; fmod = FREAD; break; @@ -568,8 +560,7 @@ f_open(Chan *cp, Fcall *in, Fcall *ou) goto out; } if(in->mode & OTRUNC) { - if((d->mode & DDIR) || - (iaccess(f, d, DWRITE) && !wok)) + if((d->mode & DDIR) || iaccess(f, d, DWRITE)) goto badaccess; if(ro) { ou->err = Eronly; @@ -617,7 +608,7 @@ f_create(Chan *cp, Fcall *in, Fcall *ou) Iobuf *p, *p1; Dentry *d, *d1; File *f; - int slot, slot1, fmod, wok; + int slot, slot1, fmod; Off addr, addr1, path; Qid qid; Tlock *t; @@ -632,10 +623,6 @@ f_create(Chan *cp, Fcall *in, Fcall *ou) fprint(2, "\tmode = %o\n", in->mode); } - wok = 0; - if(cp == cons.chan || writeallow) - wok = 1; - p = 0; f = filep(cp, in->fid, 0); if(!f) { @@ -659,7 +646,7 @@ f_create(Chan *cp, Fcall *in, Fcall *ou) ou->err = Edir2; goto out; } - if(iaccess(f, d, DWRITE) && !wok) { + if(iaccess(f, d, DWRITE)) { ou->err = Eaccess; goto out; } @@ -1118,7 +1105,7 @@ out: } int -doremove(File *f, int wok) +doremove(File *f) { Iobuf *p, *p1; Dentry *d, *d1; @@ -1144,7 +1131,7 @@ doremove(File *f, int wok) err = Ephase; goto out; } - if(iaccess(f, d1, DWRITE) && !wok) { + if(iaccess(f, d1, DWRITE)) { err = Eaccess; goto out; } @@ -1202,7 +1189,7 @@ out: } static int -doclunk(File* f, int remove, int wok) +doclunk(File* f, int remove) { Tlock *t; int err; @@ -1214,7 +1201,7 @@ doclunk(File* f, int remove, int wok) f->tlock = 0; } if(remove) - err = doremove(f, wok); + err = doremove(f); f->open = 0; freewp(f->wpath); freefp(f); @@ -1236,7 +1223,7 @@ f_clunk(Chan *cp, Fcall *in, Fcall *ou) if(!f) ou->err = Efid; else { - doclunk(f, f->open & FREMOV, 0); + doclunk(f, f->open & FREMOV); qunlock(f); } ou->fid = in->fid; @@ -1256,7 +1243,7 @@ f_remove(Chan *cp, Fcall *in, Fcall *ou) if(!f) ou->err = Efid; else { - ou->err = doclunk(f, 1, cp==cons.chan); + ou->err = doclunk(f, 1); qunlock(f); } ou->fid = in->fid; @@ -1371,7 +1358,7 @@ f_wstat(Chan *cp, Fcall *in, Fcall *ou) * if chown, * must be god */ - if(xd.uid != d->uid && !wstatallow) { /* set to allow chown during boot */ + if(xd.uid != d->uid && !isallowed(f)) { ou->err = Ewstatu; goto out; } @@ -1382,10 +1369,9 @@ f_wstat(Chan *cp, Fcall *in, Fcall *ou) * a) owner and in new group * b) leader of both groups */ - if (xd.gid != d->gid && - (!wstatallow && !writeallow && /* set to allow chgrp during boot */ + if (xd.gid != d->gid && !isallowed(f) && (d->uid != f->uid || !ingroup(f->uid, xd.gid)) && - (!leadgroup(f->uid, xd.gid) || !leadgroup(f->uid, d->gid)))) { + (!leadgroup(f->uid, xd.gid) || !leadgroup(f->uid, d->gid))) { ou->err = Ewstatg; goto out; } @@ -1439,8 +1425,7 @@ f_wstat(Chan *cp, Fcall *in, Fcall *ou) goto out; } - if (!wstatallow && !writeallow && /* set to allow rename during boot */ - (!d1 || iaccess(f, d1, DWRITE))) { + if(iaccess(f, d1, DWRITE)) { ou->err = Eaccess; goto out; } @@ -1453,8 +1438,7 @@ f_wstat(Chan *cp, Fcall *in, Fcall *ou) */ if (d->mtime != xd.mtime || ((d->mode^xd.mode) & (DAPND|DLOCK|0777))) - if (!wstatallow && /* set to allow chmod during boot */ - d->uid != f->uid && + if (d->uid != f->uid && !isallowed(f) && !leadgroup(f->uid, xd.gid) && !leadgroup(f->uid, d->gid)) { ou->err = Ewstatu; diff --git a/sys/src/cmd/cwfs/9p2.c b/sys/src/cmd/cwfs/9p2.c index 97fafe55f..e72756c01 100644 --- a/sys/src/cmd/cwfs/9p2.c +++ b/sys/src/cmd/cwfs/9p2.c @@ -148,7 +148,7 @@ auth(Chan* chan, Fcall* f, Fcall* r) Filsys *fs; int error; - if(noauth || wstatallow) + if(noauth) return Eauthdisabled; error = 0; @@ -201,7 +201,7 @@ authorize(Chan* chan, Fcall* f) db = cons.flags & authdebugflag; - if(noauth || wstatallow){ + if(noauth){ uid = strtouid(f->uname); if(db) fprint(2, "permission granted by noauth uid %s = %d\n", @@ -290,7 +290,7 @@ attach(Chan* chan, Fcall* f, Fcall* r) error = Ealloc; goto out; } - if (iaccess(file, d, DEXEC) || + if(iaccess(file, d, DEXEC) || file->uid == 0 && fs->dev->type == Devro) { /* * 'none' not allowed on dump @@ -394,7 +394,7 @@ walkname(File* file, char* wname, Qid* wqid) * For walked elements the implied user must * have permission to search the directory. */ - if(file->cp != cons.chan && iaccess(file, d, DEXEC)){ + if(iaccess(file, d, DEXEC)){ error = Eaccess; goto out; } @@ -607,14 +607,9 @@ fs_open(Chan* chan, Fcall* f, Fcall* r) File *file; Tlock *t; Qid qid; - int error, ro, fmod, wok; + int error, ro, fmod; - wok = 0; p = nil; - - if(chan == cons.chan || writeallow) - wok = 1; - if((file = filep(chan, f->fid, 0)) == nil){ error = Efid; goto out; @@ -672,13 +667,13 @@ fs_open(Chan* chan, Fcall* f, Fcall* r) switch(f->mode & 7){ case OREAD: - if(iaccess(file, d, DREAD) && !wok) + if(iaccess(file, d, DREAD)) goto badaccess; fmod = FREAD; break; case OWRITE: - if((d->mode & DDIR) || (iaccess(file, d, DWRITE) && !wok)) + if((d->mode & DDIR) || iaccess(file, d, DWRITE)) goto badaccess; if(ro){ error = Eronly; @@ -689,8 +684,8 @@ fs_open(Chan* chan, Fcall* f, Fcall* r) case ORDWR: if((d->mode & DDIR) - || (iaccess(file, d, DREAD) && !wok) - || (iaccess(file, d, DWRITE) && !wok)) + || iaccess(file, d, DREAD) + || iaccess(file, d, DWRITE)) goto badaccess; if(ro){ error = Eronly; @@ -700,7 +695,7 @@ fs_open(Chan* chan, Fcall* f, Fcall* r) break; case OEXEC: - if((d->mode & DDIR) || (iaccess(file, d, DEXEC) && !wok)) + if((d->mode & DDIR) || iaccess(file, d, DEXEC)) goto badaccess; fmod = FREAD; break; @@ -710,7 +705,7 @@ fs_open(Chan* chan, Fcall* f, Fcall* r) goto out; } if(f->mode & OTRUNC){ - if((d->mode & DDIR) || (iaccess(file, d, DWRITE) && !wok)) + if((d->mode & DDIR) || iaccess(file, d, DWRITE)) goto badaccess; if(ro){ error = Eronly; @@ -759,17 +754,13 @@ fs_create(Chan* chan, Fcall* f, Fcall* r) Iobuf *p, *p1; Dentry *d, *d1; File *file; - int error, slot, slot1, fmod, wok; + int error, slot, slot1, fmod; Off addr, addr1, path; Tlock *t; Wpath *w; - wok = 0; p = nil; - if(chan == cons.chan || writeallow) - wok = 1; - if((file = filep(chan, f->fid, 0)) == nil){ error = Efid; goto out; @@ -799,7 +790,7 @@ fs_create(Chan* chan, Fcall* f, Fcall* r) error = Edir2; goto out; } - if(iaccess(file, d, DWRITE) && !wok) { + if(iaccess(file, d, DWRITE)) { error = Eaccess; goto out; } @@ -1273,7 +1264,7 @@ out: } static int -_clunk(File* file, int remove, int wok) +_clunk(File* file, int remove) { Tlock *t; int error; @@ -1285,7 +1276,7 @@ _clunk(File* file, int remove, int wok) file->tlock = 0; } if(remove && (file->qid.type & QTAUTH) == 0) - error = doremove(file, wok); + error = doremove(file); file->open = 0; freewp(file->wpath); authfree(file->auth); @@ -1304,7 +1295,7 @@ clunk(Chan* chan, Fcall* f, Fcall*) if((file = filep(chan, f->fid, 0)) == nil) return Efid; - _clunk(file, file->open & FREMOV, 0); + _clunk(file, file->open & FREMOV); return 0; } @@ -1315,8 +1306,7 @@ fs_remove(Chan* chan, Fcall* f, Fcall*) if((file = filep(chan, f->fid, 0)) == nil) return Efid; - - return _clunk(file, 1, chan == cons.chan); + return _clunk(file, 1); } static int @@ -1433,13 +1423,10 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) * .qid.path, .qid.vers and .muid are checked for validity but * any attempt to change them is an error. * .qid.type/.mode, .mtime, .name, .length, .uid and .gid can - * possibly be changed (and .muid iff wstatallow). + * possibly be changed (and .muid iff is god). * * 'Op' flags there are changed fields, i.e. it's not a no-op. * 'Tsync' flags all fields are defaulted. - * - * Wstatallow and writeallow are set to allow changes during the - * fileserver bootstrap phase. */ tsync = 1; if(dir.qid.path != ~0){ @@ -1526,7 +1513,7 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) gl = leadgroup(file->uid, gid) != 0; gl += leadgroup(file->uid, d->gid) != 0; - if(op && !wstatallow && d->uid != file->uid && !gl){ + if(op && !isallowed(file) && d->uid != file->uid && !gl){ error = Ewstato; goto out; } @@ -1613,7 +1600,7 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) /* * Check write permission in the parent. */ - if(!wstatallow && !writeallow && iaccess(file, d1, DWRITE)){ + if(iaccess(file, d1, DWRITE)){ error = Eaccess; goto out; } @@ -1625,7 +1612,7 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) if(dir.uid != nil && *dir.uid != '\0'){ uid = strtouid(dir.uid); if(uid != d->uid){ - if(!wstatallow){ + if(!isallowed(file)){ error = Ewstatu; goto out; } @@ -1637,7 +1624,7 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) if(dir.muid != nil && *dir.muid != '\0'){ muid = strtouid(dir.muid); if(muid != d->muid){ - if(!wstatallow){ + if(!isallowed(file)){ error = Ewstatm; goto out; } @@ -1652,7 +1639,7 @@ fs_wstat(Chan* chan, Fcall* f, Fcall*, char* strs) * either owner and in new group or leader of both groups. */ if(gid != d->gid){ - if(!(wstatallow || writeallow) + if(!isallowed(file) && !(d->uid == file->uid && ingroup(file->uid, gid)) && !(gl == 2)){ error = Ewstatg; diff --git a/sys/src/cmd/cwfs/all.h b/sys/src/cmd/cwfs/all.h index 1cf878b04..4c358ba78 100644 --- a/sys/src/cmd/cwfs/all.h +++ b/sys/src/cmd/cwfs/all.h @@ -85,12 +85,10 @@ int noauth; /* auth is disable */ int nonone; /* attach as none disabled */ int noatime; /* atime is disabled */ int noatimeset; /* noatime was changed (reset after dump) */ -int wstatallow; /* set to circumvent wstat permissions */ -int writeallow; /* set to circumvent write permissions */ +int allowed; /* allow wstat and disable permission checks + * for user or anyone when -1 */ int duallow; /* single user to allow du */ int readonly; /* disable writes if true */ - - int rawreadok; /* allow reading raw data */ File* flist[5003]; /* base of file structures */ diff --git a/sys/src/cmd/cwfs/con.c b/sys/src/cmd/cwfs/con.c index 00fadf6bb..bace9df29 100644 --- a/sys/src/cmd/cwfs/con.c +++ b/sys/src/cmd/cwfs/con.c @@ -461,15 +461,31 @@ cmd_clri(int argc, char *argv[]) } static void -cmd_allow(int, char**) +cmd_allow(int argc, char *argv[]) { - wstatallow = writeallow = 1; + char *name; + int uid; + + uid = -1; + name = "any user"; + if(argc > 1){ + name = argv[1]; + uid = strtouid(name); + if(uid < 0) + uid = number(name, -2, 10); + if(uid < 0) { + print("bad uid %s\n", name); + return; + } + } + print("allowed %s\n", name); + allowed = uid; } static void cmd_disallow(int, char**) { - wstatallow = writeallow = 0; + allowed = 0; } void @@ -748,14 +764,14 @@ cmd_chatty(int argc, char *argv[]) static void installcmds(void) { - cmd_install("allow", "-- disable permission checking", cmd_allow); + cmd_install("allow", "[uid] -- disable permission checking", cmd_allow); cmd_install("cfs", "[file] -- set current filesystem", cmd_cfs); cmd_install("chatty", "n -- set chattiness", cmd_chatty); cmd_install("clean", "file [bno [addr]] -- block print/fix", cmd_clean); cmd_install("check", "[options]", cmd_check); cmd_install("clri", "[file ...] -- purge files/dirs", cmd_clri); cmd_install("create", "path uid gid perm [lad] -- make a file/dir", cmd_create); - cmd_install("disallow", "-- enable permission checking", cmd_disallow); + cmd_install("disallow", "-- (re)enable permission checking", cmd_disallow); cmd_install("duallow", "uid -- duallow", cmd_duallow); cmd_install("flag", "-- print set flags", cmd_flag); cmd_install("fstat", "path -- print info on a file/dir", cmd_fstat); diff --git a/sys/src/cmd/cwfs/config.c b/sys/src/cmd/cwfs/config.c index da71fcd69..a59306e90 100644 --- a/sys/src/cmd/cwfs/config.c +++ b/sys/src/cmd/cwfs/config.c @@ -1105,9 +1105,6 @@ arginit(void) } switch(verb) { case FREAM: - if(strcmp(fs->name, "main") == 0) - wstatallow = 1; /* only set, never reset */ - /* fallthrough */ case FRECOVER: fs->flags |= verb; break; diff --git a/sys/src/cmd/cwfs/portfns.h b/sys/src/cmd/cwfs/portfns.h index ba584caf0..d6628c640 100644 --- a/sys/src/cmd/cwfs/portfns.h +++ b/sys/src/cmd/cwfs/portfns.h @@ -66,7 +66,7 @@ Devsize devsize(Device*); int devwrite(Device*, Off, void*); Iobuf* dnodebuf(Iobuf*, Dentry*, Off, int, int); Iobuf* dnodebuf1(Iobuf*, Dentry*, Off, int, int); -int doremove(File*, int); +int doremove(File*); void dtrunc(Iobuf*, Dentry*, int); int dtrunclen(Iobuf *p, Dentry *, Off newsize, int uid); int dumpblock(Device*); @@ -107,6 +107,7 @@ void iobufinit(void); void* iobufmap(Iobuf*); void iobufunmap(Iobuf*); int iobufql(QLock*); +int isallowed(File*); int jukeread(Device*, Off, void*); int jukewrite(Device*, Off, void*); void jukeinit(Device*); diff --git a/sys/src/cmd/cwfs/sub.c b/sys/src/cmd/cwfs/sub.c index bf9a59e1d..c64f77c10 100644 --- a/sys/src/cmd/cwfs/sub.c +++ b/sys/src/cmd/cwfs/sub.c @@ -89,7 +89,7 @@ loop: f->tlock = 0; } if(f->open & FREMOV) - doremove(f, 0); + doremove(f); freewp(f->wpath); f->open = 0; authfree(f->auth); @@ -237,26 +237,41 @@ iaccess(File *f, Dentry *d, int m) return 0; } - /* - * other - */ + /* other */ if(m & d->mode) { + /* + * walk directories regardless. + * otherwise its impossible to get + * from the root to noworld's directories. + */ if((d->mode & DDIR) && (m == DEXEC)) return 0; if(!ingroup(f->uid, 9999)) return 0; } - /* - * various forms of superuser - */ - if(wstatallow) - return 0; + /* read access for du */ if(duallow != 0 && duallow == f->uid) if((d->mode & DDIR) && (m == DREAD || m == DEXEC)) return 0; - return 1; + /* allow god */ + return !isallowed(f); +} + +int +isallowed(File *f) +{ + if(f->cp == cons.chan) + return 1; + switch(allowed){ + case 0: + return 0; + case -1: + return 1; + default: + return f->uid == allowed; + } } Tlock* |
