]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-windows-del-symlink-20071021
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 22 Oct 2007 04:30:04 +0000 (04:30 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 22 Oct 2007 04:30:04 +0000 (04:30 +0000)
The cmd.exe "del" command operates by opening a file and then setting
the file disposition to delete on close followed by closing the file.

When the filename is a symlink, the smb_fid_t scp refers to the final
destination object and not the symlink.  In smb_CloseFid() the correct
object would be removed from the directory by name, but the wrong cm_scache_t
would be marked deleted.  This would result in subsequent references to
the target file being considered invalid.

Fix it by looking up the cm_scache_t of the symlink prior to performing
the deletion.

(cherry picked from commit f90153625efee1e5589df5e6b66a1162e07ddbfa)

src/WINNT/afsd/smb.c

index 77f40de55b038c38338d3dbaf34c3b29ed3837e6..45880442ffa554114baee65d122bc1a9a0129429 100644 (file)
@@ -6046,6 +6046,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
     cm_scache_t *dscp = NULL;
     char *pathp = NULL;
     cm_scache_t * scp = NULL;
+    cm_scache_t *delscp = NULL;
     int deleted = 0;
     int nullcreator = 0;
 
@@ -6153,8 +6154,14 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
         char *fullPathp;
 
        lock_ReleaseMutex(&fidp->mx);
-        smb_FullName(dscp, scp, pathp, &fullPathp, userp, &req);
-        if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
+
+        code = cm_Lookup(dscp, pathp, CM_FLAG_NOMOUNTCHASE, userp, &req, &delscp);
+        if (code) {
+            cm_HoldSCache(scp);
+            delscp = scp;
+        }
+        smb_FullName(dscp, delscp, pathp, &fullPathp, userp, &req);
+        if (delscp->fileType == CM_SCACHETYPE_DIRECTORY) {
             code = cm_RemoveDir(dscp, fullPathp, userp, &req);
            if (code == 0) {
                deleted = 1;
@@ -6210,16 +6217,20 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
     if (dscp)
        cm_ReleaseSCache(dscp);
 
-    if (scp) {
-       if (deleted || nullcreator) {
-           lock_ObtainMutex(&scp->mx);
-           if (nullcreator && scp->creator == userp)
-               scp->creator = NULL;
+    if (delscp) {
+       if (deleted) {
+           lock_ObtainMutex(&delscp->mx);
            if (deleted)
-               scp->flags |= CM_SCACHEFLAG_DELETED;
-           lock_ReleaseMutex(&scp->mx);
+               delscp->flags |= CM_SCACHEFLAG_DELETED;
+           lock_ReleaseMutex(&delscp->mx);
        }
+        cm_ReleaseSCache(delscp);
+    }
+
+    if (scp) {
        lock_ObtainMutex(&scp->mx);
+        if (nullcreator && scp->creator == userp)
+            scp->creator = NULL;
        scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
        lock_ReleaseMutex(&scp->mx);
        cm_ReleaseSCache(scp);