shithub: gefs

Download patch

ref: 4cc5ea3405e2cdc000a2788c0d2429ec8078ac7a
parent: 011d7f3a9030fc56deeae7998b7ca4e9082a4822
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Nov 22 21:40:12 EST 2023

fs: add the concept of permissive mounts for user initialization

--- a/dat.h
+++ b/dat.h
@@ -663,6 +663,8 @@
 	int	duid;
 	int	dgid;
 	int	dmode;
+
+	char	permit;
 };
 
 enum {
--- a/fns.h
+++ b/fns.h
@@ -15,6 +15,7 @@
 extern Blk*	blkbuf;
 extern int	noneid;
 extern int	nogroupid;
+extern int	admid;
 
 #define	UNPACK8(p)	(((uchar*)(p))[0])
 #define	UNPACK16(p)	((((uchar*)(p))[0]<<8)|(((uchar*)(p))[1]))
--- a/fs.c
+++ b/fs.c
@@ -800,6 +800,8 @@
 	in = 0;
 	u = uid2user(uid);
 	g = uid2user(gid);
+	if(u->id == g->id)
+		in = 1;
 	if(u != nil && g != nil)
 		for(i = 0; i < g->nmemb; i++)
 			if(u->id == g->memb[i])
@@ -853,7 +855,7 @@
 fsaccess(Fid *f, ulong fmode, int fuid, int fgid, int m)
 {
 	/* uid none gets only other permissions */
-	if(permissive)
+	if(f->permit)
 		return 0;
 	if(f->uid != noneid) {
 		if(f->uid == fuid)
@@ -875,7 +877,8 @@
 static void
 fsattach(Fmsg *m)
 {
-	char *p, *n, dbuf[Kvmax], kvbuf[Kvmax];
+	char dbuf[Kvmax], kvbuf[Kvmax];
+	char *p, *n, *aname;
 	Mount *mnt;
 	Dent *de;
 	Tree *t;
@@ -893,9 +896,12 @@
 		rerror(m, errmsg());
 		goto Err;
 	}
-	if(m->aname[0] == '\0')
-		m->aname = "main";
-	if((mnt = getmount(m->aname)) == nil)
+	aname = m->aname;
+	if(aname[0] == '%')
+		aname++;
+	if(aname[0] == '\0')
+		aname = "main";
+	if((mnt = getmount(aname)) == nil)
 		error(Enosnap);
 
 	rlock(&fs->userlk);
@@ -904,8 +910,9 @@
 	 * to allow people to add themselves to the user file,
 	 * we need to force the user id to one that exists.
 	 */
-	if(permissive && strcmp(m->aname, "adm") == 0)
+	if(permissive && strcmp(aname, "adm") == 0)
 		n = "adm";
+print("permissive: %d, name2user %s aname: %s\n", permissive, n, aname);
 	if((u = name2user(n)) == nil){
 		runlock(&fs->userlk);
 		error(Enouser);
@@ -958,6 +965,8 @@
 	f.duid = d.uid;
 	f.dgid = d.gid;
 	f.dmode = d.mode;
+	if(m->aname[0] == '%' && ingroup(uid, admid))
+		f.permit = 1;
 	if(dupfid(m->conn, m->fid, &f) == nil)
 		error(Efid);
 
@@ -1288,13 +1297,13 @@
 		if(fsaccess(f, de->mode, de->uid, de->gid, DMWRITE) == -1)
 			error(Eperm);
 	if(op & (Owmode|Owmtime))
-		if(!permissive && f->uid != de->uid && !groupleader(f->uid, de->gid))
+		if(!f->permit && f->uid != de->uid && !groupleader(f->uid, de->gid))
 			error(Ewstato);
 	if(op & Owuid)
-		if(!permissive)
+		if(!f->permit)
 			error(Ewstatu);
 	if(op & Owgid)
-		if(!permissive
+		if(!f->permit
 		&& !(f->uid == de->uid && ingroup(f->uid, n.gid))
 		&& !(groupleader(f->uid, de->gid) && groupleader(f->uid, n.gid)))
 			error(Ewstatg);
--- a/main.c
+++ b/main.c
@@ -22,6 +22,7 @@
 char	*srvname 	= "gefs";
 int	noneid		= 0;
 int	nogroupid	= 9999;
+int	admid		= -1;
 Blk	*blkbuf;
 void	**errctx;
 
--- a/ream.c
+++ b/ream.c
@@ -13,8 +13,6 @@
 	Nreamqid,
 };
 
-char *defaultusers ="-1:adm::%s\n0:none::\n";
-
 static void
 fillxdir(Xdir *d, vlong qid, char *name, int type, int mode)
 {
@@ -250,6 +248,7 @@
 	vlong sz, asz, off;
 	Mount *mnt, *adm;
 	Arena *a;
+	char *utab;
 	Dir *d;
 	int i;
 
@@ -320,17 +319,15 @@
 		sysfatal("ream: allocate root: %r");
 	holdblk(ab);
 	holdblk(ub);
-	if(reamuser != nil){
-		defaultusers = smprint(
-			"-1:adm::%s\n"
-			"0:none::\n"
-			"1:%s:%s:\n",
-			reamuser, reamuser, reamuser);
-	}
-	memcpy(ub->data, defaultusers, strlen(defaultusers));
+	utab = smprint(
+		"-1:adm::%s\n"
+		"0:none::\n"
+		"1:%s:%s:\n",
+		reamuser, reamuser, reamuser);
+	memcpy(ub->data, utab, strlen(utab));
 	finalize(ub);
 	syncblk(ub);
-	initadm(ab, ub, strlen(defaultusers));
+	initadm(ab, ub, strlen(utab));
 	finalize(ab);
 	syncblk(ab);
 
--- a/user.c
+++ b/user.c
@@ -137,6 +137,8 @@
 		u->nmemb = 0;
 		if(strcmp(u->name, "none") == 0)
 			noneid = u->id;
+		if(strcmp(u->name, "adm") == 0)
+			admid = u->id;
 		i++;
 	}
 	nusers = i;
@@ -237,7 +239,12 @@
 		error(Efsize);
 	s = slurp(t, q.path, len);
 	e = parseusers(fd, s);
-	if(e != nil)
-		error(e);
+	if(e != nil){
+		if(fs->users != nil)
+			error(e);
+		fprint(2, "user table broken: %s\n", e);
+		fprint(2, "\tfalling back to default\n");
+		parseusers(fd, "-1:adm::\n0:none::\n");
+	}
 	free(s);
 }