public inbox for linux-cifs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cifs: implementation id context as negotiate context
@ 2026-03-04 12:27 nspmangalore
  2026-03-04 12:34 ` Shyam Prasad N
  2026-03-09 16:19 ` Ralph Boehme
  0 siblings, 2 replies; 15+ messages in thread
From: nspmangalore @ 2026-03-04 12:27 UTC (permalink / raw)
  To: linux-cifs, smfrench, pc, bharathsm, dhowells; +Cc: Shyam Prasad N

From: Shyam Prasad N <sprasad@microsoft.com>

MS-SMB2 does not allow any fields for the client to communicate
the client version details to the server. This change is a
proof-of-concept to add client details in a new negotiate context.

Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
---
 fs/smb/client/smb2pdu.c | 78 +++++++++++++++++++++++++++++++++++++++++
 fs/smb/common/smb2pdu.h | 32 +++++++++++++++++
 2 files changed, 110 insertions(+)

diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index ef655acf673df..9c89f6b4a6709 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -24,6 +24,7 @@
 #include <linux/pagemap.h>
 #include <linux/xattr.h>
 #include <linux/netfs.h>
+#include <linux/utsname.h>
 #include <trace/events/netfs.h>
 #include "cifsglob.h"
 #include "cifsproto.h"
@@ -45,6 +46,7 @@
 #include "cached_dir.h"
 #include "compress.h"
 #include "fs_context.h"
+#include "cifsfs.h"
 
 /*
  *  The following table defines the expected "StructureSize" of SMB2 requests
@@ -724,6 +726,75 @@ build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
 	pneg_ctxt->Name[15] = 0x7C;
 }
 
+static unsigned int
+build_implementation_id_ctxt(struct smb2_implementation_id_context *pneg_ctxt)
+{
+	struct nls_table *cp = load_nls_default();
+	struct new_utsname *uts = utsname();
+	const char *impl_domain = "kernel.org";
+	const char *impl_name = "fs/smb/client";
+	const char *os_name = "Linux";
+	unsigned int data_len = 0;
+	__u8 *data_ptr;
+	int len;
+
+	pneg_ctxt->ContextType = SMB2_IMPLEMENTATION_ID_CONTEXT_ID;
+	data_ptr = pneg_ctxt->Data;
+
+	/* ImplDomain */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, impl_domain,
+			      SMB2_IMPL_ID_MAX_DOMAIN_LEN, cp);
+	pneg_ctxt->ImplDomainLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* ImplName */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, impl_name,
+			      SMB2_IMPL_ID_MAX_NAME_LEN, cp);
+	pneg_ctxt->ImplNameLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* ImplVersion - CIFS_VERSION from cifsfs.h */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, CIFS_VERSION,
+			      SMB2_IMPL_ID_MAX_VERSION_LEN, cp);
+	pneg_ctxt->ImplVersionLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* HostName - from utsname()->nodename */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->nodename,
+			      SMB2_IMPL_ID_MAX_HOSTNAME_LEN, cp);
+	pneg_ctxt->HostNameLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* OSName */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, os_name,
+			      SMB2_IMPL_ID_MAX_OS_NAME_LEN, cp);
+	pneg_ctxt->OSNameLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* OSVersion - from utsname()->release */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->release,
+			      SMB2_IMPL_ID_MAX_OS_VERSION_LEN, cp);
+	pneg_ctxt->OSVersionLength = cpu_to_le16(len * 2);
+	data_ptr += len * 2;
+	data_len += len * 2;
+
+	/* Arch - from utsname()->machine */
+	len = cifs_strtoUTF16((__le16 *)data_ptr, uts->machine,
+			      SMB2_IMPL_ID_MAX_ARCH_LEN, cp);
+	pneg_ctxt->ArchLength = cpu_to_le16(len * 2);
+	data_len += len * 2;
+
+	pneg_ctxt->Reserved2 = 0;
+	pneg_ctxt->DataLength = cpu_to_le16(data_len + 14); /* 14 = 7 length fields * 2 bytes */
+	/* Context size is DataLength + minimal smb2_neg_context, aligned to 8 */
+	return ALIGN(le16_to_cpu(pneg_ctxt->DataLength) + sizeof(struct smb2_neg_context), 8);
+}
+
 static void
 assemble_neg_contexts(struct smb2_negotiate_req *req,
 		      struct TCP_Server_Info *server, unsigned int *total_len)
