From: Jeffrey Altman Date: Wed, 29 Feb 2012 18:07:47 +0000 (-0500) Subject: Windows: Workaround Win7 SMB Reconnect Bug X-Git-Tag: upstream/1.6.1.pre4^2~5 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=2c4618adc47fa1336a4636bd328c0dad0194c9d2;p=packages%2Fo%2Fopenafs.git 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. Reviewed-on: http://gerrit.openafs.org/6846 Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman (cherry picked from commit 28a33f8492098c23f7c3c58763ace93b82ea80a7) Change-Id: I424b8a8f76c3ee5a70e0886a169c4a7175ff5e47 Reviewed-on: http://gerrit.openafs.org/6849 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index dd2c9074a..8c6502385 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -770,7 +770,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 */ @@ -3976,22 +3976,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 */