9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Jacob Moody <moody@mail.posixcafe.org>
To: 9front@9front.org
Subject: Re: [9front] [PATCH] Permissions for child boards in /srv
Date: Fri, 24 Jun 2022 21:49:37 -0600	[thread overview]
Message-ID: <16473a2f-dc03-d6f2-4060-bb1b5bef3f9f@posixcafe.org> (raw)
In-Reply-To: <59eb60df-a92a-9d40-a97e-d179b5f80ea0@posixcafe.org>

Some more tweaks:

diff 5ee86cf824c5591aa92118c0cd9d71b005e789d0 uncommitted
--- a/sys/src/9/port/devsrv.c
+++ b/sys/src/9/port/devsrv.c
@@ -13,6 +13,8 @@
 	void 	*link;
 	char 	*name;
 	ulong 	path;
+	char	*owner;
+	ulong	perm;
 };

 typedef struct Srv Srv;
@@ -19,9 +21,6 @@
 struct Srv
 {
 	Link;
-
-	char	*owner;
-	ulong	perm;
 	Chan	*chan;
 };

@@ -140,6 +139,7 @@

 		b = ch->parent;
 		free(ch->name);
+		free(ch->owner);
 		wunlock(ch);
 		free(ch);
 	}
@@ -162,14 +162,17 @@
 	rlock(b);
 	if(waserror()){
 		runlock(b);
-		return -1;
+		nexterror();
 	}
-	if(s == DEVDOTDOT){
+	switch(s){
+	case -2: /* dot */
+		ch = b;
+		goto Child;
+	case DEVDOTDOT:
 		ch = b->parent;
 		if(ch == nil)
 			ch = &root;
 		goto Child;
-		
 	}
 	if(name != nil){
 		if(strcmp("clone", name) == 0)
@@ -194,21 +197,25 @@
 		devdir(c, q, up->genbuf, 0, sp->owner, sp->perm, dp);
 	} else if(ch != nil){
 Child:
+		if(name != nil || s == DEVDOTDOT){
+			devpermcheck(ch->owner, ch->perm, OEXEC);
+			c->aux = ch;
+		}
 		kstrcpy(up->genbuf, ch->name, sizeof up->genbuf);
 		q.vers = ch->id;
 		q.path = NETQID(q.vers, ch->path);
 		q.type = QTDIR;
-		devdir(c, q, up->genbuf, 0, eve, 0555|DMDIR, dp);
-		/* dirread's and stats shouldn't alter c->aux */
-		if(name != nil)
-			c->aux = ch;
+		devdir(c, q, up->genbuf, 0, ch->owner, ch->perm|DMDIR, dp);
 	} else if(0){
 Clone:
 		q.vers = NETID(c->qid.path);
 		q.path = NETQID(q.vers, Qclone);
 		devdir(c, q, "clone", 0, eve, 0444, dp);
-	} else
-		error(Enonexist);
+	} else {
+		runlock(b);
+		poperror();
+		return -1;
+	}

 	runlock(b);
 	poperror();
@@ -220,6 +227,8 @@
 {
 	root.qidpath = Qend;
 	root.name = "#s";
+	root.perm = 0777;
+	kstrdup(&root.owner, eve);
 }

 static Chan*
@@ -253,6 +262,17 @@
 static int
 srvstat(Chan *c, uchar *db, int n)
 {
+	Dir d;
+
+	/* devstat cheats for dir stats, we care about our dir perms */
+	if(c->qid.type == QTDIR){
+		srvgen(c, nil, nil, 0, -2, &d);
+		n = convD2M(&d, db, n);
+		if(n == 0)
+			error(Ebadarg);
+		return n;
+	}
+
 	return devstat(c, db, n, 0, 0, srvgen);
 }

@@ -286,16 +306,6 @@
 	Chan *nc;
 	char buf[64];

-	if(c->qid.type == QTDIR){
-		if(omode & ORCLOSE)
-			error(Eperm);
-		if(omode != OREAD)
-			error(Eisdir);
-		c->mode = omode;
-		c->flag |= COPEN;
-		c->offset = 0;
-		return c;
-	}
 	if(omode&OTRUNC)
 		error(Eexist);
 	if(omode&ORCLOSE)
@@ -311,6 +321,8 @@
 		ch = smalloc(sizeof *ch);
 		ch->qidpath = Qend;
 		ch->ref = 1;
+		ch->perm = 0770;
+		kstrdup(&ch->owner, up->user);
 		do {
 			qlock(&boards);
 			ch->id = ++boards.path;
@@ -336,6 +348,19 @@
 		runlock(b);
 		nexterror();
 	}
+	if(c->qid.type == QTDIR){
+		if(omode & ORCLOSE)
+			error(Eperm);
+		if(omode != OREAD)
+			error(Eisdir);
+		devpermcheck(b->owner, b->perm, omode);
+		c->mode = omode;
+		c->flag |= COPEN;
+		c->offset = 0;
+		runlock(b);
+		poperror();
+		return c;
+	}
 	if(b->closed)
 		error(Eexpired);

