windows-unix-mode-bit-enforcement-20070105
[openafs.git] / src / WINNT / afsd / cm_access.c
index a40e17e..5b9d6bd 100644 (file)
 #include <afs/param.h>
 #include <afs/stds.h>
 
-#ifndef DJGPP
 #include <windows.h>
 #include <winsock2.h>
-#endif
 #include <malloc.h>
 #include <string.h>
 #include <stdlib.h>
-#ifndef DJGPP
 #include <nb30.h>
-#endif
 #include <osi.h>
 
 #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.
  *
@@ -93,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 */
@@ -118,26 +122,22 @@ long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *userp,
 {
     long code;
     cm_fid_t tfid;
-    cm_scache_t *aclScp;
+    cm_scache_t *aclScp = NULL;
     int got_cb = 0;
 
     /* pretty easy: just force a pass through the fetch status code */
         
-    osi_Log2(afsd_logp, "GetAccess scp %x user %x", scp, userp);
+    osi_Log2(afsd_logp, "GetAccess scp 0x%p user 0x%p", scp, 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 (!cm_HaveCallback(scp)) {
+    if (scp->fileType == CM_SCACHETYPE_DIRECTORY ) {
        code = cm_SyncOp(scp, NULL, userp, reqp, 0,
-                     CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-       if (code) 
-           return code;
-
-       got_cb = 1;
-    }
-        
-    if (scp->fileType != CM_SCACHETYPE_DIRECTORY) {
+                        CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_FORCECB);
+       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,19 +147,21 @@ long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *userp,
         code = cm_GetSCache(&tfid, &aclScp, userp, reqp);
         if (code) {
             lock_ObtainMutex(&scp->mx);
-            return code;
+           goto _done;
         }       
                 
         osi_Log2(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp);
-        lock_ObtainMutex(&aclScp->mx);
-
-       code = cm_GetCallback(aclScp, userp, reqp, 1);
-        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);
-    } else if (!got_cb) {
-       code = cm_GetCallback(scp, userp, reqp, 1);
     }
 
+  _done:
     return code;
 }