]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
windows-smb_fid_t-mx-20060130
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 31 Jan 2006 09:13:11 +0000 (09:13 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 31 Jan 2006 09:13:11 +0000 (09:13 +0000)
*Includes the changes from STABLE14-windows-smb_fid_t-audit-20060125
 as well:

"Further testing revealed that some smb_vc_t objects could not be freed
because the associated smb_fid_t objects never reached a zero refcount.
Additional auditing uncovered cases in which there were holds not being
released and others in which they were released to many times.  This
patch fixes the problems and improves auditability by modifying the
behavior of the smb_IoctlXXX() functions to not release a reference
that was obtained by the caller.  Now the caller releases the reference."

Fixup token deletion logic

Surround all references to smb_fid_t flags and other references
by obtaining and releasing the 'mx' lock.

src/WINNT/afsd/afslogon.c
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb3.c
src/WINNT/afsd/smb_ioctl.c

index bcd700f5918eb2a4a83b98a44cc95a24702fc147..f8c25ac4042368b4954e6cc49531c65f4d8c5f6f 100644 (file)
@@ -256,7 +256,7 @@ BOOL IsServiceRunning (void)
 
         CloseServiceHandle (hManager);
     }
-    DebugEvent("AFS AfsLogon - Test Service Running","Return Code[%x] ?Running[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_RUNNING));
+    DebugEvent("AFS AfsLogon - Test Service Running Return Code[%x] ?Running[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_RUNNING));
     return (Status.dwCurrentState == SERVICE_RUNNING);
 }   
 
@@ -278,7 +278,7 @@ BOOL IsServiceStartPending (void)
 
         CloseServiceHandle (hManager);
     }
-    DebugEvent("AFS AfsLogon - Test Service Start Pending","Return Code[%x] ?Start Pending[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_START_PENDING));
+    DebugEvent("AFS AfsLogon - Test Service Start Pending Return Code[%x] ?Start Pending[%d]",Status.dwCurrentState,(Status.dwCurrentState == SERVICE_START_PENDING));
     return (Status.dwCurrentState == SERVICE_START_PENDING);
 }   
 
index 0c992166501900067051e6514d4702d7dcda36ae..8aac5dacc14ac0338014b60ebfa5cd7b9f378cb9 100644 (file)
@@ -928,7 +928,8 @@ int smb_IsStarMask(char *maskp)
         
     for(i=0; i<11; i++) {
         tc = *maskp++;
-        if (tc == '?' || tc == '*' || tc == '>') return 1;        
+        if (tc == '?' || tc == '*' || tc == '>')
+           return 1;
     }  
     return 0;
 }
@@ -951,7 +952,7 @@ void smb_ReleaseVCInternal(smb_vc_t *vcp)
                break;
            }
        } 
-
+       lock_FinalizeMutex(&vcp->mx);
        memset(vcp,0,sizeof(smb_vc_t));
        free(vcp);
     }
@@ -995,7 +996,6 @@ void smb_CleanupDeadVC(smb_vc_t *vcp)
     unsigned short tid;
     smb_user_t *uidpIter;
     smb_user_t *uidpNext;
-    unsigned short uid;
     smb_vc_t **vcpp;
 
     osi_Log1(smb_logp, "Cleaning up dead vcp 0x%x", vcp);
@@ -1013,9 +1013,9 @@ void smb_CleanupDeadVC(smb_vc_t *vcp)
        smb_HoldFIDNoLock(fidpIter);
         lock_ReleaseWrite(&smb_rctLock);
 
-       /* smb_CloseFID sets SMB_FID_DELETE */
-        if (smb_CloseFID(vcp, fidpIter, NULL, 0) == 0)
-           smb_ReleaseFID(fidpIter);
+       /* smb_CloseFID sets SMB_FID_DELETE on Success */
+        smb_CloseFID(vcp, fidpIter, NULL, 0);
+       smb_ReleaseFID(fidpIter);
 
         lock_ObtainWrite(&smb_rctLock);
        fidpNext = vcp->fidsp;
