windows-smb-username-refcount-20060110
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 10 Jan 2006 13:26:41 +0000 (13:26 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 10 Jan 2006 13:26:41 +0000 (13:26 +0000)
the smb_username_t objects are reference counted but they were never
released on their own accord.  Instead the smb_uid_t objects when
released were also cleaning up the smb_username_t.  Since the smb_username_t
is reused, now that smb_user_t objects are being cleaned up, this was
a problem.

src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb.h
src/WINNT/afsd/smb3.c

index d3ce847..cbb0fa9 100644 (file)
@@ -1914,6 +1914,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     int flags;
     char sessionKey[8];
     char *smbname;
+    int release_userp = 0;
 
     saveDataPtr = ioctlp->inDatap;
 
@@ -1985,6 +1986,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     if (flags & PIOCTL_LOGON) {
         userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname);
+       release_userp = 1;
     }
 
     /* store the token */
@@ -2022,6 +2024,9 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     cm_ResetACLCache(userp);
 
+    if (release_userp)
+       cm_ReleaseUser(userp);
+
     return 0;
 }
 
index 20a9254..e849ac3 100644 (file)
@@ -1137,13 +1137,43 @@ smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern)
     lock_ReleaseWrite(&smb_rctLock);
     return uidp;
 }       
+
+void smb_ReleaseUsername(smb_username_t *unp)
+{
+    smb_username_t *up;
+    smb_username_t **lupp;
+    cm_user_t *userp = NULL;
+
+    lock_ObtainWrite(&smb_rctLock);
+    osi_assert(unp->refCount-- > 0);
+    if (unp->refCount == 0) {
+        lupp = &usernamesp;
+        for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
+            if (up == unp) 
+                break;
+        }
+        osi_assert(up != NULL);
+        *lupp = up->nextp;
+        lock_FinalizeMutex(&unp->mx);
+       userp = unp->userp;
+       free(unp->name);
+       free(unp->machine);
+       free(unp);
+    }          
+    lock_ReleaseWrite(&smb_rctLock);
+
+    if (userp) {
+        cm_ReleaseUserVCRef(userp);
+        cm_ReleaseUser(userp);
+    }  
+}      
+
 void smb_ReleaseUID(smb_user_t *uidp)
 {
     smb_user_t *up;
     smb_user_t **lupp;
-    cm_user_t *userp;
+    smb_username_t *unp = NULL;
 
-    userp = NULL;
     lock_ObtainWrite(&smb_rctLock);
     osi_assert(uidp->refCount-- > 0);
     if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) {
@@ -1155,20 +1185,15 @@ void smb_ReleaseUID(smb_user_t *uidp)
         osi_assert(up != NULL);
         *lupp = up->nextp;
         lock_FinalizeMutex(&uidp->mx);
-        if (uidp->unp) {
-            userp = uidp->unp->userp;   /* avoid deadlock by releasing */
-            uidp->unp->userp = NULL;    /* after releasing the lock */
-        }       
+       unp = uidp->unp;
         smb_ReleaseVCNoLock(uidp->vcp);
-        uidp->vcp = NULL;
+       free(uidp);
     }          
     lock_ReleaseWrite(&smb_rctLock);
-    if (userp) {
-        cm_ReleaseUserVCRef(userp);
-        cm_ReleaseUser(userp);
-    }  
-}      
 
+    if (unp)
+       smb_ReleaseUsername(unp);
+}      
 
 /* retrieve a held reference to a user structure corresponding to an incoming
  * request.
@@ -5893,7 +5918,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
         /* handle over quota or out of space */
         if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) {
             *writtenp = written;
-            code = CM_ERROR_QUOTA;
+            code = (scp->flags & CM_SCACHEFLAG_OVERQUOTA) ? CM_ERROR_QUOTA : CM_ERROR_SPACE;
             break;
         }
 
index 02a2a75..81fda64 100644 (file)
@@ -505,6 +505,8 @@ extern smb_username_t *smb_FindUserByName(char *usern, char *machine, int flags)
 
 extern smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern);
 
+extern void smb_ReleaseUsername(smb_username_t *unp);
+
 extern void smb_ReleaseUID(smb_user_t *uidp);
 
 extern cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp);
index 0436732..fefc6e5 100644 (file)
@@ -7146,9 +7146,8 @@ void smb3_Init()
     lock_InitializeMutex(&smb_Dir_Watch_Lock, "Directory Watch List Lock");
 }
 
-cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine)
+cm_user_t *smb_FindCMUserByName(char *usern, char *machine)
 {
-    /*int newUid;*/
     smb_username_t *unp;
 
     unp = smb_FindUserByName(usern, machine, SMB_FLAG_CREATE);
@@ -7160,6 +7159,8 @@ cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine)
     }  else    {
         osi_Log2(smb_logp,"smb_FindCMUserByName Not found name[%s] machine[%s]",osi_LogSaveString(smb_logp,usern),osi_LogSaveString(smb_logp,machine));
     }
+    cm_HoldUser(unp->userp);
+    smb_ReleaseUsername(unp);
     return unp->userp;
 }