]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-get-acls-20060528
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 1 Jun 2006 16:40:57 +0000 (16:40 +0000)
committerDerrick Brashear <shadow@dementia.org>
Thu, 1 Jun 2006 16:40:57 +0000 (16:40 +0000)
It is possible to have a valid callback but not to have the
required ACL info for the current user.  Force acquisition of
a FetchStatus but do so without making multiple calls.

(cherry picked from commit 83732fdb158e79b64774667ee09fc1b81062707e)

src/WINNT/afsd/cm_access.c
src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_scache.c

index b2b86c9aec176b2d00813e6453d70ddd72133c0c..e3097f9be1f21933a917d43fc8c4305d7754a25f 100644 (file)
@@ -32,7 +32,7 @@
  * can't be locked.  Thus, this must always be called in a while loop to stabilize
  * things, since we can always lose the race condition getting to the parent vnode.
  */
-int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, afs_uint32 rights,
+int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *userp, afs_uint32 rights,
                         afs_uint32 *outRightsp)
 {
     cm_scache_t *aclScp;
@@ -82,7 +82,7 @@ int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, afs_uint32 ri
         *outRightsp = rights;
     } else {
         /* we have to check the specific rights info */
-        code = cm_FindACLCache(aclScp, up, &trights);
+        code = cm_FindACLCache(aclScp, userp, &trights);
         if (code) {
             code = 0;
             goto done;
@@ -107,30 +107,35 @@ int cm_HaveAccessRights(struct cm_scache *scp, struct cm_user *up, afs_uint32 ri
 }
 
 /* called with locked scp; ensures that we have an ACL cache entry for the
- * user specified by the parameter "up."
+ * user specified by the parameter "userp."
  * In pathological race conditions, this function may return success without
  * having loaded the entry properly (due to a racing callback revoke), so this
  * function must also be called in a while loop to make sure that we eventually
  * succeed.
  */
-long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *up,
+long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *userp,
                         struct cm_req *reqp)
 {
     long code;
     cm_fid_t tfid;
     cm_scache_t *aclScp;
+    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, up);
+    osi_Log2(afsd_logp, "GetAccess scp %x user %x", 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.
      */
-    code = cm_SyncOp(scp, NULL, up, reqp, 0, 
+    if (!cm_HaveCallback(scp)) {
+       code = cm_SyncOp(scp, NULL, userp, reqp, 0,
                      CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-    if (code) 
-        return code;
+       if (code) 
+           return code;
+
+       got_cb = 1;
+    }
         
     if (scp->fileType != CM_SCACHETYPE_DIRECTORY) {
         /* not a dir, use parent dir's acl */
@@ -139,19 +144,21 @@ long cm_GetAccessRights(struct cm_scache *scp, struct cm_user *up,
         tfid.vnode = scp->parentVnode;
         tfid.unique = scp->parentUnique;
         lock_ReleaseMutex(&scp->mx);
-        code = cm_GetSCache(&tfid, &aclScp, up, reqp);
+        code = cm_GetSCache(&tfid, &aclScp, userp, reqp);
         if (code) {
             lock_ObtainMutex(&scp->mx);
             return code;
         }       
                 
-        osi_Log1(afsd_logp, "GetAccess parent scp %x user %x", aclScp, up);
+        osi_Log1(afsd_logp, "GetAccess parent scp %x user %x", aclScp, userp);
         lock_ObtainMutex(&aclScp->mx);
-       code = cm_SyncOp(aclScp, NULL, up, reqp, 0,
-                         CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+
+       code = cm_GetCallback(aclScp, userp, reqp, 1);
         lock_ReleaseMutex(&aclScp->mx);
         cm_ReleaseSCache(aclScp);
         lock_ObtainMutex(&scp->mx);
+    } else if (!got_cb) {
+       code = cm_GetCallback(scp, userp, reqp, 1);
     }
 
     return code;
index 23bcd26f3f6162119f563af5c89b995ba01669ce..b282aaad7f05f2adfab52bef2a7e0f74f6b86068 100644 (file)
@@ -1681,7 +1681,7 @@ long cm_GetCallback(cm_scache_t *scp, struct cm_user *userp,
 
         /* otherwise, we have to make an RPC to get the status */
         sflags = CM_SCACHESYNC_FETCHSTATUS | CM_SCACHESYNC_GETCALLBACK;
-        cm_SyncOp(scp, NULL, NULL, NULL, 0, sflags);
+        cm_SyncOp(scp, NULL, userp, reqp, 0, sflags);
         cm_StartCallbackGrantingCall(scp, &cbr);
         sfid = scp->fid;
         lock_ReleaseMutex(&scp->mx);
index 826b2697630198d7f8460aee4df5da5aa4c4c48d..18b599a26c87b55451cfdd02b6791ed572c25f1b 100644 (file)
@@ -667,7 +667,7 @@ cm_scache_t * cm_FindSCacheParent(cm_scache_t * scp)
  * is to serialize all StoreData RPC's.  This is the reason we defined
  * CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING.
  */
-long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
+long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *userp, cm_req_t *reqp,
                afs_uint32 rights, afs_uint32 flags)
 {
     osi_queueData_t *qdp;
@@ -854,7 +854,7 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
                 osi_Log1(afsd_logp, "CM SyncOp getting callback on scp 0x%p",
                           scp);
                 if (bufLocked) lock_ReleaseMutex(&bufp->mx);
-                code = cm_GetCallback(scp, up, reqp, 0);
+                code = cm_GetCallback(scp, userp, reqp, 0);
                 if (bufLocked) {
                     lock_ReleaseMutex(&scp->mx);
                     lock_ObtainMutex(&bufp->mx);
@@ -873,14 +873,14 @@ long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
             if ((rights & PRSFS_WRITE) && (scp->flags & CM_SCACHEFLAG_RO))
                 return CM_ERROR_READONLY;
 
-            if (cm_HaveAccessRights(scp, up, rights, &outRights)) {
+            if (cm_HaveAccessRights(scp, userp, rights, &outRights)) {
                 if (~outRights & rights) 
                    return CM_ERROR_NOACCESS;
             }
             else {
                 /* we don't know the required access rights */
                 if (bufLocked) lock_ReleaseMutex(&bufp->mx);
-                code = cm_GetAccessRights(scp, up, reqp);
+                code = cm_GetAccessRights(scp, userp, reqp);
                 if (code) 
                     return code;
                 if (bufLocked) {