]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
DEVEL15-smb-vc-reset-on-request-20090218
authorAsanka Herath <asanka@secure-endpoints.com>
Thu, 19 Feb 2009 04:04:36 +0000 (04:04 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 19 Feb 2009 04:04:36 +0000 (04:04 +0000)
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)

src/WINNT/afsd/afsd_eventlog.c
src/WINNT/afsd/afsd_eventmessages.mc
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb.h
src/WINNT/afsd/smb3.c

index 192d8d574be0fcb338dbc40f176d5a93c37a5ad3..a6ed02cb26e75c4c90ff7469a298a37f5dd24103 100644 (file)
@@ -167,7 +167,7 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...)
     CHAR       lpStrings[MAXARGS][STRLEN];
     WORD       wNumArgs = 0;
     WORD       wNumStrings = 0;
-       DWORD   code;
+    DWORD       code;
 
     // Ensure that our event source is properly initialized.
     if (!AddEventSource())
@@ -195,6 +195,7 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...)
     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:
@@ -209,6 +210,8 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...)
        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);
@@ -296,14 +299,14 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...)
 
     // 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);
index f01059d0dc4b4e6aea0ac867478b9b0cc58917a3..5c0f27ff0e69bf259094fa98acf4a905724643f3 100644 (file)
@@ -7,7 +7,7 @@
 ;// 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
@@ -358,5 +358,28 @@ Language=English
 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 */
index ace8c36adda2faacac8065e70e3ad5cd8bcd2fd5..59ba7b8b0bff6eccaadcb9cea6566dc92ce580c2 100644 (file)
@@ -819,6 +819,61 @@ void smb_UnixTimeFromDosUTime(time_t *unixTimep, afs_uint32 dosTime)
     *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
@@ -834,11 +889,14 @@ smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana)
            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));
index 31f5212b40a10d332cbb72776b6576c820eeb92f..111769e8abdbd8324a31114a725ac64415b12998 100644 (file)
@@ -543,6 +543,8 @@ extern void smb_ReleaseVCNoLock(smb_vc_t *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__);
index b2c615ffef7f1d5d26c1f429aa3db3bb86087e1e..dadaa910d895df01fa9abf9357eb5c29700acbdd 100644 (file)
@@ -686,11 +686,40 @@ long smb_ReceiveV3SessionSetupX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *
     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 */