@@ -1422,8 +1422,8 @@ smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags)
         if (newFid) {
             vcp->fidCounter = fid+1;
             if (vcp->fidCounter == 0) {
-                osi_Log1(smb_logp, "fidCounter wrapped around for vcp 0x%x",
-                         vcp);
+               osi_Log1(smb_logp, "fidCounter wrapped around for vcp 0x%x",
+                        vcp);
                 vcp->fidCounter = 1;
            }
        }
@@ -1445,11 +1445,9 @@ void smb_ReleaseFID(smb_fid_t *fidp)
     smb_vc_t *vcp = NULL;
     smb_ioctl_t *ioctlp;
 
-    if (!fidp)
-        return;
-
     lock_ObtainWrite(&smb_rctLock);
     osi_assert(fidp->refCount-- > 0);
+    lock_ObtainMutex(&fidp->mx);
     if (fidp->refCount == 0 && (fidp->flags & SMB_FID_DELETE)) {
         vcp = fidp->vcp;
         fidp->vcp = NULL;
@@ -1473,10 +1471,14 @@ void smb_ReleaseFID(smb_fid_t *fidp)
             free(ioctlp);
         }       
 
+       lock_ReleaseMutex(&fidp->mx);
+       lock_FinalizeMutex(&fidp->mx);
         free(fidp);
 
        if (vcp)
            smb_ReleaseVCNoLock(vcp);
+    } else {
+       lock_ReleaseMutex(&fidp->mx);
     }
     lock_ReleaseWrite(&smb_rctLock);
 
@@ -2941,8 +2943,10 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp
     if (!rawBuf)
         goto send1a;
 
+    lock_ObtainMutex(&fidp->mx);
     if (fidp->flags & SMB_FID_IOCTL)
     {
+       lock_ReleaseMutex(&fidp->mx);
 #ifndef DJGPP
         rc = smb_IoctlReadRaw(fidp, vcp, inp, outp);
 #else
@@ -2964,7 +2968,8 @@ long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp
         smb_ReleaseFID(fidp);
         return rc;
     }
-        
+    lock_ReleaseMutex(&fidp->mx);
+
     userp = smb_GetUser(vcp, inp);
 
 #ifndef DJGPP
@@ -3313,11 +3318,7 @@ void smb_Daemon(void *parmp)
            smb_CheckVCs();
        }
 
-       /* XXX GC the smb_username_t objects with refCount 0 and
-        * neither SMB_USERNAMEFLAG_AFSLOGON nor (SMB_USERNAMEFLAG_LOGOFF
-        * && smb_LogoffTokenTransfer && 
-        * now > last_logoff_t + smb_LogoffTransferTimeout) 
-        */
+       /* GC smb_username_t objects that will no longer be used */
        now = osi_Time();
        lock_ObtainWrite(&smb_rctLock);
        for ( unpp=&usernamesp; *unpp; ) {
@@ -3325,13 +3326,12 @@ void smb_Daemon(void *parmp)
            smb_username_t *unp;
 
            lock_ObtainMutex(&(*unpp)->mx);
-           if ( (*unpp)->refCount > 0 )
+           if ( (*unpp)->refCount > 0 || 
+                ((*unpp)->flags & SMB_USERNAMEFLAG_AFSLOGON) || 
+                !((*unpp)->flags & SMB_USERNAMEFLAG_LOGOFF))
                ;
-           else if ((*unpp)->flags & SMB_USERNAMEFLAG_AFSLOGON)
-               ;
-           else if (!(((*unpp)->flags & SMB_USERNAMEFLAG_LOGOFF) && smb_LogoffTokenTransfer))
-               delete = 1;
-           else if ((*unpp)->last_logoff_t + smb_LogoffTransferTimeout < now)
+           else if (!smb_LogoffTokenTransfer ||
+                    ((*unpp)->last_logoff_t + smb_LogoffTransferTimeout < now))
                delete = 1;
            lock_ReleaseMutex(&(*unpp)->mx);
 
@@ -4852,12 +4852,14 @@ long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     cm_HoldUser(userp);
     fidp->userp = userp;
 
+    lock_ObtainMutex(&fidp->mx);
     if ((share & 0xf) == 0)
         fidp->flags |= SMB_FID_OPENREAD;
     else if ((share & 0xf) == 1)
         fidp->flags |= SMB_FID_OPENWRITE;
     else 
         fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+    lock_ReleaseMutex(&fidp->mx);
 
     lock_ObtainMutex(&scp->mx);
     smb_SetSMBParm(outp, 0, fidp->fid);
@@ -5593,11 +5595,16 @@ long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 
     fid = smb_ChainFID(fid, inp);
     fidp = smb_FindFID(vcp, fid, 0);
-    if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
-        if (fidp)
-            smb_ReleaseFID(fidp);
+    if (!fidp)
+       return CM_ERROR_BADFD;
+    
+    lock_ObtainMutex(&fidp->mx);
+    if (fidp->flags & SMB_FID_IOCTL) {
+       lock_ReleaseMutex(&fidp->mx);
+       smb_ReleaseFID(fidp);
         return CM_ERROR_BADFD;
     }
+    lock_ReleaseMutex(&fidp->mx);
         
     userp = smb_GetUser(vcp, inp);
 
@@ -5673,13 +5680,16 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
              fidp, fidp->fid, vcp);
 
     if (!userp) {
+       lock_ObtainMutex(&fidp->mx);
         if (!fidp->userp && !(fidp->flags & SMB_FID_IOCTL)) {
+           lock_ReleaseMutex(&fidp->mx);
             osi_Log0(smb_logp, "  No user specified.  Not closing fid");
            return CM_ERROR_BADFD;
        }
         
         userp = fidp->userp;    /* no hold required since fidp is held
                                    throughout the function */
+       lock_ReleaseMutex(&fidp->mx);
     }
 
     cm_InitReq(&req);
@@ -6027,6 +6037,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
         
     /* make sure we have a writable FD */
     if (!(fidp->flags & SMB_FID_OPENWRITE)) {
+       lock_ReleaseMutex(&fidp->mx);
         code = CM_ERROR_BADFDOP;
         goto done;
     }
@@ -6191,7 +6202,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
 
   done:
     lock_ReleaseMutex(&scp->mx);
-    lock_ReleaseMutex(&fidp->mx);
+
     if (bufferp) {
         lock_ReleaseMutex(&bufferp->mx);
         buf_Release(bufferp);
@@ -6203,6 +6214,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
                           fidp->NTopen_dscp, fidp->NTopen_pathp,
                           NULL, TRUE);
     }       
+    lock_ReleaseMutex(&fidp->mx);
 
     if (code == 0 && doWriteBack) {
         long code2;
@@ -6248,13 +6260,17 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         
     fd = smb_ChainFID(fd, inp);
     fidp = smb_FindFID(vcp, fd, 0);
-    if (!fidp) {
+    if (!fidp)
         return CM_ERROR_BADFD;
-    }
-        
-    if (fidp->flags & SMB_FID_IOCTL)
-        return smb_IoctlWrite(fidp, vcp, inp, outp);
         
+    lock_ObtainMutex(&fidp->mx);
+    if (fidp->flags & SMB_FID_IOCTL) {
+       lock_ReleaseMutex(&fidp->mx);
+        code = smb_IoctlWrite(fidp, vcp, inp, outp);
+       smb_ReleaseFID(fidp);
+       return code;
+    }
+    lock_ReleaseMutex(&fidp->mx);
     userp = smb_GetUser(vcp, inp);
 
     /* special case: 0 bytes transferred means truncate to this position */
@@ -6306,10 +6322,12 @@ long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
      * and don't set client mod time if we think that would go against the
      * intention.
      */
+    lock_ObtainMutex(&fidp->mx);
     if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) {
         fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
         fidp->scp->clientModTime = time(NULL);
     }