@@ -797,6 +868,13 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
 		neg_context_count++;
 	}
 
+	/* Add implementation ID context */
+	ctxt_len = build_implementation_id_ctxt((struct smb2_implementation_id_context *)
+				pneg_ctxt);
+	*total_len += ctxt_len;
+	pneg_ctxt += ctxt_len;
+	neg_context_count++;
+
 	/* check for and add transport_capabilities and signing capabilities */
 	req->NegotiateContextCount = cpu_to_le16(neg_context_count);
 
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index e482c86ceb00d..1ad7b57ce2952 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -457,6 +457,7 @@ struct smb2_tree_disconnect_rsp {
 #define SMB2_TRANSPORT_CAPABILITIES		cpu_to_le16(6)
 #define SMB2_RDMA_TRANSFORM_CAPABILITIES	cpu_to_le16(7)
 #define SMB2_SIGNING_CAPABILITIES		cpu_to_le16(8)
+#define SMB2_IMPLEMENTATION_ID_CONTEXT_ID	cpu_to_le16(0xF100)
 #define SMB2_POSIX_EXTENSIONS_AVAILABLE		cpu_to_le16(0x100)
 
 struct smb2_neg_context {
@@ -596,6 +597,37 @@ struct smb2_signing_capabilities {
 	/*  Followed by padding to 8 byte boundary (required by some servers) */
 } __packed;
 
+/*
+ * For implementation ID context see MS-SMB2 2.2.3.1.8
+ * Maximum string lengths per specification
+ */
+#define SMB2_IMPL_ID_MAX_DOMAIN_LEN	128
+#define SMB2_IMPL_ID_MAX_NAME_LEN	260
+#define SMB2_IMPL_ID_MAX_VERSION_LEN	260
+#define SMB2_IMPL_ID_MAX_HOSTNAME_LEN	64
+#define SMB2_IMPL_ID_MAX_OS_NAME_LEN	64
+#define SMB2_IMPL_ID_MAX_OS_VERSION_LEN	64
+#define SMB2_IMPL_ID_MAX_ARCH_LEN	64
+
+struct smb2_implementation_id_context {
+	__le16	ContextType; /* 9 */
+	__le16	DataLength;
+	__le32	Reserved;
+	__le16	ImplDomainLength;
+	__le16	ImplNameLength;
+	__le16	ImplVersionLength;
+	__le16	HostNameLength;
+	__le16	OSNameLength;
+	__le16	OSVersionLength;
+	__le16	ArchLength;
+	__le16	Reserved2;
+	/* Followed by variable length UTF-16 strings:
+	 * ImplDomain, ImplName, ImplVersion, HostName,
+	 * OSName, OSVersion, Arch
+	 */
+	__u8	Data[];
+} __packed;
+
 #define POSIX_CTXT_DATA_LEN	16
 struct smb2_posix_neg_context {
 	__le16	ContextType; /* 0x100 */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-03-12  0:00 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-04 12:27 [PATCH] cifs: implementation id context as negotiate context nspmangalore
2026-03-04 12:34 ` Shyam Prasad N
2026-03-06 22:45   ` Henrique Carvalho
2026-03-06 23:04     ` Steve French
2026-03-06 23:19       ` Paulo Alcantara
2026-03-06 23:23         ` Steve French
2026-03-09 16:34         ` Shyam Prasad N
2026-03-06 23:30       ` Henrique Carvalho
2026-03-09 16:19 ` Ralph Boehme
2026-03-09 16:37   ` Shyam Prasad N
2026-03-09 17:35     ` Ralph Boehme
2026-03-11 23:50       ` Shyam Prasad N
2026-03-09 17:59     ` Enzo Matsumiya
2026-03-11 23:52       ` Shyam Prasad N
2026-03-12  0:00         ` Steve French

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox