[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Wed Jan 4 07:47:01 UTC 2023


The branch, master has been updated
       via  c9a6e242d15 s3: smbd: Strip any leading '\' characters if the SMB2 DFS flag is set.
       via  d99d14cbc1d s3: smbtorture: Add SMB2-DFS-FILENAME-LEADING-BACKSLASH test.
      from  01cdc5e00be lib/replace - add extra check to bsd_attr_list

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c9a6e242d15ee707a2e30f973fd37e80b3225aca
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jan 3 18:28:54 2023 -0800

    s3: smbd: Strip any leading '\\' characters if the SMB2 DFS flag is set.
    
    MacOS clients send SMB2 DFS pathnames as \server\share\file\name.
    
    Ensure smbd can cope with this by stipping any leading '\\'
    characters from an SMB2 packet with the DFS flag set.
    
    Remove knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Wed Jan  4 07:46:06 UTC 2023 on sn-devel-184

commit d99d14cbc1db2e59e6c0d6169dd623bfb686fa0f
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jan 3 17:53:17 2023 -0800

    s3: smbtorture: Add SMB2-DFS-FILENAME-LEADING-BACKSLASH test.
    
    Shows that we fail to cope with MacOSX clients that send a
    (or more than one) leading '\\' character for an SMB2 DFS pathname.
    
    I missed this in earlier tests as Windows, Linux, and
    libsmbclient clients do NOT send a leading backslash
    for SMB2 DFS paths. Only MacOSX (sigh:-).
    
    Passes against Windows. Adds a knownfail for smbd.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/selftest/tests.py   |  14 ++++
 source3/smbd/smb2_create.c  |  13 ++-
 source3/torture/proto.h     |   1 +
 source3/torture/test_smb2.c | 190 ++++++++++++++++++++++++++++++++++++++++++++
 source3/torture/torture.c   |   4 +
 5 files changed, 220 insertions(+), 2 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index a40316ef532..8039b4a8171 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -257,6 +257,20 @@ plantestsuite("samba3.smbtorture_s3.smb2.SMB2-DFS-PATHS",
                 smbtorture3,
                 "-mSMB2"])
 
+# BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
+# MacOSX clients send a leading '\\' character for DFS paths.
+#
+plantestsuite("samba3.smbtorture_s3.smb2.SMB2-DFS-FILENAME-LEADING-BACKSLASH",
+                "fileserver",
+                [os.path.join(samba3srcdir,
+                              "script/tests/test_smbtorture_s3.sh"),
+                'SMB2-DFS-FILENAME-LEADING-BACKSLASH',
+                '//$SERVER_IP/msdfs-pathname-share',
+                '$USERNAME',
+                '$PASSWORD',
+                smbtorture3,
+                "-mSMB2"])
+
 #
 # SMB2-NON-DFS-SHARE needs to run against a special share non-msdfs-pathname-share
 # This is an empty non-DFS share with no links, used merely to test
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index aba339014bb..0f18d5594a4 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -776,6 +776,17 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 
 	in_file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
 
+	is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
+	if (is_dfs) {
+		/*
+		 * With a DFS flag set, remove any leading '\\'
+		 * characters from in_name before further processing.
+		 */
+		while (in_name[0] == '\\') {
+			in_name++;
+		}
+	}
+
 	state->fname = talloc_strdup(state, in_name);
 	if (tevent_req_nomem(state->fname, req)) {
 		return tevent_req_post(req, state->ev);
@@ -960,8 +971,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 		state->lease_ptr = NULL;
 	}
 
-	is_dfs = (smb1req->flags2 & FLAGS2_DFS_PATHNAMES);
-
 	/* convert '\\' into '/' */
 	status = check_path_syntax_smb2(state->fname, is_dfs);
 	if (tevent_req_nterror(req, status)) {
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index 92b7dd4216c..df98a7445d7 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -123,6 +123,7 @@ bool run_smb2_stream_acl(int dummy);
 bool run_smb2_dfs_paths(int dummy);
 bool run_smb2_non_dfs_share(int dummy);
 bool run_smb2_dfs_share_non_dfs_path(int dummy);
+bool run_smb2_dfs_filename_leading_backslash(int dummy);
 bool run_smb1_dfs_paths(int dummy);
 bool run_smb1_dfs_search_paths(int dummy);
 bool run_smb1_dfs_operations(int dummy);
diff --git a/source3/torture/test_smb2.c b/source3/torture/test_smb2.c
index 22918d39ccd..dc249643aa6 100644
--- a/source3/torture/test_smb2.c
+++ b/source3/torture/test_smb2.c
@@ -4946,3 +4946,193 @@ bool run_smb2_dfs_share_non_dfs_path(int dummy)
 	(void)smb2_dfs_delete(cli, dfs_filename);
 	return retval;
 }
