devip: fix permission checking
permission checking had the "other" and "owner" bits swapped plus incoming connections where always owned by "network" instead of the owner of the listening connection. also, ipwstat() was not effective as the uid strings where not parsed. this fixes the permission checks for data/ctl/err file and makes incoming connections inherit the owner from the listening connection. we also allow ipwstat() to change ownership to the commonuser() or anyone if we are eve. we might have to add additional restrictions for none at a later point...
This commit is contained in:
parent
b56909157f
commit
5993760e14
1 changed files with 48 additions and 31 deletions
|
@ -355,7 +355,7 @@ ipopen(Chan* c, int omode)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case Qndb:
|
case Qndb:
|
||||||
if(omode & (OWRITE|OTRUNC) && !iseve())
|
if((omode & (OWRITE|OTRUNC)) != 0 && !iseve())
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
|
if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
|
||||||
f->ndb[0] = 0;
|
f->ndb[0] = 0;
|
||||||
|
@ -412,15 +412,12 @@ ipopen(Chan* c, int omode)
|
||||||
qunlock(p);
|
qunlock(p);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
if((perm & (cv->perm>>6)) != perm) {
|
if(strcmp(ATTACHER(c), cv->owner) == 0)
|
||||||
if(strcmp(ATTACHER(c), cv->owner) != 0)
|
perm <<= 6;
|
||||||
error(Eperm);
|
if((perm & cv->perm) != perm && !iseve())
|
||||||
if((perm & cv->perm) != perm)
|
error(Eperm);
|
||||||
error(Eperm);
|
|
||||||
|
|
||||||
}
|
if(++cv->inuse == 1){
|
||||||
cv->inuse++;
|
|
||||||
if(cv->inuse == 1){
|
|
||||||
kstrdup(&cv->owner, ATTACHER(c));
|
kstrdup(&cv->owner, ATTACHER(c));
|
||||||
cv->perm = 0660;
|
cv->perm = 0660;
|
||||||
}
|
}
|
||||||
|
@ -430,24 +427,26 @@ ipopen(Chan* c, int omode)
|
||||||
break;
|
break;
|
||||||
case Qlisten:
|
case Qlisten:
|
||||||
cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
|
cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
|
||||||
if((perm & (cv->perm>>6)) != perm) {
|
qlock(cv);
|
||||||
if(strcmp(ATTACHER(c), cv->owner) != 0)
|
if(waserror()){
|
||||||
error(Eperm);
|
qunlock(cv);
|
||||||
if((perm & cv->perm) != perm)
|
nexterror();
|
||||||
error(Eperm);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(strcmp(ATTACHER(c), cv->owner) == 0)
|
||||||
|
perm <<= 6;
|
||||||
|
if((perm & cv->perm) != perm && !iseve())
|
||||||
|
error(Eperm);
|
||||||
|
|
||||||
if(cv->state != Announced)
|
if(cv->state != Announced)
|
||||||
error("not announced");
|
error("not announced");
|
||||||
|
|
||||||
|
cv->inuse++;
|
||||||
|
qunlock(cv);
|
||||||
|
poperror();
|
||||||
if(waserror()){
|
if(waserror()){
|
||||||
closeconv(cv);
|
closeconv(cv);
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
qlock(cv);
|
|
||||||
cv->inuse++;
|
|
||||||
qunlock(cv);
|
|
||||||
|
|
||||||
nc = nil;
|
nc = nil;
|
||||||
while(nc == nil) {
|
while(nc == nil) {
|
||||||
|
@ -469,7 +468,6 @@ ipopen(Chan* c, int omode)
|
||||||
if(nc != nil){
|
if(nc != nil){
|
||||||
cv->incall = nc->next;
|
cv->incall = nc->next;
|
||||||
mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
|
mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
|
||||||
kstrdup(&cv->owner, ATTACHER(c));
|
|
||||||
}
|
}
|
||||||
qunlock(cv);
|
qunlock(cv);
|
||||||
|
|
||||||
|
@ -502,10 +500,9 @@ ipremove(Chan*)
|
||||||
static int
|
static int
|
||||||
ipwstat(Chan *c, uchar *dp, int n)
|
ipwstat(Chan *c, uchar *dp, int n)
|
||||||
{
|
{
|
||||||
Dir d;
|
Dir *dir;
|
||||||
Conv *cv;
|
Conv *cv;
|
||||||
Fs *f;
|
Fs *f;
|
||||||
Proto *p;
|
|
||||||
|
|
||||||
f = ipfs[c->dev];
|
f = ipfs[c->dev];
|
||||||
switch(TYPE(c->qid)) {
|
switch(TYPE(c->qid)) {
|
||||||
|
@ -517,16 +514,36 @@ ipwstat(Chan *c, uchar *dp, int n)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = convM2D(dp, n, &d, nil);
|
dir = smalloc(sizeof(Dir)+n);
|
||||||
if(n > 0){
|
if(waserror()){
|
||||||
p = f->p[PROTO(c->qid)];
|
free(dir);
|
||||||
cv = p->conv[CONV(c->qid)];
|
nexterror();
|
||||||
if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0)
|
|
||||||
error(Eperm);
|
|
||||||
if(d.uid[0])
|
|
||||||
kstrdup(&cv->owner, d.uid);
|
|
||||||
cv->perm = d.mode & 0777;
|
|
||||||
}
|
}
|
||||||
|
n = convM2D(dp, n, &dir[0], (char*)&dir[1]);
|
||||||
|
if(n == 0)
|
||||||
|
error(Eshortstat);
|
||||||
|
|
||||||
|
cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
|
||||||
|
qlock(cv);
|
||||||
|
if(waserror()){
|
||||||
|
qunlock(cv);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
|
||||||
|
error(Eperm);
|
||||||
|
if(!emptystr(dir->uid)){
|
||||||
|
if(strcmp(dir->uid, commonuser()) != 0 && !iseve())
|
||||||
|
error(Eperm);
|
||||||
|
kstrdup(&cv->owner, dir->uid);
|
||||||
|
}
|
||||||
|
if(dir->mode != ~0UL)
|
||||||
|
cv->perm = dir->mode & 0666;
|
||||||
|
qunlock(cv);
|
||||||
|
poperror();
|
||||||
|
|
||||||
|
free(dir);
|
||||||
|
poperror();
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1394,7 +1411,7 @@ Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport, uchar
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find a free conversation */
|
/* find a free conversation */
|
||||||
nc = Fsprotoclone(c->p, network);
|
nc = Fsprotoclone(c->p, c->owner);
|
||||||
if(nc == nil) {
|
if(nc == nil) {
|
||||||
qunlock(c);
|
qunlock(c);
|
||||||
return nil;
|
return nil;
|
||||||
|
|
Loading…
Reference in a new issue