Windows: Workaround Win7 SMB Reconnect Bug
authorJeffrey Altman <jaltman@your-file-system.com>
Wed, 29 Feb 2012 18:07:47 +0000 (13:07 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 1 Mar 2012 02:04:18 +0000 (18:04 -0800)
The SMB specification permits the server to save a round trip
in the GSS negotiation by sending an initial security blob.
Unfortunately, doing so trips a bug in Windows 7 and Server 2008 R2
whereby the SMB 1.x redirector drops the blob on the floor after
the first connection to the server and simply attempts to reuse
the previous authentication context.  This bug can be avoided by
the server sending no security blob in the SMB_COM_NEGOTIATE
response.  This forces the client to send an initial GSS init_sec_context
blob under all circumstances which works around the bug in Microsoft's
code.

Do not call smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength);

As a result of the SMB 1.x bug, all attempts to reconnect fail due to
SMB connection resets.  The SMB 1.x redirector will retry indefinitely
but all processes with outstanding requests to \\AFS will block until
the machine is rebooted.

Change-Id: Iedd58fccbf85495d48871935f6e61ede1e1240ff
Reviewed-on: http://gerrit.openafs.org/6846
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsd/smb.c

index 8c8045a..28feb57 100644 (file)
@@ -773,7 +773,7 @@ smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana)
         vcp->lana = lana;
         vcp->secCtx = NULL;
 
-        if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) {
+        if (smb_authType == SMB_AUTH_NTLM) {
             /* We must obtain a challenge for extended auth
              * in case the client negotiates smb v3
              */
@@ -3990,22 +3990,36 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
                                   datap + MSV1_0_CHALLENGE_LENGTH,
                                   (int)(sizeof(outp->data)/sizeof(char) - (datap - outp->data)));
         } else if ( smb_authType == SMB_AUTH_EXTENDED ) {
-            void * secBlob;
-            int secBlobLength;
+            void * secBlob = NULL;
+            int secBlobLength = 0;
 
             smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */
 
-            smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength);
+            /*
+             * The SMB specification permits the server to save a round trip
+             * in the GSS negotiation by sending an initial security blob.
+             * Unfortunately, doing so trips a bug in Windows 7 and Server 2008 R2
+             * whereby the SMB 1.x redirector drops the blob on the floor after
+             * the first connection to the server and simply attempts to reuse
+             * the previous authentication context.  This bug can be avoided by
+             * the server sending no security blob in the SMB_COM_NEGOTIATE
+             * response.  This forces the client to send an initial GSS init_sec_context
+             * blob under all circumstances which works around the bug in Microsoft's
+             * code.
+             *
+             * Do not call smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength);
+             */
 
             smb_SetSMBDataLength(outp, secBlobLength + sizeof(smb_ServerGUID));
-
             datap = smb_GetSMBData(outp, NULL);
+
             memcpy(datap, &smb_ServerGUID, sizeof(smb_ServerGUID));
+            datap += sizeof(smb_ServerGUID);
 
             if (secBlob) {
-                datap += sizeof(smb_ServerGUID);
                 memcpy(datap, secBlob, secBlobLength);
                 free(secBlob);
+                datap += sizeof(secBlobLength);
             }
         } else {
             smb_SetSMBParmByte(outp, 16, 0);/* Challenge length */