LICENSE MIT
When processing SMB_SESSION_SETUP_ANDX in smb_ReceiveV3SessionSetupX
it is possible that the smb client might indicate that it requires an
Mpx Count greater than we are configured to support. If so, log it
to the Windows Event Log as a warning.
It is also possible that the client might specify that its maximum
receive buffer is smaller than the SMB_PACKETSIZE. If so, log it
to the Windows Event Log as a warning.
Finally, if the client specifies a virtual circuit number of zero,
the client thinks this is its first time communicating with us.
In which case we should invalidate all prior virtual circuits.
We also log this request to the Windows Event Log as informational.
(cherry picked from commit
4eb808d26b1d417189d363924c4e2e32ed832690)
CHAR lpStrings[MAXARGS][STRLEN];
WORD wNumArgs = 0;
WORD wNumStrings = 0;
- DWORD code;
+ DWORD code;
// Ensure that our event source is properly initialized.
if (!AddEventSource())
case MSG_SERVICE_ERROR_STOP:
case MSG_CRYPT_OFF:
case MSG_CRYPT_ON:
+ case MSG_SMB_RESET_ALL_VCS:
break;
case MSG_FLUSH_BAD_SHARE_NAME:
case MSG_FLUSH_OPEN_ENUM_ERROR:
break;
case MSG_TIME_FLUSH_PER_VOLUME:
case MSG_TIME_FLUSH_TOTAL:
+ case MSG_SMB_MAX_MPX_COUNT:
+ case MSG_SMB_MAX_BUFFER_SIZE:
wNumArgs = 2;
lpArgs[0] = va_arg(listArgs, LPTSTR);
lpArgs[1] = va_arg(listArgs, LPTSTR);
// Log the event.
code = ReportEvent(hEventSource, // handle of event source
- wEventType, // event type
- 0, // event category
- dwEventID, // event ID
- NULL, // current user's SID
- wNumArgs, // strings in lpszArgs
- 0, // no bytes of raw data
- wNumArgs ? lpArgs : NULL, // array of error strings
- NULL); // no raw data
+ wEventType, // event type
+ 0, // event category
+ dwEventID, // event ID
+ NULL, // current user's SID
+ wNumArgs, // strings in lpszArgs
+ 0, // no bytes of raw data
+ wNumArgs ? lpArgs : NULL,// array of error strings
+ NULL); // no raw data
DeregisterEventSource(hEventSource);
;// Do not edit the header file. It is autogenerated from
;// afsd_eventmessages.mc. If you edit afsd_eventmessages.mc
;// be sure to ensure the consistency of the data types in LogEvent()
-;//
+;// located in afsd_eventlog.c
;
;#ifndef __AFSD_EVENTMESSAGES_H_
;#define __AFSD_EVENTMESSAGES_H_ 1
Unexpected SMB Session Close: %1.
.
+MessageId=
+Severity=Warning
+Facility=System
+SymbolicName=MSG_SMB_MAX_MPX_COUNT
+Language=English
+MaxMpxCount for client is too large (Client=%1, Server=%2).
+.
+
+MessageId=
+Severity=Warning
+Facility=System
+SymbolicName=MSG_SMB_MAX_BUFFER_SIZE
+Language=English
+MaxBufferSize for client is too small (Client=%1, Server=%2).
+.
+
+MessageId=
+Severity=Informational
+Facility=System
+SymbolicName=MSG_SMB_RESET_ALL_VCS
+Language=English
+Windows SMB Redirector requests reset of all SMB virtual circuits.
+.
;#endif /* __AFSD_EVENTMESSAGES_H_ 1 */
*unixTimep = dosTime + smb_localZero;
}
+void smb_MarkAllVCsDead(smb_vc_t * exclude)
+{
+ smb_vc_t *vcp;
+ smb_vc_t **vcp_to_cleanup = NULL;
+ int n_to_cleanup = 0;
+ int i;
+
+ osi_Log1(smb_logp, "Marking all VCs as dead excluding %p", exclude);
+
+ lock_ObtainWrite(&smb_globalLock); /* for dead_sessions[] */
+ lock_ObtainWrite(&smb_rctLock);
+ for (vcp = smb_allVCsp; vcp; vcp = vcp->nextp) {
+
+ if (vcp->magic != SMB_VC_MAGIC)
+ osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
+ __FILE__, __LINE__);
+
+ if (vcp == exclude)
+ continue;
+
+ lock_ObtainMutex(&vcp->mx);
+ if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ lock_ReleaseMutex(&vcp->mx);
+ dead_sessions[vcp->session] = TRUE;
+ } else {
+ lock_ReleaseMutex(&vcp->mx);
+ }
+ n_to_cleanup ++;
+ }
+
+ vcp_to_cleanup = malloc(sizeof(vcp_to_cleanup[0]) * n_to_cleanup);
+ i = 0;
+ for (vcp = smb_allVCsp; vcp; vcp = vcp->nextp) {
+ if (vcp == exclude)
+ continue;
+
+ vcp_to_cleanup[i++] = vcp;
+ smb_HoldVCNoLock(vcp);
+ }
+
+ osi_assert(i == n_to_cleanup);
+
+ lock_ReleaseWrite(&smb_rctLock);
+ lock_ReleaseWrite(&smb_globalLock);
+
+ for (i=0; i < n_to_cleanup; i++) {
+ smb_CleanupDeadVC(vcp_to_cleanup[i]);
+ smb_ReleaseVC(vcp_to_cleanup[i]);
+ vcp_to_cleanup[i] = 0;
+ }
+
+ free(vcp_to_cleanup);
+}
+
#ifdef DEBUG_SMB_REFCOUNT
smb_vc_t *smb_FindVCDbg(unsigned short lsn, int flags, int lana, char *file, long line)
#else
osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
__FILE__, __LINE__);
+ lock_ObtainMutex(&vcp->mx);
if (lsn == vcp->lsn && lana == vcp->lana &&
!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ lock_ReleaseMutex(&vcp->mx);
smb_HoldVCNoLock(vcp);
break;
}
+ lock_ReleaseMutex(&vcp->mx);
}
if (!vcp && (flags & SMB_FLAG_CREATE)) {
vcp = malloc(sizeof(*vcp));
extern void smb_CleanupDeadVC(smb_vc_t *vcp);
+extern void smb_MarkAllVCsDead(smb_vc_t *exclude_vcp);
+
#ifdef DEBUG_SMB_REFCOUNT
extern smb_tid_t *smb_FindTIDDbg(smb_vc_t *vcp, unsigned short tid, int flags, char *, long);
#define smb_FindTID(a,b,c) smb_FindTIDDbg(a,b,c,__FILE__,__LINE__);
clientchar_t usern[SMB_MAX_USERNAME_LENGTH];
char *secBlobOut = NULL;
int secBlobOutLength = 0;
+ int maxBufferSize = 0;
+ int maxMpxCount = 0;
+ int vcNumber = 0;
/* Check for bad conns */
if (vcp->flags & SMB_VCFLAG_REMOTECONN)
return CM_ERROR_REMOTECONN;
+ /* maxBufferSize */
+ maxBufferSize = smb_GetSMBParm(inp, 2);
+ maxMpxCount = smb_GetSMBParm(inp, 3);
+ vcNumber = smb_GetSMBParm(inp, 4);
+
+ osi_Log3(smb_logp, "SESSION_SETUP_ANDX with MaxBufferSize=%d, MaxMpxCount=%d, VCNumber=%d",
+ maxBufferSize, maxMpxCount, vcNumber);
+
+ if (maxMpxCount > smb_maxMpxRequests) {
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SMB_MAX_MPX_COUNT, maxMpxCount, smb_maxMpxRequests);
+ osi_Log2(smb_logp, "MaxMpxCount for client is too large (Client=%d, Server=%d)",
+ maxMpxCount, smb_maxMpxRequests);
+ }
+
+ if (maxBufferSize < SMB_PACKETSIZE) {
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SMB_MAX_BUFFER_SIZE, maxBufferSize, SMB_PACKETSIZE);
+ osi_Log2(smb_logp, "MaxBufferSize for client is too small (Client=%d, Server=%d)",
+ maxBufferSize, SMB_PACKETSIZE);
+ }
+
+ if (vcNumber == 0) {
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SMB_RESET_ALL_VCS);
+ osi_Log0(smb_logp, "Resetting all VCs");
+ smb_MarkAllVCsDead(vcp);
+ }
+
if (vcp->flags & SMB_VCFLAG_USENT) {
if (smb_authType == SMB_AUTH_EXTENDED) {
/* extended authentication */