+    lock_ReleaseMutex(&fidp->mx);
 
     code = 0;
     while ( code == 0 && count > 0 ) {
@@ -6484,10 +6502,12 @@ long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
      * and don't set client mod time if we think that would go against the
      * intention.
      */
+    lock_ObtainMutex(&fidp->mx);
     if ((fidp->flags & SMB_FID_LOOKSLIKECOPY) != SMB_FID_LOOKSLIKECOPY) {
         fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
         fidp->scp->clientModTime = time(NULL);
     }
+    lock_ReleaseMutex(&fidp->mx);
 
     code = 0;
     while ( code == 0 && count > 0 ) {
@@ -6581,13 +6601,17 @@ long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         
     fd = smb_ChainFID(fd, inp);
     fidp = smb_FindFID(vcp, fd, 0);
-    if (!fidp) {
+    if (!fidp)
         return CM_ERROR_BADFD;
-    }
         
+    lock_ObtainMutex(&fidp->mx);
     if (fidp->flags & SMB_FID_IOCTL) {
-        return smb_IoctlRead(fidp, vcp, inp, outp);
+       lock_ReleaseMutex(&fidp->mx);
+        code = smb_IoctlRead(fidp, vcp, inp, outp);
+       smb_ReleaseFID(fidp);
+       return code;
     }
+    lock_ReleaseMutex(&fidp->mx);
 
     {
         LARGE_INTEGER LOffset, LLength;
@@ -6929,22 +6953,24 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
     osi_assert(fidp);
        
+    cm_HoldUser(userp);
+
+    lock_ObtainMutex(&fidp->mx);
+    /* always create it open for read/write */
+    fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+
     /* save a pointer to the vnode */
     fidp->scp = scp;
     /* and the user */
-    cm_HoldUser(userp);
     fidp->userp = userp;
-        
-    /* always create it open for read/write */
-    fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+    lock_ReleaseMutex(&fidp->mx);
 
-    smb_ReleaseFID(fidp);
-        
     smb_SetSMBParm(outp, 0, fidp->fid);
     smb_SetSMBDataLength(outp, 0);
 
     cm_Open(scp, 0, userp);
 
+    smb_ReleaseFID(fidp);
     cm_ReleaseUser(userp);
     /* leave scp held since we put it in fidp->scp */
     return 0;
@@ -6970,9 +6996,17 @@ long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     /* try to find the file descriptor */
     fd = smb_ChainFID(fd, inp);
     fidp = smb_FindFID(vcp, fd, 0);
-    if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+
+    if (!fidp)
+       return CM_ERROR_BADFD;
+    
+    lock_ObtainMutex(&fidp->mx);
+    if (fidp->flags & SMB_FID_IOCTL) {
+       lock_ReleaseMutex(&fidp->mx);
+       smb_ReleaseFID(fidp);
         return CM_ERROR_BADFD;
     }
+    lock_ReleaseMutex(&fidp->mx);
        
     userp = smb_GetUser(vcp, inp);
 
@@ -7962,8 +7996,10 @@ void smb_Listener(void *parmp)
 #endif /* !DJGPP */
            }
            
+           lock_ObtainMutex(&vcp->mx);
            strcpy(vcp->rname, rname);
            vcp->flags |= flags;
+           lock_ReleaseMutex(&vcp->mx);
 
            /* Allocate slot in session arrays */
            /* Re-use dead session if possible, otherwise add one more */
@@ -8046,7 +8082,6 @@ void smb_Listener(void *parmp)
            vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
            lock_ReleaseMutex(&vcp->mx);
            smb_CleanupDeadVC(vcp);
-           smb_ReleaseVC(vcp);
         } else {
             /* assert that we do not exceed the maximum number of sessions or NCBs.
              * we should probably want to wait for a session to be freed in case
@@ -8091,7 +8126,6 @@ void smb_Listener(void *parmp)
                 thrd_SetEvent(SessionEvents[session]);
             }
         }
-        
         smb_ReleaseVC(vcp);
 
         /* unlock */
index d24e3d6ba80e17a726064c30bc52148f0c9f1653..df1d0793a04dedf6219c8aada42da2b8da60adc2 100644 (file)
@@ -2349,16 +2349,19 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
     fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
     osi_assert(fidp);
        
+    cm_HoldUser(userp);
+    lock_ObtainMutex(&fidp->mx);
     /* save a pointer to the vnode */
     fidp->scp = scp;
     /* and the user */
-    cm_HoldUser(userp);
     fidp->userp = userp;
         
     /* compute open mode */
-    if (openMode != 1) fidp->flags |= SMB_FID_OPENREAD;
+    if (openMode != 1) 
+       fidp->flags |= SMB_FID_OPENREAD;
     if (openMode == 1 || openMode == 2)
         fidp->flags |= SMB_FID_OPENWRITE;
+    lock_ReleaseMutex(&fidp->mx);
 
     smb_ReleaseFID(fidp);
         
@@ -2923,7 +2926,9 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t
         *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */
         *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */
         *((u_long *)op) = scp->linkCount; op += 4;
+       lock_ObtainMutex(&fidp->mx);
         *op++ = ((fidp->flags & SMB_FID_DELONCLOSE) ? 1 : 0);
+       lock_ReleaseMutex(&fidp->mx);
         *op++ = (scp->fileType == CM_SCACHETYPE_DIRECTORY ? 1 : 0);
         *op++ = 0;
         *op++ = 0;
@@ -2990,17 +2995,21 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet
         return 0;
     }
 
+    lock_ObtainMutex(&fidp->mx);
     if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) {
-        smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
+       lock_ReleaseMutex(&fidp->mx);
         smb_ReleaseFID(fidp);
+        smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
         return 0;
     }
     if ((infoLevel == SMB_QUERY_FILE_EA_INFO || infoLevel == SMB_QUERY_FILE_NAME_INFO)
          && !(fidp->flags & SMB_FID_OPENWRITE)) {
-        smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
+       lock_ReleaseMutex(&fidp->mx);
         smb_ReleaseFID(fidp);
+        smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS);
         return 0;
     }
