3.2.5.3.1 Handling a New Authentication

If the Status field in the SMB2 header of the response is not STATUS_SUCCESS and is not STATUS_MORE_PROCESSING_REQUIRED, the client MUST return the error code to the calling application that initiated the authentication request and processing is complete.

Otherwise, the client MUST process the GSS token received in the SMB2 SESSION_SETUP Response following the SMB2 header, described by SecurityBufferOffset and SecurityBufferLength. The client MUST use the configured GSS authentication protocol as specified in [MS-SPNG] section 3.3.5 and [RFC4178] section 3.2 to obtain the next GSS output token for the authentication exchange. Based on the result from the GSS authentication protocol, one of the following actions will be taken:

If the GSS protocol indicates an error, the error MUST be returned to the calling application that initiated the authentication request and processing is complete.

If the GSS protocol returns success, and the Status code of the SMB2 header of the response was STATUS_SUCCESS, authentication is complete. The client MUST process the message as follows:

If Connection.Dialect is "3.1.1", and if SMB2_FLAGS_SIGNED is not set in the Flags field of the SMB2 packet header of the response, the client MUST return an error to the calling application.

If Connection.Dialect is "3.1.1", the client MUST look for a session object in the Connection.PreAuthSessionTable by using the SessionId in the SMB2 header of the SMB2 SESSION_SETUP Response. If a session object is located, the client MUST remove it from Connection.PreAuthSessionTable and place it in the Connection.SessionTable. Otherwise, the client MUST allocate a session object and place it in the Connection.SessionTable.

If Connection.Dialect is "2.0.2", "2.1", "3.0", or "3.0.2", the client MUST allocate a session object and place it in the Connection.SessionTable.

