Skip to content

Commit 52d0053

Browse files
author
Steve French
committed
smb3: send NTLMSSP version information
For improved debugging it can be helpful to send version information as other clients do during NTLMSSP negotiation. See protocol document MS-NLMP section 2.2.1.1 Set the major and minor versions based on the kernel version, and the BuildNumber based on the internal cifs.ko module version number, and following the recommendation in the protocol documentation (MS-NLMP section 2.2.10) we set the NTLMRevisionCurrent field to 15. Reviewed-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 70431bf commit 52d0053

File tree

4 files changed

+101
-2
lines changed

4 files changed

+101
-2
lines changed

fs/cifs/cifsfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,5 +152,6 @@ extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
152152
extern const struct export_operations cifs_export_ops;
153153
#endif /* CONFIG_CIFS_NFSD_EXPORT */
154154

155+
#define SMB3_PRODUCT_BUILD 34
155156
#define CIFS_VERSION "2.34"
156157
#endif /* _CIFSFS_H */

fs/cifs/ntlmssp.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#define NTLMSSP_REQUEST_NON_NT_KEY 0x400000
4141
#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x800000
4242
/* #define reserved4 0x1000000 */
43-
#define NTLMSSP_NEGOTIATE_VERSION 0x2000000 /* we do not set */
43+
#define NTLMSSP_NEGOTIATE_VERSION 0x2000000 /* we only set for SMB2+ */
4444
/* #define reserved3 0x4000000 */
4545
/* #define reserved2 0x8000000 */
4646
/* #define reserved1 0x10000000 */
@@ -87,6 +87,30 @@ typedef struct _NEGOTIATE_MESSAGE {
8787
/* followed by WorkstationString */
8888
} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
8989

90+
#define NTLMSSP_REVISION_W2K3 0x0F
91+
92+
/* See MS-NLMP section 2.2.2.10 */
93+
struct ntlmssp_version {
94+
__u8 ProductMajorVersion;
95+
__u8 ProductMinorVersion;
96+
__le16 ProductBuild; /* we send the cifs.ko module version here */
97+
__u8 Reserved[3];
98+
__u8 NTLMRevisionCurrent; /* currently 0x0F */
99+
} __packed;
100+
101+
/* see MS-NLMP section 2.2.1.1 */
102+
struct negotiate_message {
103+
__u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
104+
__le32 MessageType; /* NtLmNegotiate = 1 */
105+
__le32 NegotiateFlags;
106+
SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */
107+
SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */
108+
struct ntlmssp_version Version;
109+
/* SECURITY_BUFFER */
110+
char DomainString[0];
111+
/* followed by WorkstationString */
112+
} __packed;
113+
90114
typedef struct _CHALLENGE_MESSAGE {
91115
__u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
92116
__le32 MessageType; /* NtLmChallenge = 2 */
@@ -123,6 +147,10 @@ int build_ntlmssp_negotiate_blob(unsigned char **pbuffer, u16 *buflen,
123147
struct cifs_ses *ses,
124148
struct TCP_Server_Info *server,
125149
const struct nls_table *nls_cp);
150+
int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer, u16 *buflen,
151+
struct cifs_ses *ses,
152+
struct TCP_Server_Info *server,
153+
const struct nls_table *nls_cp);
126154
int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
127155
struct cifs_ses *ses,
128156
struct TCP_Server_Info *server,

fs/cifs/sess.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "nterr.h"
1818
#include <linux/utsname.h>
1919
#include <linux/slab.h>
20+
#include <linux/version.h>
21+
#include "cifsfs.h"
2022
#include "cifs_spnego.h"
2123
#include "smb2proto.h"
2224
#include "fs_context.h"
@@ -809,6 +811,74 @@ int build_ntlmssp_negotiate_blob(unsigned char **pbuffer,
809811
return rc;
810812
}
811813

814+
/*
815+
* Build ntlmssp blob with additional fields, such as version,
816+
* supported by modern servers. For safety limit to SMB3 or later
817+
* See notes in MS-NLMP Section 2.2.2.1 e.g.
818+
*/
819+
int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer,
820+
u16 *buflen,
821+
struct cifs_ses *ses,
822+
struct TCP_Server_Info *server,
823+
const struct nls_table *nls_cp)
824+
{
825+
int rc = 0;
826+
struct negotiate_message *sec_blob;
827+
__u32 flags;
828+
unsigned char *tmp;
829+
int len;
830+
831+
len = size_of_ntlmssp_blob(ses, sizeof(struct negotiate_message));
832+
*pbuffer = kmalloc(len, GFP_KERNEL);
833+
if (!*pbuffer) {
834+
rc = -ENOMEM;
835+
cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
836+
*buflen = 0;
837+
goto setup_ntlm_smb3_neg_ret;
838+
}
839+
sec_blob = (struct negotiate_message *)*pbuffer;
840+
841+
memset(*pbuffer, 0, sizeof(struct negotiate_message));
842+
memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
843+
sec_blob->MessageType = NtLmNegotiate;
844+
845+
/* BB is NTLMV2 session security format easier to use here? */
846+
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
847+
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
848+
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
849+
NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL |
850+
NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_VERSION;
851+
if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
852+
flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
853+
854+
sec_blob->Version.ProductMajorVersion = LINUX_VERSION_MAJOR;
855+
sec_blob->Version.ProductMinorVersion = LINUX_VERSION_PATCHLEVEL;
856+
sec_blob->Version.ProductBuild = cpu_to_le16(SMB3_PRODUCT_BUILD);
857+
sec_blob->Version.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
858+
859+
tmp = *pbuffer + sizeof(struct negotiate_message);
860+
ses->ntlmssp->client_flags = flags;
861+
sec_blob->NegotiateFlags = cpu_to_le32(flags);
862+
863+
/* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */
864+
cifs_security_buffer_from_str(&sec_blob->DomainName,
865+
NULL,
866+
CIFS_MAX_DOMAINNAME_LEN,
867+
*pbuffer, &tmp,
868+
nls_cp);
869+
870+
cifs_security_buffer_from_str(&sec_blob->WorkstationName,
871+
NULL,
872+
CIFS_MAX_WORKSTATION_LEN,
873+
*pbuffer, &tmp,
874+
nls_cp);
875+
876+
*buflen = tmp - *pbuffer;
877+
setup_ntlm_smb3_neg_ret:
878+
return rc;
879+
}
880+
881+
812882
int build_ntlmssp_auth_blob(unsigned char **pbuffer,
813883
u16 *buflen,
814884
struct cifs_ses *ses,

fs/cifs/smb2pdu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1506,7 +1506,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
15061506
if (rc)
15071507
goto out_err;
15081508

1509-
rc = build_ntlmssp_negotiate_blob(&ntlmssp_blob,
1509+
rc = build_ntlmssp_smb3_negotiate_blob(&ntlmssp_blob,
15101510
&blob_length, ses, server,
15111511
sess_data->nls_cp);
15121512
if (rc)

0 commit comments

Comments
 (0)