From 28a33f8492098c23f7c3c58763ace93b82ea80a7 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 29 Feb 2012 13:07:47 -0500 Subject: [PATCH] Windows: Workaround Win7 SMB Reconnect Bug 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 Reviewed-by: Jeffrey Altman --- src/WINNT/afsd/smb.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 8c8045a..28feb57 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -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 */ -- 1.9.4