@@ -369,6 +394,9 @@
 	if(strlen(name) >= sizeof(up->genbuf))
 		error(Etoolong);

+	if(strcmp("clone", name) == 0)
+		error("reserved name");
+
 	sp = smalloc(sizeof *sp);
 	kstrdup(&sp->name, name);
 	kstrdup(&sp->owner, up->user);
@@ -384,6 +412,7 @@
 	}
 	if(b->closed)
 		error(Eexpired);
+	devpermcheck(b->owner, b->perm, OWRITE);
 	if(lookup(b->srv, name, ~0UL) != nil)
 		error(Eexist);
 	if(lookup(b->child, name, ~0UL) != nil)
@@ -432,18 +461,9 @@
 	if(sp == nil)
 		error(Enonexist);

-	/*
-	 * Only eve can remove system services.
-	 */
-	if(strcmp(sp->owner, eve) == 0 && !iseve())
+	if(strcmp(sp->owner, up->user) != 0 && !iseve())
 		error(Eperm);

-	/*
-	 * No removing personal services.
-	 */
-	if((sp->perm&7) != 7 && strcmp(sp->owner, up->user) && !iseve())
-		error(Eperm);
-
 	remove((Link**)&b->srv, nil, c->qid.path);

 	boardclunk(b, 0); //unlock
@@ -459,18 +479,18 @@
 static int
 srvwstat(Chan *c, uchar *dp, int n)
 {
-	Board *b;
+	Board *b, *s;
 	char *strs;
-	Srv *sp;
 	Dir d;
+	Link *lp;

-	if(c->qid.type & QTDIR)
-		error(Eperm);
 	switch(NETTYPE(c->qid.path)){
 	case Qlease:
 	case Qclone:
 		error(Eperm);
 	}
+	if(c->qid.type == QTDIR && c->aux == &root)
+		error(Eperm);

 	strs = smalloc(n);
 	if(waserror()){
@@ -490,29 +510,50 @@
 	if(b->closed)
 		error(Eexpired);

-	sp = lookup(b->srv, nil, c->qid.path);
-	if(sp == nil)
+	if(c->qid.type == QTDIR){
+		lp = b;
+		/* we share ownership of our stats with our parent */
+		assert(b->parent != nil);
+		wlock(b->parent);
+		if(waserror()){
+			wunlock(b->parent);
+			nexterror();
+		}
+	} else
+		lp = lookup(b->srv, nil, c->qid.path);
+	if(lp == nil)
 		error(Enonexist);

-	if(strcmp(sp->owner, up->user) != 0 && !iseve())
+	if(strcmp(lp->owner, up->user) != 0 && !iseve())
 		error(Eperm);

-	if(d.name != nil && *d.name && strcmp(sp->name, d.name) != 0) {
+	if(d.name != nil && *d.name && strcmp(lp->name, d.name) != 0) {
 		if(strchr(d.name, '/') != nil)
 			error(Ebadchar);
 		if(strlen(d.name) >= sizeof(up->genbuf))
 			error(Etoolong);
-		if(lookup(b->srv, d.name, ~0UL) != nil)
+
+		//Ensure new name doesn't conflict with old names
+		if(c->qid.type == QTDIR)
+			s = b->parent;
+		else
+			s = b;
+		if(lookup(s->srv, d.name, ~0UL) != nil)
 			error(Eexist);
-		if(lookup(b->child, d.name, ~0UL) != nil)
+		if(lookup(s->child, d.name, ~0UL) != nil)
 			error(Eexist);
-		kstrdup(&sp->name, d.name);
+		kstrdup(&lp->name, d.name);
 	}
 	if(d.uid != nil && *d.uid)
-		kstrdup(&sp->owner, d.uid);
+		kstrdup(&lp->owner, d.uid);
 	if(d.mode != ~0UL)
-		sp->perm = d.mode & 0777;
+		lp->perm = d.mode & 0777;

+	if(c->qid.type == QTDIR){
+		wunlock(b->parent);
+		poperror();
+	}
+
 	wunlock(b);
 	poperror();

@@ -644,6 +685,7 @@

 	b = &root;
 	wlock(b);
+	kstrdup(&b->owner, new);
 	for(sp = b->srv; sp != nil; sp = sp->link) {
 		if(sp->owner != nil && strcmp(old, sp->owner) == 0)
 			kstrdup(&sp->owner, new);



  reply	other threads:[~2022-06-25  3:51 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-24 14:34 Jacob Moody
2022-06-25  3:49 ` Jacob Moody [this message]
2022-06-29 14:53   ` Jacob Moody
2022-06-29 16:35     ` cinap_lenrek
2022-06-29 16:42       ` Jacob Moody
2022-06-29 16:46         ` ori
2022-06-29 17:12           ` hiro
2022-06-29 17:20         ` cinap_lenrek
2022-06-29 17:50           ` Jacob Moody
2022-07-02 21:25             ` ori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=16473a2f-dc03-d6f2-4060-bb1b5bef3f9f@posixcafe.org \
    --to=moody@mail.posixcafe.org \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).