+    lock_ReleaseMutex(&fidp->mx);
 
     osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel);
 
@@ -3047,7 +3056,9 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet
              lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) {
             attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
             smb_UnixTimeFromLargeSearchTime(&attr.clientModTime, &lastMod);
+           lock_ObtainMutex(&fidp->mx);
             fidp->flags |= SMB_FID_MTIMESETDONE;
+           lock_ReleaseMutex(&fidp->mx);
         }
                
         attribute = *((u_long *)(p->datap + 32));
@@ -3086,12 +3097,17 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet
         if (*((char *)(p->datap))) {
             code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp,
                                      &req);
-            if (code == 0)          
+            if (code == 0) {
+               lock_ObtainMutex(&fidp->mx);
                 fidp->flags |= SMB_FID_DELONCLOSE;
-        }               
+               lock_ReleaseMutex(&fidp->mx);
+           }
+       }               
         else {  
             code = 0;
+           lock_ObtainMutex(&fidp->mx);
             fidp->flags &= ~SMB_FID_DELONCLOSE;
+           lock_ReleaseMutex(&fidp->mx);
         }
     }       
 
@@ -4730,10 +4746,11 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
     osi_assert(fidp);
        
+    cm_HoldUser(userp);
+    lock_ObtainMutex(&fidp->mx);
     /* save a pointer to the vnode */
     fidp->scp = scp;
     /* also the user */
-    cm_HoldUser(userp);
     fidp->userp = userp;
         
     /* compute open mode */
@@ -4742,6 +4759,7 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     if (openMode == 1 || openMode == 2)
         fidp->flags |= SMB_FID_OPENWRITE;
 
