X-Git-Url: https://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Fafs%2FVNOPS%2Fafs_vnop_access.c;h=f72b6e634fe5e3e152e8553554c53fdfe401da56;hp=0a31ac8d1b9f4ddb60fd216660e1663917965d54;hb=3f89c0feae89e9a255afb8a7f08995412a3f1b79;hpb=cb4b62a40352ccebae3a299f4327fa70fc7a0c5c diff --git a/src/afs/VNOPS/afs_vnop_access.c b/src/afs/VNOPS/afs_vnop_access.c index 0a31ac8..f72b6e6 100644 --- a/src/afs/VNOPS/afs_vnop_access.c +++ b/src/afs/VNOPS/afs_vnop_access.c @@ -148,15 +148,36 @@ afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq, /* Avoid this GetVCache call */ tvc = afs_GetVCache(&dirFid, areq, NULL, NULL); if (tvc) { - dirBits = afs_GetAccessBits(tvc, arights, areq); + if ((arights & (PRSFS_READ | PRSFS_WRITE))) { + /* we may need to grant implicit 'rw' rights if we have + * 'i' on the parent dir and we are the owner, so check + * for 'i' rights in addition, here */ + dirBits = afs_GetAccessBits(tvc, arights | PRSFS_INSERT, areq); + } else { + dirBits = afs_GetAccessBits(tvc, arights, areq); + } afs_PutVCache(tvc); } } else dirBits = 0xffffffff; /* assume OK; this is a race condition */ - if (arights & PRSFS_ADMINISTER) + if (arights & PRSFS_ADMINISTER) { fileBits = afs_GetAccessBits(avc, arights, areq); - else + + } else if ((dirBits & PRSFS_INSERT) && + ((arights & (PRSFS_READ | PRSFS_WRITE)) & dirBits) != + (arights & (PRSFS_READ | PRSFS_WRITE))) { + + /* if we have 'i' rights in the directory, and we are requesting + * read or write access, AND the directory ACL (dirBits) does not + * already give us the requested read or write access, we need to + * find out if we are the owner for the file ('A' bit), for the + * "throw in R and W if we have I and A" check below */ + + fileBits = afs_GetAccessBits(avc, arights | PRSFS_ADMINISTER, areq); + + } else { fileBits = 0; /* don't make call if results don't matter */ + } /* compute basic rights in fileBits, taking A from file bits */ fileBits = @@ -164,8 +185,8 @@ afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq, /* for files, throw in R and W if have I and A (owner). This makes * insert-only dirs work properly */ - if (vType(avc) != VDIR - && (fileBits & (PRSFS_ADMINISTER | PRSFS_INSERT)) == + /* note that we know vType(avc) != VDIR from the top-level 'else' */ + if ((fileBits & (PRSFS_ADMINISTER | PRSFS_INSERT)) == (PRSFS_ADMINISTER | PRSFS_INSERT)) fileBits |= (PRSFS_READ | PRSFS_WRITE);