windows-unix-mode-bit-enforcement-20070105
[openafs.git] / src / WINNT / afsd / cm_access.c
index e5a1c12..5b9d6bd 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "afsd.h"
 
+int cm_deleteReadOnly = 0;
+
 /* called with scp write-locked, check to see if we have the ACL info we need
  * and can get it w/o blocking for any locks.
  *
@@ -89,8 +91,14 @@ int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *userp, afs_uint32
     /* check mode bits */
     if (!(scp->unixModeBits & 0400))
         *outRightsp &= ~PRSFS_READ;
-    if (!(scp->unixModeBits & 0200))
+    if (!(scp->unixModeBits & 0200) && !(rights == (PRSFS_WRITE | PRSFS_LOCK)))
         *outRightsp &= ~PRSFS_WRITE;
+    if (!(scp->unixModeBits & 0200) && !cm_deleteReadOnly)
+        *outRightsp &= ~PRSFS_DELETE;
+
+    /* if the user can obtain a write-lock, read-locks are implied */
+    if (*outRightsp & PRSFS_WRITE)
+       *outRightsp |= PRSFS_LOCK;
 
     code = 1;
     /* fall through */
@@ -124,16 +132,12 @@ long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *userp,
     /* first, start by finding out whether we have a directory or something
      * else, so we can find what object's ACL we need.
      */
-    if (scp->fileType == CM_SCACHETYPE_DIRECTORY || !cm_HaveCallback(scp)) {
+    if (scp->fileType == CM_SCACHETYPE_DIRECTORY ) {
        code = cm_SyncOp(scp, NULL, userp, reqp, 0,
                         CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB);
-       if (code) 
-           return code;
-
-       got_cb = 1;
-    }
-        
-    if (scp->fileType != CM_SCACHETYPE_DIRECTORY) {
+       if (!code) 
+           cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+    } else {
         /* not a dir, use parent dir's acl */
         tfid.cell = scp->fid.cell;
         tfid.volume = scp->fid.volume;
@@ -147,33 +151,17 @@ long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *userp,
         }       
                 
         osi_Log2(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp);
-       if (!cm_HaveCallback(aclScp)) {
-           lock_ObtainMutex(&aclScp->mx);
-           code = cm_SyncOp(aclScp, NULL, userp, reqp, 0,
-                             CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-           if (!code) {
-#if 0
-               /* cm_GetCallback was called by cm_SyncOp */
-               code = cm_GetCallback(aclScp, userp, reqp, 1); 
-#endif
-               cm_SyncOpDone(aclScp, NULL, 
-                             CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB);
-           }
-           lock_ReleaseMutex(&aclScp->mx);
-       }
+       lock_ObtainMutex(&aclScp->mx);
+       code = cm_SyncOp(aclScp, NULL, userp, reqp, 0,
+                        CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB);
+       if (!code)
+           cm_SyncOpDone(aclScp, NULL, 
+                         CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+       lock_ReleaseMutex(&aclScp->mx);
         cm_ReleaseSCache(aclScp);
         lock_ObtainMutex(&scp->mx);
     }
-#if 0    
-    else if (!got_cb) {
-       /* cm_GetCallback was called by cm_SyncOp */
-       code = cm_GetCallback(scp, userp, reqp, 1);
-    }
-#endif
 
   _done:
-    if (got_cb)
-       cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-
     return code;
 }