/* Faux server GUID. This is never checked. */
GUID smb_ServerGUID = { 0x40015cb8, 0x058a, 0x44fc, { 0xae, 0x7e, 0xbb, 0x29, 0x52, 0xee, 0x7e, 0xff }};
+const char * ncb_error_string(int code)
+{
+ const char * s;
+ switch ( code ) {
+ case 0x01: s = "llegal buffer length"; break;
+ case 0x03: s = "illegal command"; break;
+ case 0x05: s = "command timed out"; break;
+ case 0x06: s = "message incomplete, issue another command"; break;
+ case 0x07: s = "illegal buffer address"; break;
+ case 0x08: s = "session number out of range"; break;
+ case 0x09: s = "no resource available"; break;
+ case 0x0a: s = "session closed"; break;
+ case 0x0b: s = "command cancelled"; break;
+ case 0x0d: s = "duplicate name"; break;
+ case 0x0e: s = "name table full"; break;
+ case 0x0f: s = "no deletions, name has active sessions"; break;
+ case 0x11: s = "local session table full"; break;
+ case 0x12: s = "remote session table full"; break;
+ case 0x13: s = "illegal name number"; break;
+ case 0x14: s = "no callname"; break;
+ case 0x15: s = "cannot put * in NCB_NAME"; break;
+ case 0x16: s = "name in use on remote adapter"; break;
+ case 0x17: s = "name deleted"; break;
+ case 0x18: s = "session ended abnormally"; break;
+ case 0x19: s = "name conflict detected"; break;
+ case 0x21: s = "interface busy, IRET before retrying"; break;
+ case 0x22: s = "too many commands outstanding, retry later";break;
+ case 0x23: s = "ncb_lana_num field invalid"; break;
+ case 0x24: s = "command completed while cancel occurring "; break;
+ case 0x26: s = "command not valid to cancel"; break;
+ case 0x30: s = "name defined by anther local process"; break;
+ case 0x34: s = "environment undefined. RESET required"; break;
+ case 0x35: s = "required OS resources exhausted"; break;
+ case 0x36: s = "max number of applications exceeded"; break;
+ case 0x37: s = "no saps available for netbios"; break;
+ case 0x38: s = "requested resources are not available"; break;
+ case 0x39: s = "invalid ncb address or length > segment"; break;
+ case 0x3B: s = "invalid NCB DDID"; break;
+ case 0x3C: s = "lock of user area failed"; break;
+ case 0x3f: s = "NETBIOS not loaded"; break;
+ case 0x40: s = "system error"; break;
+ default: s = "unknown error";
+ }
+ return s;
+}
+
+
char * myCrt_Dispatch(int i)
{
switch (i)
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");
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);
}
lock_ReleaseWrite(&smb_rctLock);
}
+void smb_CleanupDeadVC(smb_vc_t *vcp)
+{
+ smb_fid_t *fidpIter;
+ smb_fid_t *fidpNext;
+ smb_fid_t *fidp;
+ unsigned short fid;
+ smb_tid_t *tidpIter;
+ smb_tid_t *tidpNext;
+ smb_tid_t *tidp;
+ unsigned short tid;
+ smb_user_t *userpIter;
+ 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);
+
+ lock_ObtainRead(&smb_rctLock);
+ for (fidpIter = vcp->fidsp; fidpIter; fidpIter = fidpNext) {
+ fidpNext = (smb_fid_t *) osi_QNext(&fidpIter->q);
+
+ if (fidpIter->flags & SMB_FID_DELETE)
+ continue;
+
+ fid = fidpIter->fid;
+ osi_Log2(smb_logp, " Cleanup FID %d (fidp=0x%x)", fid, fidpIter);
+ lock_ReleaseRead(&smb_rctLock);
+
+ fidp = smb_FindFID(vcp, fid, 0);
+ osi_assert(fidp);
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+
+ lock_ObtainRead(&smb_rctLock);
+ }
+
+ for (tidpIter = vcp->tidsp; tidpIter; tidpIter = tidpNext) {
+ tidpNext = tidpIter->nextp;
+
+ if (tidpIter->flags & SMB_TIDFLAG_DELETE)
+ continue;
+
+ tid = tidpIter->tid;
+ osi_Log2(smb_logp, " Cleanup TID %d (tidp=0x%x)", tid, tidpIter);
+ lock_ReleaseRead(&smb_rctLock);
+
+ tidp = smb_FindTID(vcp, tid, 0);
+ osi_assert(tidp);
+
+ lock_ObtainMutex(&tidp->mx);
+ tidp->flags |= SMB_TIDFLAG_DELETE;
+ lock_ReleaseMutex(&tidp->mx);
+
+ smb_ReleaseTID(tidp);
+
+ lock_ObtainRead(&smb_rctLock);
+ }
+
+ for (userpIter = vcp->usersp; userpIter; userpIter = userpNext) {
+ userpNext = userpIter->nextp;
+
+ if (userpIter->flags & SMB_USERFLAG_DELETE)
+ continue;
+
+ uid = userpIter->userID;
+ osi_Log2(smb_logp, " Cleanup UID %d (userp=0x%x)", uid, userpIter);
+ lock_ReleaseRead(&smb_rctLock);
+
+ userp = smb_FindUID(vcp, uid, 0);
+ osi_assert(userp);
+
+ lock_ObtainMutex(&userp->mx);
+ userp->flags |= SMB_USERFLAG_DELETE;
+ lock_ReleaseMutex(&userp->mx);
+
+ smb_ReleaseUID(userp);
+
+ 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");
+}
+
smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags)
{
smb_tid_t *tidp;
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;
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)) {
+ if (uidp->refCount == 0) {
lupp = &uidp->vcp->usersp;
for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
if (up == 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.
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;
}
if (fid == fidp->fid) {
if (newFid) {
fid++;
- if (fid == 0)
+ if (fid == 0) {
+ osi_Log1(smb_logp,
+ "New FID number wraps on vcp 0x%x", vcp);
fid = 1;
+ }
goto retry;
}
fidp->refCount++;
osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
thrd_CloseHandle(event);
fid++;
- if (fid == 0)
+ if (fid == 0) {
+ osi_Log1(smb_logp, "New FID wraps around for vcp 0x%x", vcp);
fid = 1;
+ }
goto retry;
}
fidp->raw_write_event = event;
if (newFid) {
vcp->fidCounter = fid+1;
- if (vcp->fidCounter == 0)
+ if (vcp->fidCounter == 0) {
+ osi_Log1(smb_logp, "fidCounter wrapped around for vcp 0x%x",
+ vcp);
vcp->fidCounter = 1;
}
}
+ }
lock_ReleaseWrite(&smb_rctLock);
return fidp;
void smb_ReleaseFID(smb_fid_t *fidp)
{
cm_scache_t *scp;
+ cm_user_t *userp;
smb_vc_t *vcp = NULL;
smb_ioctl_t *ioctlp;
return;
scp = NULL;
+ userp = NULL;
lock_ObtainWrite(&smb_rctLock);
osi_assert(fidp->refCount-- > 0);
if (fidp->refCount == 0 && (fidp->flags & SMB_FID_DELETE)) {
vcp = fidp->vcp;
- fidp->vcp = 0;
+ fidp->vcp = NULL;
scp = fidp->scp; /* release after lock is released */
- fidp->scp = 0;
+ fidp->scp = NULL;
+ userp = fidp->userp;
+ fidp->userp = NULL;
osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q);
thrd_CloseHandle(fidp->raw_write_event);
/* now release the scache structure */
if (scp)
cm_ReleaseSCache(scp);
+
+ if (userp)
+ cm_ReleaseUser(userp);
}
/*
#endif /* !DJGPP */
if (code != 0) {
- char * s;
- switch ( code ) {
- case 0x01: s = "llegal buffer length "; break;
- case 0x03: s = "illegal command "; break;
- case 0x05: s = "command timed out "; break;
- case 0x06: s = "message incomplete, issue another command"; break;
- case 0x07: s = "illegal buffer address "; break;
- case 0x08: s = "session number out of range "; break;
- case 0x09: s = "no resource available "; break;
- case 0x0a: s = "session closed "; break;
- case 0x0b: s = "command cancelled "; break;
- case 0x0d: s = "duplicate name "; break;
- case 0x0e: s = "name table full "; break;
- case 0x0f: s = "no deletions, name has active sessions "; break;
- case 0x11: s = "local session table full "; break;
- case 0x12: s = "remote session table full "; break;
- case 0x13: s = "illegal name number "; break;
- case 0x14: s = "no callname "; break;
- case 0x15: s = "cannot put * in NCB_NAME "; break;
- case 0x16: s = "name in use on remote adapter "; break;
- case 0x17: s = "name deleted "; break;
- case 0x18: s = "session ended abnormally "; break;
- case 0x19: s = "name conflict detected "; break;
- case 0x21: s = "interface busy, IRET before retrying "; break;
- case 0x22: s = "too many commands outstanding, retry later"; break;
- case 0x23: s = "ncb_lana_num field invalid "; break;
- case 0x24: s = "command completed while cancel occurring "; break;
- case 0x26: s = "command not valid to cancel "; break;
- case 0x30: s = "name defined by anther local process "; break;
- case 0x34: s = "environment undefined. RESET required "; break;
- case 0x35: s = "required OS resources exhausted "; break;
- case 0x36: s = "max number of applications exceeded "; break;
- case 0x37: s = "no saps available for netbios "; break;
- case 0x38: s = "requested resources are not available "; break;
- case 0x39: s = "invalid ncb address or length > segment "; break;
- case 0x3B: s = "invalid NCB DDID "; break;
- case 0x3C: s = "lock of user area failed "; break;
- case 0x3f: s = "NETBIOS not loaded "; break;
- case 0x40: s = "system error "; break;
- default:
- s = "unknown error";
- }
+ 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)
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);
}
}
}
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;
/* save a pointer to the vnode */
fidp->scp = scp;
+ /* and the user */
+ cm_HoldUser(userp);
+ fidp->userp = userp;
if ((share & 0xf) == 0)
fidp->flags |= SMB_FID_OPENREAD;
*newPathp = strdup(pathp);
}
-long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
-{
- unsigned short fid;
- smb_fid_t *fidp;
- cm_user_t *userp;
- afs_uint32 dosTime;
+long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
+ afs_uint32 dosTime) {
long code = 0;
cm_req_t req;
- cm_InitReq(&req);
-
- fid = smb_GetSMBParm(inp, 0);
- dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16);
+ osi_Log3(smb_logp, "smb_CloseFID Closing fidp 0x%x (fid=%d vcp=0x%x)",
+ fidp, fidp->fid, vcp);
- osi_Log1(smb_logp, "SMB close fid %d", fid);
-
- fid = smb_ChainFID(fid, inp);
- fidp = smb_FindFID(vcp, fid, 0);
- if (!fidp) {
+ if (!userp) {
+ if (!fidp->userp) {
+ osi_Log0(smb_logp, " No user specified. Not closing fid");
return CM_ERROR_BADFD;
}
- userp = smb_GetUser(vcp, inp);
+ userp = fidp->userp; /* no hold required since fidp is held
+ throughout the function */
+ }
+
+ cm_InitReq(&req);
lock_ObtainMutex(&fidp->mx);
if (!(fidp->flags & SMB_FID_IOCTL) && fidp->scp &&
fidp->scp->fileType == CM_SCACHETYPE_FILE) {
cm_key_t key;
- unsigned pid;
cm_scache_t * scp;
long tcode;
- pid = ((smb_t *) inp)->pid;
- key = cm_GenerateKey(vcp->vcID, pid, fid);
+ /* CM_UNLOCK_BY_FID doesn't look at the process ID. We pass
+ in zero. */
+ key = cm_GenerateKey(vcp->vcID, 0, fidp->fid);
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ObtainMutex(&scp->mx);
| CM_SCACHESYNC_LOCK);
if (tcode) {
- osi_Log1(smb_logp, "smb CoreClose SyncOp failure code 0x%x", tcode);
+ osi_Log1(smb_logp,
+ "smb CoreClose SyncOp failure code 0x%x", tcode);
goto post_syncopdone;
}
smb_NotifyChange(FILE_ACTION_REMOVED,
FILE_NOTIFY_CHANGE_DIR_NAME,
dscp, fullPathp, NULL, TRUE);
- }
- else
- {
+ } else {
code = cm_Unlink(dscp, fullPathp, userp, &req);
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
smb_NotifyChange(FILE_ACTION_REMOVED,
if (fidp->flags & SMB_FID_NTOPEN) {
cm_ReleaseSCache(fidp->NTopen_dscp);
free(fidp->NTopen_pathp);
+ fidp->NTopen_pathp = NULL;
}
- if (fidp->NTopen_wholepathp)
+ if (fidp->NTopen_wholepathp) {
free(fidp->NTopen_wholepathp);
+ fidp->NTopen_wholepathp = NULL;
+ }
+
+ return code;
+}
+
+long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+{
+ unsigned short fid;
+ smb_fid_t *fidp;
+ cm_user_t *userp;
+ long code = 0;
+ afs_uint32 dosTime;
+
+ fid = smb_GetSMBParm(inp, 0);
+ dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16);
+
+ osi_Log1(smb_logp, "SMB ReceiveCoreClose fid %d", fid);
+
+ fid = smb_ChainFID(fid, inp);
+ fidp = smb_FindFID(vcp, fid, 0);
+ if (!fidp) {
+ return CM_ERROR_BADFD;
+ }
+
+ userp = smb_GetUser(vcp, inp);
+
+ code = smb_CloseFID(vcp, fidp, userp, dosTime);
smb_ReleaseFID(fidp);
cm_ReleaseUser(userp);
/* 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;
}
/* 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);
/* Remember session generation number and time */
oldGen = sessionGen;
- oldTime = GetCurrentTime();
+ oldTime = GetTickCount();
while (inp->inCom != 0xff) {
dp = &smb_dispatchTable[inp->inCom];
}
if (oldGen != sessionGen) {
- newTime = GetCurrentTime();
+ newTime = GetTickCount();
#ifndef DJGPP
LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_WRONG_SESSION,
newTime - oldTime, ncbp->ncb_length);
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;
}
idx_session = NCBsessions[idx_NCB];
rc = ncbp->ncb_retcode;
- if (rc != NRC_PENDING && rc != NRC_GOODRET) {
- switch (rc) {
- case 0x01:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal buffer length", ncbp->ncb_lsn, idx_session);
- break;
- case 0x03:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal command", ncbp->ncb_lsn, idx_session);
- break;
- case 0x05:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command timed out", ncbp->ncb_lsn, idx_session);
- break;
- case 0x06:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: message incomplete, issue another command", ncbp->ncb_lsn, idx_session);
- break;
- case 0x07:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal buffer address", ncbp->ncb_lsn, idx_session);
- break;
- case 0x08:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session number out of range", ncbp->ncb_lsn, idx_session);
- break;
- case 0x09:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no resource available", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0a:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session closed", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0b:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command cancelled", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0d:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: duplicate name", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0e:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name table full", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0f:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no deletions, name has active lsn %d sessions", ncbp->ncb_lsn, idx_session);
- break;
- case 0x11:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: local session table full", ncbp->ncb_lsn, idx_session);
- break;
- case 0x12:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: remote session table full", ncbp->ncb_lsn, idx_session);
- break;
- case 0x13:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal name number", ncbp->ncb_lsn, idx_session);
- break;
- case 0x14:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no callname", ncbp->ncb_lsn, idx_session);
- break;
- case 0x15:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: cannot put * in NCB_NAME", ncbp->ncb_lsn, idx_session);
- break;
- case 0x16:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name in use on remote adapter", ncbp->ncb_lsn, idx_session);
- break;
- case 0x17:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name deleted", ncbp->ncb_lsn, idx_session);
- break;
- case 0x18:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session ended abnormally", ncbp->ncb_lsn, idx_session);
- break;
- case 0x19:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name conflict detected", ncbp->ncb_lsn, idx_session);
- break;
- case 0x21:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: interface busy, IRET before retrying", ncbp->ncb_lsn, idx_session);
- break;
- case 0x22:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: too many commands outstanding, retry later", ncbp->ncb_lsn, idx_session);
- break;
- case 0x23:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: ncb_lana_num field invalid", ncbp->ncb_lsn, idx_session);
- break;
- case 0x24:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command completed while cancel occurring", ncbp->ncb_lsn, idx_session);
- break;
- case 0x26:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command not valid to cancel", ncbp->ncb_lsn, idx_session);
- break;
- case 0x30:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name defined by anther local process", ncbp->ncb_lsn, idx_session);
- break;
- case 0x34:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: environment undefined. RESET required", ncbp->ncb_lsn, idx_session);
- break;
- case 0x35:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: required OS resources exhausted", ncbp->ncb_lsn, idx_session);
- break;
- case 0x36:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: max number of applications exceeded", ncbp->ncb_lsn, idx_session);
- break;
- case 0x37:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no saps available for netbios", ncbp->ncb_lsn, idx_session);
- break;
- case 0x38:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: requested resources are not available", ncbp->ncb_lsn, idx_session);
- break;
- case 0x39:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: invalid ncb address or length > segment", ncbp->ncb_lsn, idx_session);
- break;
- case 0x3B:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: invalid NCB DDID", ncbp->ncb_lsn, idx_session);
- break;
- case 0x3C:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lock of user area failed", ncbp->ncb_lsn, idx_session);
- break;
- case 0x3f:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: NETBIOS not loaded", ncbp->ncb_lsn, idx_session);
- break;
- case 0x40:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: system error", ncbp->ncb_lsn, idx_session);
- break;
- default:
- osi_Log3(smb_logp, "NCBRECV failure lsn %d session %d code %d", ncbp->ncb_lsn, idx_session, rc);
- break;
- }
- }
+ if (rc != NRC_PENDING && rc != NRC_GOODRET)
+ osi_Log3(smb_logp, "NCBRECV failure lsn %d session %d: %s", ncbp->ncb_lsn, idx_session, ncb_error_string(rc));
switch (rc) {
case NRC_GOODRET:
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;
}
+
if (vcp->justLoggedOut) {
loggedOut = 1;
loggedOutTime = vcp->logoffTime;