The Session object MUST be initialized as follows:

  • Session.SessionId MUST be set to the SessionId in the SMB2 header of the response.

  • Session.TreeConnectTable MUST be set to an empty table.

  • Session.UserCredentials MUST be set to the OS-specific entity that identifies the credentials that were used to authenticate to the server.

  • Session.SessionKey MUST be set to the first 16 bytes of the cryptographic key queried from the GSS protocol for this authenticated context. If the cryptographic key is less than 16 bytes, it is right-padded with zero bytes. If Connection.Dialect is “3.1.1” and Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey MUST be set to the cryptographic key as queried from the GSS protocol for this authenticated context. For information about how this is calculated for Kerberos authentication using Generic Security Service Application Programming Interface (GSS-API), see [MS-KILE] section 3.1.1.2. For information about how this is calculated for NTLM authentication using GSS-API, see [MS-NLMP] section 3.1.5.1.

  • If Connection.Dialect is "3.1.1", the client MUST compute its preauthentication integrity hash value as follows:

    • Set Session.PreauthIntegrityHashValue to Connection.PreauthIntegrityHashValue.

    • The client MUST generate a hash using the Connection.PreauthIntegrityHashId algorithm on the string constructed by concatenating the Session.PreauthIntegrityHashValue and the session setup request message retrieved from the Connection.OutstandingRequests. The client MUST set Session.PreauthIntegrityHashValue to the hash value generated above.

  • If Connection.Dialect belongs to the SMB 3.x dialect family, the client MUST generate Session.SigningKey, as specified in section 3.1.4.2, and pass the following inputs:

    • Session.SessionKey as the key derivation key.

    • If Connection.Dialect is "3.1.1", the case-sensitive ASCII string "SMBSigningKey" as the label; otherwise, the case-sensitive ASCII string "SMB2AESCMAC" as the label.

    • The label buffer size in bytes, including the terminating null character. The size of "SMBSigningKey" is 14. The size of "SMB2AESCMAC" is 12.

    •  If Connection.Dialect is "3.1.1", Session.PreauthIntegrityHashValue as the context; otherwise, the case-sensitive ASCII string "SmbSign" as context for the algorithm.

    • The context buffer size in bytes. If Connection.Dialect is "3.1.1", the size of Session.PreauthIntegrityHashValue. Otherwise, the size of "SmbSign", including the terminating null character, is 8.

  • If Connection.Dialect belongs to the SMB 3.x dialect family, the client MUST allocate a new channel entry with the following values and insert it in Session.ChannelList:

    • Channel.SigningKey is set to Session.SigningKey.

    • Channel.Connection is set to the connection on which this response is received.

  • If Connection.Dialect belongs to the SMB 3.x dialect family, Session.ApplicationKey MUST be generated as specified in section 3.1.4.2, and pass the following inputs:

    • Session.SessionKey as the key derivation key.

    • If Connection.Dialect is "3.1.1", the case-sensitive ASCII string "SMBAppKey" as the label; otherwise, the case-sensitive ASCII string "SMB2APP" as the label.

    • The label buffer size in bytes, including the terminating null character. The size of "SMBAppKey" is 10. The size of "SMB2APP" is 8.

    • If Connection.Dialect is "3.1.1", Session.PreauthIntegrityHashValue as the context; otherwise, the case-sensitive ASCII string "SmbRpc" as context for the algorithm.

    • The context buffer size in bytes. If Connection.Dialect is "3.1.1", the size of Session.PreauthIntegrityHashValue. Otherwise, the size of "SmbRpc", including the terminating null character, is 7.

  • Session.Connection MUST be set to the connection on which this authentication attempt was issued.

  • If the global setting RequireMessageSigning is set to TRUE or Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE, otherwise Session.SigningRequired MUST be set to FALSE.

  • If the security subsystem indicates that the session was established by an anonymous user, Session.SigningRequired MUST be set to FALSE and Session.IsAnonymous MUST be set to TRUE.

  • If the security subsystem indicates that the session was established by a guest user, Session.SigningRequired MUST be set to FALSE and Session.IsGuest MUST be set to TRUE.

  • If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags field of the SMB2 SESSION_SETUP Response and if Session.SigningRequired is TRUE, this indicates a SESSION_SETUP failure and the connection MUST be terminated. If the SMB2_SESSION_FLAG_IS_GUEST bit is set in the SessionFlags field of the SMB2 SESSION_SETUP Response and if RequireMessageSigning is FALSE, Session.SigningRequired MUST be set to FALSE.

  • If Connection.Dialect belongs to the SMB 3.x dialect family and if the SMB2_SESSION_FLAG_ENCRYPT_DATA bit is set in the SessionFlags field of the SMB2 SESSION_SETUP Response, Session.EncryptData MUST be set to TRUE, and Session.SigningRequired MUST be set to FALSE.

  • If Connection.Dialect belongs to the SMB 3.x dialect family, the SMB2_SESSION_FLAG_IS_GUEST and SMB2_SESSION_FLAG_IS_NULL flags are not set in the SessionFlags field of the SMB2 SESSION_SETUP response, and if Connection.SupportsEncryption is TRUE, the client MUST do the following:

    • Generate Session.EncryptionKey, as specified in section 3.1.4.2, and pass the following inputs:

      • If Connection.Dialect is “3.1.1” and Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey as the key derivation key. Otherwise, Session.SessionKey as the key derivation key.

      • If Connection.Dialect is "3.1.1", the case-sensitive ASCII string "SMBC2SCipherKey" as the label; otherwise, the case-sensitive ASCII string "SMB2AESCCM" as the label.

      • The label buffer length in bytes, including the terminating null character. The size of "SMBC2SCipherKey" is 16. The size of "SMB2AESCCM" is 11.

      • If Connection.Dialect is "3.1.1", Session.PreauthIntegrityHashValue as the context; otherwise, the case-sensitive ASCII string "ServerIn " as context for the algorithm (note the blank space at the end).

      • The context buffer size in bytes. If Connection.Dialect is "3.1.1", the size of Session.PreauthIntegrityHashValue. Otherwise, the size of "ServerIn ", including the terminating null character, is 10.

    • Generate Session.DecryptionKey, as specified in section 3.1.4.2, and pass the following inputs:

      • If Connection.Dialect is “3.1.1” and Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey as the key derivation key. Otherwise, Session.SessionKey as the key derivation key.

      • If Connection.Dialect is "3.1.1", the case-sensitive ASCII string "SMBS2CCipherKey" as the label; otherwise, the case-sensitive ASCII string "SMB2AESCCM" as the label.

      • The label buffer length in bytes, including the terminating null character. The size of "SMBS2CCipherKey" is 16. The size of "SMB2AESCCM" is 11.

      • If Connection.Dialect is "3.1.1", Session.PreauthIntegrityHashValue as the context; otherwise, the case-sensitive ASCII string "ServerOut" as context for the algorithm.

      • The context buffer size in bytes. If Connection.Dialect is "3.1.1", the size of Session.PreauthIntegrityHashValue. Otherwise, the size of "ServerOut", including the terminating null character, is 10.

  • Session.OpenTable MUST be set to an empty table.