+    lock_ReleaseMutex(&fidp->mx);
     smb_ReleaseFID(fidp);
         
     cm_Open(scp, 0, userp);
@@ -4832,10 +4850,18 @@ long smb_ReceiveV3LockingX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     fid = smb_ChainFID(fid, inp);
 
     fidp = smb_FindFID(vcp, fid, 0);
-    if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+    if (!fidp)
+       return CM_ERROR_BADFD;
+    
+    lock_ObtainMutex(&fidp->mx);
+    if (fidp->flags & SMB_FID_IOCTL) {
         osi_Log0(smb_logp, "smb_ReceiveV3Locking BadFD");
+       lock_ReleaseMutex(&fidp->mx);
+       smb_ReleaseFID(fidp);
         return CM_ERROR_BADFD;
     }
+    lock_ReleaseMutex(&fidp->mx);
+
     /* set inp->fid so that later read calls in same msg can find fid */
     inp->fid = fid;
 
@@ -5062,9 +5088,16 @@ long smb_ReceiveV3GetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
     fid = smb_ChainFID(fid, inp);
         
     fidp = smb_FindFID(vcp, fid, 0);
-    if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+    if (!fidp)
+       return CM_ERROR_BADFD;
+    
+    lock_ObtainMutex(&fidp->mx);
+    if (fidp->flags & SMB_FID_IOCTL) {
+       lock_ReleaseMutex(&fidp->mx);
+       smb_ReleaseFID(fidp);
         return CM_ERROR_BADFD;
     }
+    lock_ReleaseMutex(&fidp->mx);
         
     userp = smb_GetUser(vcp, inp);
         
@@ -5126,9 +5159,16 @@ long smb_ReceiveV3SetAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
     fid = smb_ChainFID(fid, inp);
         
     fidp = smb_FindFID(vcp, fid, 0);
-    if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+    if (!fidp)
+       return CM_ERROR_BADFD;
+    
+    lock_ObtainMutex(&fidp->mx);
+    if (fidp->flags & SMB_FID_IOCTL) {
+       lock_ReleaseMutex(&fidp->mx);
+       smb_ReleaseFID(fidp);
         return CM_ERROR_BADFD;
     }
+    lock_ReleaseMutex(&fidp->mx);
         
     userp = smb_GetUser(vcp, inp);
         
@@ -5211,9 +5251,14 @@ long smb_ReceiveV3ReadX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     /* set inp->fid so that later read calls in same msg can find fid */
     inp->fid = fd;
 
+    lock_ObtainMutex(&fidp->mx);
     if (fidp->flags & SMB_FID_IOCTL) {
-        return smb_IoctlV3Read(fidp, vcp, inp, outp);
+       lock_ReleaseMutex(&fidp->mx);
+        code = smb_IoctlV3Read(fidp, vcp, inp, outp);
+       smb_ReleaseFID(fidp);
+       return code;
     }
+    lock_ReleaseMutex(&fidp->mx);
 
     userp = smb_GetUser(vcp, inp);
 
@@ -5449,6 +5494,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
     }
 
     if (baseFid == 0) {
+       baseFidp = NULL;
         baseDirp = cm_data.rootSCachep;
         code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
         if (code == CM_ERROR_TIDIPC) {
@@ -5509,6 +5555,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                 cm_ReleaseSCache(dscp);
                 cm_ReleaseUser(userp);
                 free(realPathp);
+               if (baseFidp) 
+                   smb_ReleaseFID(baseFidp);
                 if ( WANTS_DFS_PATHNAMES(inp) )
                     return CM_ERROR_PATH_NOT_COVERED;
                 else
@@ -5525,6 +5573,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                     cm_ReleaseSCache(dscp);
                     cm_ReleaseUser(userp);
                     free(realPathp);
+                   if (baseFidp) 
+                       smb_ReleaseFID(baseFidp);
                     return CM_ERROR_EXISTS;
                 }
             }
