STABLE14-windows-smb-username-refcount-20060110

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)
This commit is contained in:
Jeffrey Altman 2006-01-10 13:28:01 +00:00
parent d06884e28b
commit 29a68de93b
4 changed files with 49 additions and 16 deletions

View 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;
}

View 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;
}

View 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);

View 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;
}