From: Jeremy Allison Date: Wed, 4 Jan 2023 01:53:17 +0000 (-0800) Subject: s3: smbtorture: Add SMB2-DFS-FILENAME-LEADING-BACKSLASH test. X-Git-Tag: talloc-2.4.0~111 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d99d14cbc1db2e59e6c0d6169dd623bfb686fa0f;p=thirdparty%2Fsamba.git 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 Reviewed-by: Volker Lendecke --- diff --git a/selftest/knownfail.d/dfs_paths b/selftest/knownfail.d/dfs_paths index 127c0492f51..51d9d6e5a43 100644 --- a/selftest/knownfail.d/dfs_paths +++ b/selftest/knownfail.d/dfs_paths @@ -1,6 +1,7 @@ ^samba3.smbtorture_s3.smb2.SMB2-DFS-PATHS.smbtorture\(fileserver\) ^samba3.smbtorture_s3.smb2.SMB2-NON-DFS-SHARE.smbtorture\(fileserver\) ^samba3.smbtorture_s3.smb2.SMB2-DFS-SHARE-NON-DFS-PATH.smbtorture\(fileserver\) +^samba3.smbtorture_s3.smb2.SMB2-DFS-FILENAME-LEADING-BACKSLASH.smbtorture\(fileserver\) ^samba3.smbtorture_s3.smb1.SMB1-DFS-PATHS.smbtorture\(fileserver\) ^samba3.smbtorture_s3.smb1.SMB1-DFS-SEARCH-PATHS.smbtorture\(fileserver\) ^samba3.smbtorture_s3.smb1.SMB1-DFS-OPERATIONS.smbtorture\(fileserver\) 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/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,