The client MUST generate a handle for the Session, and return the handle to the application that initiated the authentication request, and processing is complete.

If the GSS protocol returns success and the Status code of the SMB2 header of the response was STATUS_MORE_PROCESSING_REQUIRED, the client MUST process as follows:

  • If Connection.Dialect is "3.1.1", the client MUST look for a session object in Connection.PreAuthSessionTable by using the SessionId in the SMB2 header of the SMB2 SESSION_SETUP Response. If a session object is not present, the client MUST:

    • Allocate a session object and place it in the Connection.PreAuthSessionTable.

    • Set Session.PreauthIntegrityHashValue to Connection.PreauthIntegrityHashValue.

    • Session.SessionId MUST be set to the SessionId in the SMB2 header of the response.

      The session MUST be updated as follows:

    • The client MUST generate a hash using the Connection.PreauthIntegrityHashId algorithm on the string constructed by concatenating Session.PreauthIntegrityHashValue and the session setup request message retrieved from the Connection.OutstandingRequests. The client MUST set Session.PreauthIntegrityHashValue to the hash value generated above.

    • The client MUST generate a hash using the Connection.PreauthIntegrityHashId algorithm on the string constructed by concatenating Session.PreauthIntegrityHashValue and the session setup response message, including all bytes from the response's SMB2 header to the last byte received from the network. The client MUST set Session.PreauthIntegrityHashValue to the hash value generated above.

  • The client MUST send a subsequent session setup request to continue the authentication attempt. The client MUST construct an SMB2 SESSION_SETUP Request by following the syntax specified in section 2.2.5. The SMB2 header MUST be initialized as follows:

    • The Command field MUST be set to SMB2 SESSION_SETUP.

    • The MessageId field is set as specified in section 3.2.4.1.3.

    • The client MUST set the SessionId field in the SMB2 header of the new request to the SessionId received in the SMB2 header of the response.

The SMB2 SESSION_SETUP Request MUST be initialized as follows:

  • If RequireMessageSigning is TRUE, the client MUST set the SMB2_NEGOTIATE_SIGNING_REQUIRED bit in the SecurityMode field.

    If RequireMessageSigning is FALSE, the client MUST set the SMB2_NEGOTIATE_SIGNING_ENABLED bit in the SecurityMode field.

  • The client MUST set the Flags field to 0.

  • If the client supports the Distributed File System (DFS), the client MUST set the SMB2_GLOBAL_CAP_DFS bit in the Capabilities field. For more information about DFS, see [MSDFS].

  • The client MUST copy the GSS output token into the response. The client MUST set SecurityBufferOffset and SecurityBufferLength to describe the GSS output token.

If Connection.Dialect belongs to the SMB 3.x dialect family, and the request is for establishing a new channel, the client MUST also implement the following:

  • The SessionId field in the SMB2 header MUST be set to the Session.SessionId for the new channel being established. The SMB2_SESSION_FLAG_BINDING bit MUST be set in the Flags field.

  • The request MUST be signed as specified in section 3.2.4.1.1.

This request MUST be sent to the server.