+
+/*
+ * "Raw" test of an SMB2 filename with one or more leading
+ * backslash characters to a DFS share.
+ *
+ * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
+ *
+ * Once the server passes SMB2-DFS-PATHS we can
+ * fold this test into that one.
+ *
+ * Passes cleanly against Windows.
+ */
+
+bool run_smb2_dfs_filename_leading_backslash(int dummy)
+{
+	struct cli_state *cli = NULL;
+	NTSTATUS status;
+	bool dfs_supported = false;
+	char *dfs_filename_slash = NULL;
+	char *dfs_filename_slash_multi = NULL;
+	uint64_t file_ino = 0;
+	bool ino_matched = false;
+	uint64_t fid_persistent = 0;
+	uint64_t fid_volatile = 0;
+	bool retval = false;
+
+	printf("Starting SMB2-DFS-FILENAME-LEADING-BACKSLASH\n");
+
+	if (!torture_init_connection(&cli)) {
+		return false;
+	}
+
+	status = smbXcli_negprot(cli->conn,
+				cli->timeout,
+				PROTOCOL_SMB2_02,
+				PROTOCOL_SMB3_11);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("smbXcli_negprot returned %s\n", nt_errstr(status));
+		return false;
+	}
+
+	status = cli_session_setup_creds(cli, torture_creds);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_session_setup returned %s\n", nt_errstr(status));
+		return false;
+	}
+
+	status = cli_tree_connect(cli, share, "?????", NULL);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("cli_tree_connect returned %s\n", nt_errstr(status));
+		return false;
+	}
+
+	/* Ensure this is a DFS share. */
+	dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
+	if (!dfs_supported) {
+		printf("Server %s does not support DFS\n",
+			smbXcli_conn_remote_name(cli->conn));
+		return false;
+	}
+	dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
+	if (!dfs_supported) {
+		printf("Share %s does not support DFS\n",
+			cli->share);
+		return false;
+	}
+
+	/*
+	 * Create the filename with one leading backslash.
+	 */
+	dfs_filename_slash = talloc_asprintf(talloc_tos(),
+					"\\%s\\%s\\file",
+					smbXcli_conn_remote_name(cli->conn),
+					cli->share);
+	if (dfs_filename_slash == NULL) {
+		printf("Out of memory\n");
+		return false;
+	}
+
+	/*
+	 * Create the filename with many leading backslashes.
+	 */
+	dfs_filename_slash_multi = talloc_asprintf(talloc_tos(),
+					"\\\\\\\\%s\\%s\\file",
+					smbXcli_conn_remote_name(cli->conn),
+					cli->share);
+	if (dfs_filename_slash_multi == NULL) {
+		printf("Out of memory\n");
+		return false;
+	}
+
+	/*
+	 * Trying to open "\\server\\share\\file" should get
+	 * NT_STATUS_OBJECT_NAME_NOT_FOUND.
+	 */
+	status = get_smb2_inode(cli,
+				dfs_filename_slash,
+				&file_ino);
+	if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+		printf("%s:%d Open of %s should get "
+			"STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
+			__FILE__,
+			__LINE__,
+			dfs_filename_slash,
+			nt_errstr(status));
+		return false;
+	}
+
+	/* Now create a file called "\\server\\share\\file". */
+	status = smb2cli_create(cli->conn,
+				cli->timeout,
+				cli->smb2.session,
+				cli->smb2.tcon,
+				dfs_filename_slash,
+				SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
+				SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
+				SEC_STD_SYNCHRONIZE|
+					SEC_STD_DELETE |
+					SEC_FILE_READ_DATA|
+					SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
+				FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
+				FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
+				FILE_CREATE, /* create_disposition, */
+				0, /* create_options, */
+				NULL, /* smb2_create_blobs *blobs */
+				&fid_persistent,
+				&fid_volatile,
+				NULL, /* struct smb_create_returns * */
+				talloc_tos(), /* mem_ctx. */
+				NULL, /* struct smb2_create_blobs * */
+				NULL); /* struct symlink_reparse_struct */
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("%s:%d smb2cli_create on %s returned %s\n",
+			__FILE__,
+			__LINE__,
+			dfs_filename_slash,
+			nt_errstr(status));
+		return false;
+	}
+
+	/*
+	 * Trying to open "\\server\\share\\file" should now get
+	 * a valid inode.
+	 */
+	status = get_smb2_inode(cli,
+				dfs_filename_slash,
+				&file_ino);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("%s:%d Open of %s should succeed "
+			"got %s\n",
+			__FILE__,
+			__LINE__,
+			dfs_filename_slash,
+			nt_errstr(status));
+		goto err;
+	}
+
+	/*
+	 * Trying to open "\\\\\\server\\share\\file" should now get
+	 * a valid inode that matches. MacOSX-style of DFS name test.
+	 */
+	ino_matched = smb2_inode_matches(cli,
+				dfs_filename_slash,
+				file_ino,
+				dfs_filename_slash_multi);
+       if (!ino_matched) {
+		printf("%s:%d Failed to match ino number for %s\n",
+			__FILE__,
+			__LINE__,
+			dfs_filename_slash_multi);
+		goto err;
+	}
+
+	retval = true;
+
+  err:
+
+	if (fid_persistent != 0 || fid_volatile != 0) {
+		smb2cli_close(cli->conn,
+			      cli->timeout,
+			      cli->smb2.session,
+			      cli->smb2.tcon,
+			      0, /* flags */
+			      fid_persistent,
+			      fid_volatile);
+	}
+	/* Delete anything we made. */
+	(void)smb2_dfs_delete(cli, dfs_filename_slash);
+	return retval;
+}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 4d22c539e52..acf245f3cb5 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -15369,6 +15369,10 @@ static struct {
 		.name  = "SMB2-DFS-SHARE-NON-DFS-PATH",
 		.fn    = run_smb2_dfs_share_non_dfs_path,
 	},
+	{
+		.name  = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
+		.fn    = run_smb2_dfs_filename_leading_backslash,
+	},
 	{
 		.name  = "SMB1-DFS-PATHS",
 		.fn    = run_smb1_dfs_paths,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list