/* 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 =
/* 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);
#if defined(AFS_SUN5_ENV) || (defined(AFS_SGI_ENV) && !defined(AFS_SGI65_ENV))
int
afs_access(OSI_VC_DECL(avc), register afs_int32 amode, int flags,
- struct AFS_UCRED *acred)
+ afs_ucred_t *acred)
#else
int
afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
- struct AFS_UCRED *acred)
+ afs_ucred_t *acred)
#endif
{
register afs_int32 code;
if (amode & VEXEC) {
code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
if (code) {
-#ifdef AFS_OSF_ENV
- /*
- * The nfs server in read operations for non-owner of a file
- * will also check the access with the VEXEC (along with VREAD)
- * because for them exec is the same as read over the net because of
- * demand loading. But this means if the mode bit is '-rw' the call
- * will fail below; so for this particular case where both modes are
- * specified (only in rfs_read so far) and from the xlator requests
- * we return succes.
- */
- if (!((amode & VREAD) && AFS_NFSXLATORREQ(acred)))
-#endif
if ((avc->f.m.Mode & 0100) == 0)
code = 0;
} else if (avc->f.m.Mode & 0100)
*/
int
afs_getRights(OSI_VC_DECL(avc), register afs_int32 arights,
- struct AFS_UCRED *acred)
+ afs_ucred_t *acred)
{
register afs_int32 code;
struct vrequest treq;