@@ -5538,6 +5588,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
             free(realPathp);
+           if (baseFidp) 
+               smb_ReleaseFID(baseFidp);
             if ( WANTS_DFS_PATHNAMES(inp) )
                 return CM_ERROR_PATH_NOT_COVERED;
             else
@@ -5574,6 +5626,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                     cm_ReleaseSCache(dscp);
                     cm_ReleaseUser(userp);
                     free(realPathp);
+                   if (baseFidp) 
+                       smb_ReleaseFID(baseFidp);
                     if ( WANTS_DFS_PATHNAMES(inp) )
                         return CM_ERROR_PATH_NOT_COVERED;
                     else
@@ -5590,7 +5644,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                     treeStartp = realPathp + (tp - spacep->data);
 
                     if (*tp && !smb_IsLegalFilename(tp)) {
-                        if (baseFid != 0
+                        if (baseFidp
                             smb_ReleaseFID(baseFidp);
                         cm_ReleaseUser(userp);
                         free(realPathp);
@@ -5606,7 +5660,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 
         /* we might have scp and we might have dscp */
 
-        if (baseFid != 0) 
+        if (baseFidp)
             smb_ReleaseFID(baseFidp);
 
         if (code) {
@@ -5668,7 +5722,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         /* we have scp and dscp */
     } else {
         /* we have scp but not dscp */
-        if (baseFid != 0) 
+        if (baseFidp)
             smb_ReleaseFID(baseFidp);
     }
 
@@ -5955,7 +6009,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         lock_ReleaseMutex(&scp->mx);
 
         if (code) {
-            fidp->flags = SMB_FID_DELETE;
+            /* shouldn't this be smb_CloseFID() fidp->flags = SMB_FID_DELETE; */
+           smb_CloseFID(vcp, fidp, NULL, 0);
             smb_ReleaseFID(fidp);
 
             cm_ReleaseSCache(scp);
@@ -5968,6 +6023,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         }
     }
 
+    lock_ObtainMutex(&fidp->mx);
     /* save a pointer to the vnode */
     fidp->scp = scp;    /* Hold transfered to fidp->scp and no longer needed */
 
@@ -5981,6 +6037,7 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         fidp->NTopen_pathp = strdup(lastNamep);
     }
     fidp->NTopen_wholepathp = realPathp;
+    lock_ReleaseMutex(&fidp->mx);
 
     /* we don't need this any longer */
     if (dscp) {
@@ -6173,6 +6230,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     }
 
     if (baseFid == 0) {
+       baseFidp = NULL;
         baseDirp = cm_data.rootSCachep;
         code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
         if (code == CM_ERROR_TIDIPC) {
@@ -6191,7 +6249,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
     } else {
         baseFidp = smb_FindFID(vcp, baseFid, 0);
         if (!baseFidp) {
-               osi_Log1(smb_logp, "NTTranCreate Invalid fid [%d]", baseFid);
+           osi_Log1(smb_logp, "NTTranCreate Invalid fid [%d]", baseFid);
             free(realPathp);
             cm_ReleaseUser(userp);
             return CM_ERROR_INVAL;
@@ -6230,6 +6288,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
                 cm_ReleaseSCache(dscp);
                 cm_ReleaseUser(userp);
                 free(realPathp);
+               if (baseFidp)
+                   smb_ReleaseFID(baseFidp);
                 if ( WANTS_DFS_PATHNAMES(inp) )
                     return CM_ERROR_PATH_NOT_COVERED;
                 else
@@ -6246,6 +6306,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
                     cm_ReleaseSCache(dscp);
                     cm_ReleaseUser(userp);
                     free(realPathp);
+                   if (baseFidp)
+                       smb_ReleaseFID(baseFidp);
                     return CM_ERROR_EXISTS;
                 }
             }
@@ -6259,6 +6321,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
             cm_ReleaseSCache(scp);
             cm_ReleaseUser(userp);
             free(realPathp);
+           if (baseFidp)
+               smb_ReleaseFID(baseFidp);
             if ( WANTS_DFS_PATHNAMES(inp) )
                 return CM_ERROR_PATH_NOT_COVERED;
             else
@@ -6281,6 +6345,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
                 cm_ReleaseSCache(dscp);
                 cm_ReleaseUser(userp);
                 free(realPathp);
+               if (baseFidp)
+                   smb_ReleaseFID(baseFidp);
                 if ( WANTS_DFS_PATHNAMES(inp) )
                     return CM_ERROR_PATH_NOT_COVERED;
                 else
@@ -6292,10 +6358,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
         
         cm_FreeSpace(spacep);
 
-        if (baseFid != 0) {
+        if (baseFidp)
             smb_ReleaseFID(baseFidp);
-            baseFidp = 0;
-        }
 
         if (code) {
             cm_ReleaseUser(userp);
@@ -6303,8 +6367,10 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
             return code;
         }
 
-        if (!lastNamep) lastNamep = realPathp;
-        else lastNamep++;
+        if (!lastNamep)
+           lastNamep = realPathp;
+        else 
+           lastNamep++;
 
         if (!smb_IsLegalFilename(lastNamep))
             return CM_ERROR_BADNTFILENAME;
@@ -6326,10 +6392,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
             }
         }
     } else {
-        if (baseFid != 0) {
+        if (baseFidp)
             smb_ReleaseFID(baseFidp);
-            baseFidp = 0;
-        }
         cm_FreeSpace(spacep);
     }
 
