Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fcef0db6 authored by Steve French's avatar Steve French
Browse files

smb3: add support for posix negotiate context



Unlike CIFS where UNIX/POSIX extensions had been negotiatable,
SMB3 did not have POSIX extensions yet.  Add the new SMB3.11
POSIX negotiate context to ask the server whether it can
support POSIX (and thus whether we can send the new POSIX open
context).

Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent f92a720e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -238,6 +238,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
			server->credits,  server->dialect);
		if (server->sign)
			seq_printf(m, " signed");
#ifdef CONFIG_CIFS_SMB311
		if (server->posix_ext_supported)
			seq_printf(m, " posix");
#endif /* 3.1.1 */
		i++;
		list_for_each(tmp2, &server->smb_ses_list) {
			ses = list_entry(tmp2, struct cifs_ses,
+1 −0
Original line number Diff line number Diff line
@@ -683,6 +683,7 @@ struct TCP_Server_Info {
	__le16	cipher_type;
	 /* save initital negprot hash */
	__u8	preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE];
	bool	posix_ext_supported;
#endif /* 3.1.1 */
	struct delayed_work reconnect; /* reconnect workqueue job */
	struct mutex reconnect_mutex; /* prevent simultaneous reconnects */
+23 −6
Original line number Diff line number Diff line
@@ -368,6 +368,7 @@ smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,

#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES	cpu_to_le16(1)
#define SMB2_ENCRYPTION_CAPABILITIES		cpu_to_le16(2)
#define SMB2_POSIX_EXTENSIONS_AVAILABLE		cpu_to_le16(0x100)

static void
build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt)
@@ -390,22 +391,36 @@ build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
	pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_CCM;
}

static void
build_posix_ctxt(struct smb2_posix_neg_context *pneg_ctxt)
{
	pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
	pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
}

static void
assemble_neg_contexts(struct smb2_negotiate_req *req,
		      unsigned int *total_len)
{
	char *pneg_ctxt = (char *)req + OFFSET_OF_NEG_CONTEXT;
	unsigned int ctxt_len;

	*total_len += 2; /* Add 2 due to round to 8 byte boundary for 1st ctxt */
	build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
	/* Add 2 to size to round to 8 byte boundary */
	ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
	*total_len += ctxt_len;
	pneg_ctxt += ctxt_len;

	pneg_ctxt += 2 + sizeof(struct smb2_preauth_neg_context);
	build_encrypt_ctxt((struct smb2_encryption_neg_context *)pneg_ctxt);
	req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
	req->NegotiateContextCount = cpu_to_le16(2);
	ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_encryption_neg_context), 8) * 8;
	*total_len += ctxt_len;
	pneg_ctxt += ctxt_len;

	build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
	*total_len += sizeof(struct smb2_posix_neg_context);

	*total_len += 4 + sizeof(struct smb2_preauth_neg_context)
		+ sizeof(struct smb2_encryption_neg_context);
	req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
	req->NegotiateContextCount = cpu_to_le16(3);
}

static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt)
@@ -488,6 +503,8 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp,
		else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES)
			rc = decode_encrypt_ctx(server,
				(struct smb2_encryption_neg_context *)pctx);
		else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE)
			server->posix_ext_supported = true;
		else
			cifs_dbg(VFS, "unknown negcontext of type %d ignored\n",
				le16_to_cpu(pctx->ContextType));
+8 −0
Original line number Diff line number Diff line
@@ -300,6 +300,14 @@ struct smb2_encryption_neg_context {
	__le16	Ciphers[1]; /* Ciphers[0] since only one used now */
} __packed;

#define POSIX_CTXT_DATA_LEN	8
struct smb2_posix_neg_context {
	__le16	ContextType; /* 0x100 */
	__le16	DataLength;
	__le32	Reserved;
	__le64	Reserved1; /* In case needed for future (eg version or caps) */
} __packed;

struct smb2_negotiate_rsp {
	struct smb2_hdr hdr;
	__le16 StructureSize;	/* Must be 65 */