From 880a6b66a5477e092d5bb74febbf24639d786c64 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 16 Jan 2006 02:05:27 +0000 Subject: [PATCH] windows-vc-locks-and-more-20060115 This patch fixes several issues: * the smb virtual circuits can be active and/or dead. this patch improves the handling of vc's making the transition from active to dead * correct the refcounts on the smb_user_t and smb_vc_t objects * replace the deprecated GetCurrentTime() with GetTickCounts() which is the new name. This function needs to be replaced with something else because its return value wraps after 49.7 days * hold the correct locks when adjusting the scp->fileLocksH queue * add new event log entries for unexpected session closures and send packet failures --- src/WINNT/afsd/afsd_eventlog.c | 4 + src/WINNT/afsd/afsd_eventmessages.mc | 18 +++ src/WINNT/afsd/cm_conn.c | 6 +- src/WINNT/afsd/cm_vnodeops.c | 12 +- src/WINNT/afsd/smb.c | 126 +++++++++++--------- src/WINNT/afsd/smb.h | 2 + src/WINNT/afsd/smb3.c | 18 +-- src/WINNT/afsd/smb_ioctl.c | 216 ++++++++++++++++++----------------- 8 files changed, 228 insertions(+), 174 deletions(-) diff --git a/src/WINNT/afsd/afsd_eventlog.c b/src/WINNT/afsd/afsd_eventlog.c index 6bb7078..6d71062 100644 --- a/src/WINNT/afsd/afsd_eventlog.c +++ b/src/WINNT/afsd/afsd_eventlog.c @@ -212,6 +212,8 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...) case MSG_SERVICE_RUNNING: case MSG_SERVICE_STOPPING: case MSG_SERVICE_ERROR_STOP: + case MSG_CRYPT_OFF: + case MSG_CRYPT_ON: break; case MSG_FLUSH_BAD_SHARE_NAME: case MSG_FLUSH_OPEN_ENUM_ERROR: @@ -219,6 +221,8 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...) case MSG_FLUSH_FAILED: case MSG_RX_HARD_DEAD_TIME_EXCEEDED: case MSG_SERVICE_ERROR_STOP_WITH_MSG: + case MSG_SMB_SEND_PACKET_FAILURE: + case MSG_UNEXPECTED_SMB_SESSION_CLOSE: wNumArgs = 1; lpArgs[0] = va_arg(listArgs, LPTSTR); break; diff --git a/src/WINNT/afsd/afsd_eventmessages.mc b/src/WINNT/afsd/afsd_eventmessages.mc index 7c4bc9e..23fa970 100644 --- a/src/WINNT/afsd/afsd_eventmessages.mc +++ b/src/WINNT/afsd/afsd_eventmessages.mc @@ -332,4 +332,22 @@ Security Level is Crypt. . +MessageId= +Severity=Warning +Facility=System +SymbolicName=MSG_SMB_SEND_PACKET_FAILURE +Language=English +Unable to Send SMB Packet: %1. +. + + +MessageId= +Severity=Warning +Facility=System +SymbolicName=MSG_UNEXPECTED_SMB_SESSION_CLOSE +Language=English +Unexpected SMB Session Close: %1. +. + + ;#endif /* __AFSD_EVENTMESSAGES_H_ 1 */ diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 6149768..f6b79b9 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -85,7 +85,7 @@ void cm_InitReq(cm_req_t *reqp) { memset((char *)reqp, 0, sizeof(cm_req_t)); #ifndef DJGPP - reqp->startTime = GetCurrentTime(); + reqp->startTime = GetTickCount(); #else gettimeofday(&reqp->startTime, NULL); #endif @@ -185,7 +185,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, /* timeleft - get if from reqp the same way as cmXonnByMServers does */ #ifndef DJGPP - timeUsed = (GetCurrentTime() - reqp->startTime) / 1000; + timeUsed = (GetTickCount() - reqp->startTime) / 1000; #else gettimeofday(&now, NULL); timeUsed = sub_time(now, reqp->startTime) / 1000; @@ -542,7 +542,7 @@ long cm_ConnByMServers(cm_serverRef_t *serversp, cm_user_t *usersp, *connpp = NULL; #ifndef DJGPP - timeUsed = (GetCurrentTime() - reqp->startTime) / 1000; + timeUsed = (GetTickCount() - reqp->startTime) / 1000; #else gettimeofday(&now, NULL); timeUsed = sub_time(now, reqp->startTime) / 1000; diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index b3feb75..b97c716 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -3610,9 +3610,8 @@ long cm_Lock(cm_scache_t *scp, unsigned char sLockType, fileLock->lastUpdate = (code == 0) ? time(NULL) : 0; - osi_QAddT(&scp->fileLocksH, &scp->fileLocksT, &fileLock->fileq); - lock_ObtainWrite(&cm_scacheLock); + osi_QAddT(&scp->fileLocksH, &scp->fileLocksT, &fileLock->fileq); cm_HoldSCacheNoLock(scp); fileLock->scp = scp; osi_QAdd(&cm_allFileLocks, &fileLock->q); @@ -3886,20 +3885,19 @@ long cm_Unlock(cm_scache_t *scp, return 0; } + lock_ReleaseRead(&cm_scacheLock); + /* discard lock record */ + lock_ObtainWrite(&cm_scacheLock); if (scp->fileLocksT == q) scp->fileLocksT = osi_QPrev(q); osi_QRemove(&scp->fileLocksH, q); - lock_ReleaseRead(&cm_scacheLock); - /* * Don't delete it here; let the daemon delete it, to simplify * the daemon's traversal of the list. */ - lock_ObtainWrite(&cm_scacheLock); - if (IS_LOCK_ACCEPTED(fileLock)) { if (fileLock->lockType == LockRead) scp->sharedLocks--; @@ -4441,9 +4439,11 @@ long cm_RetryLock(cm_file_lock_t *oldFileLock, int client_is_dead) handleCode: if (code != 0 && code != CM_ERROR_WOULDBLOCK) { + lock_ObtainWrite(&cm_scacheLock); if (scp->fileLocksT == &oldFileLock->fileq) scp->fileLocksT = osi_QPrev(&oldFileLock->fileq); osi_QRemove(&scp->fileLocksH, &oldFileLock->fileq); + lock_ReleaseWrite(&cm_scacheLock); } else if (code == 0 && IS_LOCK_WAITLOCK(oldFileLock)) { scp->serverLock = newLock; } diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 88e9303..a5cfe6b 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -872,10 +872,10 @@ smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana) vcp = malloc(sizeof(*vcp)); memset(vcp, 0, sizeof(*vcp)); vcp->vcID = numVCs++; - vcp->refCount = 1; + vcp->refCount = 2; /* smb_allVCsp and caller */ vcp->tidCounter = 1; vcp->fidCounter = 1; - vcp->uidCounter = 1; /* UID 0 is reserved for blank user */ + vcp->uidCounter = 1; /* UID 0 is reserved for blank user */ vcp->nextp = smb_allVCsp; smb_allVCsp = vcp; lock_InitializeMutex(&vcp->mx, "vc_t mutex"); @@ -933,25 +933,31 @@ int smb_IsStarMask(char *maskp) return 0; } -void smb_ReleaseVCNoLock(smb_vc_t *vcp) +void smb_ReleaseVCInternal(smb_vc_t *vcp) { - osi_Log2(smb_logp,"smb_ReleaseVCNoLock vcp %x ref %d",vcp, vcp->refCount); #ifdef DEBUG osi_assert(vcp->refCount-- != 0); #else vcp->refCount--; #endif + + if (vcp->refCount == 0) { + memset(vcp,0,sizeof(smb_vc_t)); + free(vcp); + } +} + +void smb_ReleaseVCNoLock(smb_vc_t *vcp) +{ + osi_Log2(smb_logp,"smb_ReleaseVCNoLock vcp %x ref %d",vcp, vcp->refCount); + smb_ReleaseVCInternal(vcp); } void smb_ReleaseVC(smb_vc_t *vcp) { lock_ObtainWrite(&smb_rctLock); osi_Log2(smb_logp,"smb_ReleaseVC vcp %x ref %d",vcp, vcp->refCount); -#ifdef DEBUG - osi_assert(vcp->refCount-- != 0); -#else - vcp->refCount--; -#endif + smb_ReleaseVCInternal(vcp); lock_ReleaseWrite(&smb_rctLock); } @@ -983,6 +989,7 @@ void smb_CleanupDeadVC(smb_vc_t *vcp) smb_user_t *userpNext; smb_user_t *userp; unsigned short uid; + smb_vc_t **vcpp; osi_Log1(smb_logp, "Cleaning up dead vcp 0x%x", vcp); @@ -1049,8 +1056,15 @@ void smb_CleanupDeadVC(smb_vc_t *vcp) lock_ObtainRead(&smb_rctLock); } + /* remove VCP from smb_allVCsp */ + for (vcpp = &smb_allVCsp; *vcpp; vcpp = &((*vcpp)->nextp)) { + if (*vcpp == vcp) { + *vcpp = vcp->nextp; + smb_ReleaseVCNoLock(vcp); + break; + } + } lock_ReleaseRead(&smb_rctLock); - osi_Log0(smb_logp, "Done cleaning up dead vcp"); } @@ -1126,7 +1140,7 @@ smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags) uidp = malloc(sizeof(*uidp)); memset(uidp, 0, sizeof(*uidp)); uidp->nextp = vcp->usersp; - uidp->refCount = 1; + uidp->refCount = 2; /* one for the vcp and one for the caller */ uidp->vcp = vcp; smb_HoldVCNoLock(vcp); vcp->usersp = uidp; @@ -1224,7 +1238,7 @@ void smb_ReleaseUID(smb_user_t *uidp) lock_ObtainWrite(&smb_rctLock); osi_assert(uidp->refCount-- > 0); - if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) { + if (uidp->refCount == 0) { lupp = &uidp->vcp->usersp; for(up = *lupp; up; lupp = &up->nextp, up = *lupp) { if (up == uidp) @@ -1250,21 +1264,22 @@ void smb_ReleaseUID(smb_user_t *uidp) cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp) { smb_user_t *uidp; - cm_user_t *up; + cm_user_t *up = NULL; smb_t *smbp; smbp = (smb_t *) inp; uidp = smb_FindUID(vcp, smbp->uid, 0); - if ((!uidp) || (!uidp->unp)) - return NULL; - + if (!uidp) + return NULL; + lock_ObtainMutex(&uidp->mx); - up = uidp->unp->userp; - cm_HoldUser(up); + if (uidp->unp) { + up = uidp->unp->userp; + cm_HoldUser(up); + } lock_ReleaseMutex(&uidp->mx); smb_ReleaseUID(uidp); - return up; } @@ -2427,6 +2442,20 @@ void smb_SendPacket(smb_vc_t *vcp, smb_packet_t *inp) if (code != 0) { const char * s = ncb_error_string(code); osi_Log2(smb_logp, "SendPacket failure code %d \"%s\"", code, s); +#ifndef DJGPP + LogEvent(EVENTLOG_WARNING_TYPE, MSG_SMB_SEND_PACKET_FAILURE, s); +#endif /* !DJGPP */ + + osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x", + vcp, vcp->usersp); + smb_HoldVC(vcp); + if (dead_vcp) { + osi_Log1(smb_logp,"Previous dead_vcp %x", dead_vcp); + smb_CleanupDeadVC(dead_vcp); + smb_ReleaseVC(dead_vcp); + } + dead_vcp = vcp; + vcp->flags |= SMB_VCFLAG_ALREADYDEAD; } if (localNCB) @@ -2981,19 +3010,20 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) ongoingOps - 1); if (!isGateway) { if (active_vcp) { - DWORD now = GetCurrentTime(); - if (now - last_msg_time >= 30000 - && now - last_msg_time <= 90000) { - osi_Log1(smb_logp, - "Setting dead_vcp %x", active_vcp); - if (dead_vcp) { + DWORD now = GetTickCount(); + if (now - last_msg_time >= 30000) { + smb_vc_t *avcp = active_vcp; + active_vcp = NULL; + osi_Log1(smb_logp,"Setting dead_vcp %x", avcp); + if (dead_vcp) { + osi_Log1(smb_logp,"Previous dead_vcp %x", dead_vcp); + smb_CleanupDeadVC(dead_vcp); smb_ReleaseVC(dead_vcp); - osi_Log1(smb_logp, - "Previous dead_vcp %x", dead_vcp); } - smb_HoldVC(active_vcp); - dead_vcp = active_vcp; + smb_HoldVC(avcp); + dead_vcp = avcp; dead_vcp->flags |= SMB_VCFLAG_ALREADYDEAD; + smb_ReleaseVC(avcp); } } } @@ -3985,7 +4015,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) { /* Don't bulk stat if risking timeout */ - int now = GetCurrentTime(); + int now = GetTickCount(); if (now - req.startTime > 5000) { scp->bulkStatProgress = thyper; scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; @@ -6909,7 +6939,7 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, /* Remember session generation number and time */ oldGen = sessionGen; - oldTime = GetCurrentTime(); + oldTime = GetTickCount(); while (inp->inCom != 0xff) { dp = &smb_dispatchTable[inp->inCom]; @@ -6967,7 +6997,7 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, } if (oldGen != sessionGen) { - newTime = GetCurrentTime(); + newTime = GetTickCount(); #ifndef DJGPP LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_WRONG_SESSION, newTime - oldTime, ncbp->ncb_length); @@ -7123,19 +7153,18 @@ void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { if (active_vcp != vcp) { if (active_vcp) { - smb_ReleaseVC(active_vcp); osi_Log2(smb_logp, "Replacing active_vcp %x with %x", active_vcp, vcp); + smb_ReleaseVC(active_vcp); } smb_HoldVC(vcp); active_vcp = vcp; } - last_msg_time = GetCurrentTime(); - } else if (active_vcp == vcp) { + last_msg_time = GetTickCount(); + } else if (active_vcp == vcp) { /* the vcp is dead */ smb_ReleaseVC(active_vcp); active_vcp = NULL; } - return; } @@ -7412,39 +7441,34 @@ void smb_Server(VOID *parmp) osi_Log2(smb_logp, "NCBRECV pending lsn %d session %d", ncbp->ncb_lsn, idx_session); continue; - case NRC_SCLOSED: case NRC_SNUMOUT: case NRC_SABORT: +#ifndef DJGPP + LogEvent(EVENTLOG_WARNING_TYPE, MSG_UNEXPECTED_SMB_SESSION_CLOSE, ncb_error_string(rc)); + /* fallthrough */ +#endif /* !DJGPP */ + case NRC_SCLOSED: /* Client closed session */ - dead_sessions[idx_session] = TRUE; + dead_sessions[idx_session] = TRUE; if (vcp) smb_ReleaseVC(vcp); vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]); - /* Should also release vcp. [done] 2004-05-11 jaltman - * Also, should do - * sanity check that all TID's are gone. - * - * TODO: check if we could use LSNs[idx_session] instead, - * also cleanup after dead vcp - */ if (vcp) { - if (dead_vcp == vcp) + if (dead_vcp == vcp) osi_Log1(smb_logp, "dead_vcp already set, 0x%x", dead_vcp); else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) { osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x", vcp, vcp->usersp); - smb_HoldVC(vcp); + smb_HoldVC(vcp); if (dead_vcp) { + osi_Log1(smb_logp,"Previous dead_vcp %x", dead_vcp); + smb_CleanupDeadVC(dead_vcp); smb_ReleaseVC(dead_vcp); - osi_Log1(smb_logp, - "Previous dead_vcp %x", dead_vcp); } dead_vcp = vcp; vcp->flags |= SMB_VCFLAG_ALREADYDEAD; } - smb_CleanupDeadVC(vcp); - if (vcp->justLoggedOut) { loggedOut = 1; loggedOutTime = vcp->logoffTime; diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index 81fda64..fbfdda8 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -487,6 +487,8 @@ extern void CompensateForSmbClientLastWriteTimeBugs(afs_uint32 *dosTimep); extern smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana); +extern void smb_CleanupDeadVC(smb_vc_t *vcp); + extern void smb_ReleaseVC(smb_vc_t *vcp); extern void smb_ReleaseVCNoLock(smb_vc_t *vcp); diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index afbcfc6..e60850a 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -49,7 +49,8 @@ cm_user_t *smb_GetTran2User(smb_vc_t *vcp, smb_tran2Packet_t *inp) cm_user_t *up = NULL; uidp = smb_FindUID(vcp, inp->uid, 0); - if (!uidp) return NULL; + if (!uidp) + return NULL; lock_ObtainMutex(&uidp->mx); if (uidp->unp) { @@ -931,7 +932,6 @@ long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou /* find the tree and free it */ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); - /* TODO: smb_ReleaseUID() ? */ if (uidp) { char *s1 = NULL, *s2 = NULL; @@ -949,6 +949,7 @@ long smb_ReceiveV3UserLogoffX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou * because the vcp points to it */ lock_ReleaseMutex(&uidp->mx); + smb_ReleaseUID(uidp); } else osi_Log0(smb_logp, "SMB3 user logoffX"); @@ -1126,7 +1127,8 @@ smb_tran2Packet_t *smb_GetTran2ResponsePacket(smb_vc_t *vcp, tp = malloc(sizeof(*tp)); memset(tp, 0, sizeof(*tp)); - tp->vcp = NULL; + smb_HoldVC(vcp); + tp->vcp = vcp; tp->curData = tp->curParms = 0; tp->totalData = totalData; tp->totalParms = totalParms; @@ -4075,7 +4077,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t if ((dsp->flags & SMB_DIRSEARCH_BULKST) && LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) { /* Don't bulk stat if risking timeout */ - int now = GetCurrentTime(); + int now = GetTickCount(); if (now - req.startTime > 5000) { scp->bulkStatProgress = thyper; scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING; @@ -6700,6 +6702,8 @@ long smb_ReceiveNTTranNotifyChange(smb_vc_t *vcp, smb_packet_t *inp, savedPacketp = smb_CopyPacket(inp); smb_HoldVC(vcp); + if (savedPacketp->vcp) + smb_ReleaseVC(savedPacketp->vcp); savedPacketp->vcp = vcp; lock_ObtainMutex(&smb_Dir_Watch_Lock); savedPacketp->nextp = smb_Directory_Watches; @@ -6857,7 +6861,6 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, BOOL twoEntries = FALSE; ULONG otherNameLen, oldParmCount = 0; DWORD otherAction; - smb_vc_t *vcp; smb_fid_t *fidp; /* Get ready for rename within directory */ @@ -6878,7 +6881,6 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, wtree = smb_GetSMBParm(watch, 22) & 0xffff; /* TODO: should this be 0xff ? */ maxLen = smb_GetSMBOffsetParm(watch, 5, 1) | (smb_GetSMBOffsetParm(watch, 6, 1) << 16); - vcp = watch->vcp; /* * Strange hack - bug in NT Client and NT Server that we @@ -6887,7 +6889,7 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, if (filter == 3 && wtree) filter = 0x17; - fidp = smb_FindFID(vcp, fid, 0); + fidp = smb_FindFID(watch->vcp, fid, 0); if (!fidp) { osi_Log1(smb_logp," no fidp for fid[%d]",fid); lastWatch = watch; @@ -7017,7 +7019,7 @@ void smb_NotifyChange(DWORD action, DWORD notifyFilter, ((smb_t *) watch)->flg2 |= SMB_FLAGS2_32BIT_STATUS; } - smb_SendPacket(vcp, watch); + smb_SendPacket(watch->vcp, watch); smb_FreePacket(watch); watch = nextWatch; } diff --git a/src/WINNT/afsd/smb_ioctl.c b/src/WINNT/afsd/smb_ioctl.c index cce6635..dba453c 100644 --- a/src/WINNT/afsd/smb_ioctl.c +++ b/src/WINNT/afsd/smb_ioctl.c @@ -281,7 +281,7 @@ done: /* called from V3 read to handle IOCTL descriptor reads */ long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) { - smb_ioctl_t *iop; + smb_ioctl_t *iop; long count; long code; long leftToCopy; @@ -292,168 +292,172 @@ long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_pack iop = fidp->ioctlp; count = smb_GetSMBParm(inp, 5); - userp = smb_GetUser(vcp, inp); - osi_assert(userp != 0); + userp = smb_GetUser(vcp, inp); + osi_assert(userp != 0); uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); iop->uidp = uidp; - if (uidp && uidp->unp) + if (uidp && uidp->unp) { osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s", uidp->userID, userp, osi_LogSaveString(afsd_logp, uidp->unp->name)); - else { + } else { if (uidp) - osi_Log2(afsd_logp, "Ioctl uid %d user %x no name", - uidp->userID, userp); + osi_Log2(afsd_logp, "Ioctl uid %d user %x no name", + uidp->userID, userp); else - osi_Log1(afsd_logp, "Ioctl no uid user %x no name", - userp); + osi_Log1(afsd_logp, "Ioctl no uid user %x no name", + userp); } - code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp); - if(code) { - smb_ReleaseUID(uidp); + code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp); + if (code) { + if (uidp) + smb_ReleaseUID(uidp); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); return CM_ERROR_NOSUCHPATH; } - code = smb_IoctlPrepareRead(fidp, iop, userp); + code = smb_IoctlPrepareRead(fidp, iop, userp); if (uidp) { iop->uidp = 0; smb_ReleaseUID(uidp); } if (code) { - cm_ReleaseUser(userp); + cm_ReleaseUser(userp); smb_ReleaseFID(fidp); - return code; + return code; } - leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied); + leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied); if (count > leftToCopy) count = leftToCopy; - /* 0 and 1 are reserved for request chaining, were setup by our caller, - * and will be further filled in after we return. - */ - smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */ - smb_SetSMBParm(outp, 3, 0); /* resvd */ - smb_SetSMBParm(outp, 4, 0); /* resvd */ - smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ - /* fill in #6 when we have all the parameters' space reserved */ - smb_SetSMBParm(outp, 7, 0); /* resv'd */ - smb_SetSMBParm(outp, 8, 0); /* resv'd */ - smb_SetSMBParm(outp, 9, 0); /* resv'd */ - smb_SetSMBParm(outp, 10, 0); /* resv'd */ - smb_SetSMBParm(outp, 11, 0); /* reserved */ - - /* get op ptr after putting in the last parm, since otherwise we don't - * know where the data really is. - */ - op = smb_GetSMBData(outp, NULL); + /* 0 and 1 are reserved for request chaining, were setup by our caller, + * and will be further filled in after we return. + */ + smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */ + smb_SetSMBParm(outp, 3, 0); /* resvd */ + smb_SetSMBParm(outp, 4, 0); /* resvd */ + smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */ + /* fill in #6 when we have all the parameters' space reserved */ + smb_SetSMBParm(outp, 7, 0); /* resv'd */ + smb_SetSMBParm(outp, 8, 0); /* resv'd */ + smb_SetSMBParm(outp, 9, 0); /* resv'd */ + smb_SetSMBParm(outp, 10, 0); /* resv'd */ + smb_SetSMBParm(outp, 11, 0); /* reserved */ + + /* get op ptr after putting in the last parm, since otherwise we don't + * know where the data really is. + */ + op = smb_GetSMBData(outp, NULL); - /* now fill in offset from start of SMB header to first data byte (to op) */ - smb_SetSMBParm(outp, 6, ((int) (op - outp->data))); + /* now fill in offset from start of SMB header to first data byte (to op) */ + smb_SetSMBParm(outp, 6, ((int) (op - outp->data))); - /* set the packet data length the count of the # of bytes */ - smb_SetSMBDataLength(outp, count); + /* set the packet data length the count of the # of bytes */ + smb_SetSMBDataLength(outp, count); - /* now copy the data into the response packet */ - memcpy(op, iop->outCopied + iop->outAllocp, count); + /* now copy the data into the response packet */ + memcpy(op, iop->outCopied + iop->outAllocp, count); - /* and adjust the counters */ - iop->outCopied += count; - - /* and cleanup things */ - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); + /* and adjust the counters */ + iop->outCopied += count; - return 0; -} + /* and cleanup things */ + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + + return 0; +} /* called from Read Raw to handle IOCTL descriptor reads */ long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, - smb_packet_t *outp + smb_packet_t *outp #ifdef DJGPP -, dos_ptr rawBuf + , dos_ptr rawBuf #endif /* DJGPP */ -) + ) { - smb_ioctl_t *iop; - long leftToCopy; - NCB *ncbp; - long code; - cm_user_t *userp; + smb_ioctl_t *iop; + long leftToCopy; + NCB *ncbp; + long code; + cm_user_t *userp; #ifdef DJGPP - dos_ptr dos_ncb; + dos_ptr dos_ncb; - if (rawBuf == 0) - { - osi_Log0(afsd_logp, "Failed to get raw buf for smb_IoctlReadRaw"); - return -1; - } + if (rawBuf == 0) + { + osi_Log0(afsd_logp, "Failed to get raw buf for smb_IoctlReadRaw"); + return -1; + } #endif /* DJGPP */ - iop = fidp->ioctlp; - - userp = smb_GetUser(vcp, inp); - - { - smb_user_t *uidp; - - uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); - if (uidp && uidp->unp) - osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s", - uidp->userID, userp, - osi_LogSaveString(afsd_logp, uidp->unp->name)); - else if (uidp) - osi_Log2(afsd_logp, "Ioctl uid %d user %x no name", - uidp->userID, userp); - else - osi_Log1(afsd_logp, "Ioctl no uid user %x no name", - userp); - if (uidp) smb_ReleaseUID(uidp); + iop = fidp->ioctlp; + + userp = smb_GetUser(vcp, inp); + + /* Log the user */ + { + smb_user_t *uidp; + + uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0); + if (uidp && uidp->unp) { + osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s", + uidp->userID, userp, + osi_LogSaveString(afsd_logp, uidp->unp->name)); + } else if (uidp) { + osi_Log2(afsd_logp, "Ioctl uid %d user %x no name", + uidp->userID, userp); + } else { + osi_Log1(afsd_logp, "Ioctl no uid user %x no name", + userp); } + if (uidp) + smb_ReleaseUID(uidp); + } code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp); - if(code) { + 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; - } + code = smb_IoctlPrepareRead(fidp, iop, userp); + if (code) { + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + return code; + } - leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied); + leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied); - ncbp = outp->ncbp; - memset((char *)ncbp, 0, sizeof(NCB)); + ncbp = outp->ncbp; + memset((char *)ncbp, 0, sizeof(NCB)); - ncbp->ncb_length = (unsigned short) leftToCopy; - ncbp->ncb_lsn = (unsigned char) vcp->lsn; - ncbp->ncb_command = NCBSEND; + ncbp->ncb_length = (unsigned short) leftToCopy; + ncbp->ncb_lsn = (unsigned char) vcp->lsn; + ncbp->ncb_command = NCBSEND; /*ncbp->ncb_lana_num = smb_LANadapter;*/ - ncbp->ncb_lana_num = vcp->lana; + ncbp->ncb_lana_num = vcp->lana; #ifndef DJGPP - ncbp->ncb_buffer = iop->outCopied + iop->outAllocp; - code = Netbios(ncbp); + ncbp->ncb_buffer = iop->outCopied + iop->outAllocp; + code = Netbios(ncbp); #else /* DJGPP */ - dosmemput(iop->outCopied + iop->outAllocp, ncbp->ncb_length, rawBuf); - ncbp->ncb_buffer = rawBuf; - dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; - code = Netbios(ncbp, dos_ncb); + dosmemput(iop->outCopied + iop->outAllocp, ncbp->ncb_length, rawBuf); + ncbp->ncb_buffer = rawBuf; + dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb; + code = Netbios(ncbp, dos_ncb); #endif /* !DJGPP */ - if (code != 0) - osi_Log1(afsd_logp, "ReadRaw send failure code %d", code); + if (code != 0) + osi_Log1(afsd_logp, "ReadRaw send failure code %d", code); - cm_ReleaseUser(userp); - smb_ReleaseFID(fidp); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); - return 0; + return 0; } -- 1.9.4