@@ -6547,7 +6611,8 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
         lock_ReleaseMutex(&scp->mx);
 
         if (code) {
-            fidp->flags = SMB_FID_DELETE;
+            /* Shouldn't this be smb_CloseFID()?  fidp->flags = SMB_FID_DELETE; */
+           smb_CloseFID(vcp, fidp, NULL, 0);
             smb_ReleaseFID(fidp);
 
             cm_ReleaseSCache(scp);
@@ -6558,6 +6623,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
         }
     }
 
+    lock_ObtainMutex(&fidp->mx);
     /* save a pointer to the vnode */
     fidp->scp = scp;
 
@@ -6571,6 +6637,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out
         fidp->NTopen_pathp = strdup(lastNamep);
     }
     fidp->NTopen_wholepathp = realPathp;
+    lock_ReleaseMutex(&fidp->mx);
 
     /* we don't need this any longer */
     if (dscp) 
index dba453c5526884bc18e5d89336bda5c4656a1da2..869738ef90506fbb915e16c3c3aafb18b98362d6 100644 (file)
@@ -231,7 +231,6 @@ long smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
         iop->outCopied += count;
         
         cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
 
         return 0;
 }
@@ -274,7 +273,6 @@ done:
                 smb_SetSMBDataLength(outp, 0);
         }
 
-        smb_ReleaseFID(fidp);
         return code;
 }
 
@@ -315,7 +313,6 @@ long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_pack
        if (uidp)
            smb_ReleaseUID(uidp);
         cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
         return CM_ERROR_NOSUCHPATH;
     }
 
@@ -326,7 +323,6 @@ long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_pack
     }
     if (code) {
        cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
        return code;
     }
 
@@ -366,7 +362,6 @@ long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_pack
 
     /* and cleanup things */
     cm_ReleaseUser(userp);
-    smb_ReleaseFID(fidp);
 
     return 0;
 }      
@@ -421,14 +416,12 @@ long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
     code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
     if (code) {
         cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
         return CM_ERROR_NOSUCHPATH;
     }
 
     code = smb_IoctlPrepareRead(fidp, iop, userp);
     if (code) {
        cm_ReleaseUser(userp);
-       smb_ReleaseFID(fidp);
        return code;
     }
 
@@ -457,7 +450,6 @@ long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
        osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
 
     cm_ReleaseUser(userp);
-    smb_ReleaseFID(fidp);
 
     return 0;
 }