]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-windows-smb-username-refcount-20060110
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 10 Jan 2006 13:28:01 +0000 (13:28 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 10 Jan 2006 13:28:01 +0000 (13:28 +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.

(cherry picked from commit a9df3ca715f483a31c14b72bae3f548a4c9291d4)

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

index ffdd6d59c21a2fb30b03502fdcfc91f1b1605826..a4bfa36a57b1671ce780d1fdab759fae0e2cb2ea 100644 (file)
@@ -1882,6 +1882,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;
 
@@ -1951,6 +1952,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 */
@@ -1988,6 +1990,9 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     cm_ResetACLCache(userp);
 
+    if (release_userp)
+       cm_ReleaseUser(userp);
+
     return 0;
 }
 
index a3b570824493d22fa0044ca971b3a8777e9b2a1c..1c326bbfe952d9bbb08d151f63739815272f211b 100644 (file)
@@ -1130,13 +1130,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)) {
@@ -1148,20 +1178,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.
@@ -5898,7 +5923,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 89d66889485c17f99a7a3ddc60fafb7959059e7f..e5c7ad347038107988b9f272ed71adb60f6b1aa3 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 2adfb80560e8dc6a74a52833560a30ca7c5630fd..4d8af4dc19c1768930a431be65c652ae825f3adf 100644 (file)
@@ -7173,9 +7173,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);
@@ -7188,7 +7187,9 @@ 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));
         osi_LogEvent("AFS smb_FindCMUserByName : Found",NULL,"name[%s] machine[%s]",usern,machine);
-       }
+    }
+    cm_HoldUser(unp->userp);
+    smb_ReleaseUsername(unp);
     return unp->userp;
 }