Windows FindACLCache must hold scp write locked
[openafs.git] / src / WINNT / afsd / smb3.c
index 7c453f3..e2eae0d 100644 (file)
@@ -4556,19 +4556,19 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp,
     afs_int32 mustFake = 0;
     clientchar_t path[AFSPATHMAX];
 
+    lock_ObtainWrite(&dscp->rw);
     code = cm_FindACLCache(dscp, userp, &rights);
     if (code == -1) {
-        lock_ObtainWrite(&dscp->rw);
         code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ,
                           CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
         if (code == 0)
             cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-        lock_ReleaseWrite(&dscp->rw);
         if (code == CM_ERROR_NOACCESS) {
             mustFake = 1;
             code = 0;
         }
     }
+    lock_ReleaseWrite(&dscp->rw);
     if (code)
         goto cleanup;
 
@@ -4588,7 +4588,7 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp,
             if (patchp->flags & SMB_DIRLISTPATCH_IOCTL)
                 continue;
 
-            code = cm_GetSCache(&patchp->fid, &tscp, userp, reqp);
+            code = cm_GetSCache(&patchp->fid, &dscp->fid, &tscp, userp, reqp);
             if (code == 0) {
                 if (lock_TryWrite(&tscp->rw)) {
                     /* we have an entry that we can look at */
@@ -4673,7 +4673,7 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, smb_dirListPatch_t **dirPatchespp,
             continue;
         }
 
-        code = cm_GetSCache(&patchp->fid, &scp, userp, reqp);
+        code = cm_GetSCache(&patchp->fid, &dscp->fid, &scp, userp, reqp);
         reqp->relPathp = reqp->tidPathp = NULL;
         if (code)
             continue;
@@ -7826,8 +7826,20 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
      * by dscp, or we may have found the file directly.  If code is non-zero,
      * scp is NULL.
      */
+
+    /*
+     * open the file itself
+     * allocate the fidp early so the smb fid can be used by cm_CheckNTOpen()
+     */
+    fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
+    osi_assertx(fidp, "null smb_fid_t");
+
+    /* save a reference to the user */
+    cm_HoldUser(userp);
+    fidp->userp = userp;
+
     if (code == 0 && !treeCreate) {
-        code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
+        code = cm_CheckNTOpen(scp, desiredAccess, shareAccess, createDisp, 0, fidp->fid, userp, &req, &ldp);
         if (code) {
             cm_CheckNTOpenDone(scp, userp, &req, &ldp);
             if (dscp)
@@ -7835,6 +7847,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             if (scp)
                 cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
+           smb_CloseFID(vcp, fidp, NULL, 0);
+           smb_ReleaseFID(fidp);
             free(realPathp);
             return code;
         }
@@ -7848,6 +7862,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             if (scp)
                 cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
+           smb_CloseFID(vcp, fidp, NULL, 0);
+           smb_ReleaseFID(fidp);
             free(realPathp);
             return CM_ERROR_EXISTS;
         }
@@ -7874,7 +7890,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                    cm_CheckNTOpenDone(scp, userp, &req, &ldp);
                     cm_ReleaseSCache(scp);
                     scp = targetScp;
-                   code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
+                   code = cm_CheckNTOpen(scp, desiredAccess, shareAccess, createDisp, 0, fidp->fid, userp, &req, &ldp);
                    if (code) {
                         cm_CheckNTOpenDone(scp, userp, &req, &ldp);
                        if (dscp)
@@ -7882,6 +7898,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                        if (scp)
                            cm_ReleaseSCache(scp);
                        cm_ReleaseUser(userp);
+                        smb_CloseFID(vcp, fidp, NULL, 0);
+                        smb_ReleaseFID(fidp);
                        free(realPathp);
                        return code;
                    }
@@ -7900,6 +7918,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         if (scp)
             cm_ReleaseSCache(scp);
         cm_ReleaseUser(userp);
+        smb_CloseFID(vcp, fidp, NULL, 0);
+        smb_ReleaseFID(fidp);
         free(realPathp);
         return CM_ERROR_NOSUCHFILE;
     } else if (realDirFlag == 0 || realDirFlag == -1) {
@@ -8051,6 +8071,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         if (dscp)
             cm_ReleaseSCache(dscp);
         cm_ReleaseUser(userp);
+        smb_CloseFID(vcp, fidp, NULL, 0);
+        smb_ReleaseFID(fidp);
         free(realPathp);
         return code;
     }
@@ -8084,6 +8106,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                 cm_ReleaseSCache(dscp);
             cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
+           smb_CloseFID(vcp, fidp, NULL, 0);
+           smb_ReleaseFID(fidp);
             free(realPathp);
             return CM_ERROR_ISDIR;
         }
@@ -8097,18 +8121,12 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         if (dscp)
             cm_ReleaseSCache(dscp);
         cm_ReleaseUser(userp);
+        smb_CloseFID(vcp, fidp, NULL, 0);
+        smb_ReleaseFID(fidp);
         free(realPathp);
         return CM_ERROR_NOTDIR;
     }
 
-    /* open the file itself */
-    fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
-    osi_assertx(fidp, "null smb_fid_t");
-
-    /* save a reference to the user */
-    cm_HoldUser(userp);
-    fidp->userp = userp;
-
     /* If we are restricting sharing, we should do so with a suitable
        share lock. */
     if (scp->fileType == CM_SCACHETYPE_FILE &&
@@ -8146,7 +8164,6 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             if (dscp)
                 cm_ReleaseSCache(dscp);
            cm_ReleaseUser(userp);
-           /* Shouldn't this be smb_CloseFID()?  fidp->flags = SMB_FID_DELETE; */
            smb_CloseFID(vcp, fidp, NULL, 0);
            smb_ReleaseFID(fidp);
             free(realPathp);
@@ -8621,7 +8638,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
      * scp is NULL.
      */
     if (code == 0) {
-        code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
+        code = cm_CheckNTOpen(scp, desiredAccess, shareAccess, createDisp, 0, fidp->fid, userp, &req, &ldp);
         if (code) {
             cm_CheckNTOpenDone(scp, userp, &req, &ldp);
             cm_ReleaseSCache(dscp);
@@ -8663,7 +8680,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
                    cm_CheckNTOpenDone(scp, userp, &req, &ldp);
                     cm_ReleaseSCache(scp);
                     scp = targetScp;
-                   code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
+                   code = cm_CheckNTOpen(scp, desiredAccess, shareAccess, createDisp, 0, fidp->fid, userp, &req, &ldp);
                    if (code) {
                         cm_CheckNTOpenDone(scp, userp, &req, &ldp);
                         cm_ReleaseSCache(dscp);