diff options
author | Jeremy Allison <jra@samba.org> | 2018-05-10 11:30:24 -0700 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2018-06-19 13:45:09 +0200 |
commit | db362df94261512fff0701cf4153441fc8cf0c07 (patch) | |
tree | 31e459974021c121719828caa39b861972c0e423 | |
parent | a743be8440b05d8dd11170777965aac0fd06b062 (diff) | |
download | samba-db362df94261512fff0701cf4153441fc8cf0c07.tar.gz |
s3: smbtorture: Add new SMB2-DIR-FSYNC test to show behavior of FSYNC on directories.
Tests against a directory handle on the root of a share,
and a directory handle on a sub-directory in a share.
Check SEC_DIR_ADD_FILE and SEC_DIR_ADD_SUBDIR separately,
either allows flush to succeed.
Passes against Windows.
Regression test for:
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13428
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri May 18 02:38:50 CEST 2018 on sn-devel-144
(cherry picked from commit d42f467a25e75e5487a00378609a24809ddc83ee)
-rw-r--r-- | selftest/knownfail | 1 | ||||
-rwxr-xr-x | source3/selftest/tests.py | 2 | ||||
-rw-r--r-- | source3/torture/proto.h | 1 | ||||
-rw-r--r-- | source3/torture/test_smb2.c | 270 | ||||
-rw-r--r-- | source3/torture/torture.c | 1 |
5 files changed, 274 insertions, 1 deletions
diff --git a/selftest/knownfail b/selftest/knownfail index dd23c7d204f..267c928955e 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -8,6 +8,7 @@ .*driver.add_driver_timestamps # we only can store dates, not timestamps ^samba3.smbtorture_s3.crypt_server\(nt4_dc\).SMB2-SESSION-REAUTH # expected to give ACCESS_DENIED SMB2.1 doesn't have encryption ^samba3.smbtorture_s3.crypt_server\(nt4_dc\).SMB2-SESSION-RECONNECT # expected to give CONNECTION_DISCONNECTED, we need to fix the test +^samba3.smbtorture_s3.*ad_dc_ntvfs.*SMB2-DIR-FSYNC.* ^samba3.smb2.session enc.reconnect # expected to give CONNECTION_DISCONNECTED, we need to fix the test ^samba3.raw.session enc # expected to give ACCESS_DENIED as SMB1 encryption isn't used ^samba3.smbtorture_s3.crypt_server # expected to give ACCESS_DENIED as SMB1 encryption isn't used diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index cd5b49b87dc..59a3a551d3f 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -78,7 +78,7 @@ tests = ["FDPASS", "LOCK1", "LOCK2", "LOCK3", "LOCK4", "LOCK5", "LOCK6", "LOCK7" "GETADDRINFO", "UID-REGRESSION-TEST", "SHORTNAME-TEST", "CASE-INSENSITIVE-CREATE", "SMB2-BASIC", "NTTRANS-FSCTL", "SMB2-NEGPROT", "SMB2-SESSION-REAUTH", "SMB2-SESSION-RECONNECT", "SMB2-FTRUNCATE", - "SMB2-ANONYMOUS", + "SMB2-ANONYMOUS", "SMB2-DIR-FSYNC", "CLEANUP1", "CLEANUP2", "CLEANUP4", diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 6f12ff7c2b9..a8400382e10 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -101,6 +101,7 @@ bool run_smb2_tcon_dependence(int dummy); bool run_smb2_multi_channel(int dummy); bool run_smb2_session_reauth(int dummy); bool run_smb2_ftruncate(int dummy); +bool run_smb2_dir_fsync(int dummy); bool run_chain3(int dummy); bool run_local_conv_auth_info(int dummy); bool run_local_sprintf_append(int dummy); diff --git a/source3/torture/test_smb2.c b/source3/torture/test_smb2.c index 897d034f6a9..094a9b84d6e 100644 --- a/source3/torture/test_smb2.c +++ b/source3/torture/test_smb2.c @@ -2065,3 +2065,273 @@ bool run_smb2_ftruncate(int dummy) } return correct; } + +/* Ensure SMB2 flush on directories behaves correctly. */ + +static bool test_dir_fsync(struct cli_state *cli, const char *path) +{ + NTSTATUS status; + uint64_t fid_persistent, fid_volatile; + uint8_t *dir_data = NULL; + uint32_t dir_data_length = 0; + + /* Open directory - no write abilities. */ + status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, path, + SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */ + SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */ + SEC_STD_SYNCHRONIZE| + SEC_DIR_LIST| + SEC_DIR_READ_ATTRIBUTE, /* desired_access, */ + 0, /* file_attributes, */ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */ + FILE_OPEN, /* create_disposition, */ + FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */ + NULL, /* smb2_create_blobs *blobs */ + &fid_persistent, + &fid_volatile, + NULL, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_create '%s' (readonly) returned %s\n", + path, + nt_errstr(status)); + return false; + } + + status = smb2cli_query_directory( + cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon, + 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff, + talloc_tos(), &dir_data, &dir_data_length); + + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_query_directory returned %s\n", + nt_errstr(status)); + return false; + } + + /* Open directory no write access. Flush should fail. */ + + status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, fid_persistent, fid_volatile); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + printf("smb2cli_flush on a read-only directory returned %s\n", + nt_errstr(status)); + return false; + } + + status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, 0, fid_persistent, fid_volatile); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_close returned %s\n", nt_errstr(status)); + return false; + } + + /* Open directory write-attributes only. Flush should still fail. */ + + status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, path, + SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */ + SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */ + SEC_STD_SYNCHRONIZE| + SEC_DIR_LIST| + SEC_DIR_WRITE_ATTRIBUTE| + SEC_DIR_READ_ATTRIBUTE, /* desired_access, */ + 0, /* file_attributes, */ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */ + FILE_OPEN, /* create_disposition, */ + FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */ + NULL, /* smb2_create_blobs *blobs */ + &fid_persistent, + &fid_volatile, + NULL, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_create '%s' (write attr) returned %s\n", + path, + nt_errstr(status)); + return false; + } + + status = smb2cli_query_directory( + cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon, + 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff, + talloc_tos(), &dir_data, &dir_data_length); + + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_query_directory returned %s\n", nt_errstr(status)); + return false; + } + + status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, fid_persistent, fid_volatile); + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + printf("smb2cli_flush on a write-attributes directory " + "returned %s\n", + nt_errstr(status)); + return false; + } + + status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, 0, fid_persistent, fid_volatile); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_close returned %s\n", nt_errstr(status)); + return false; + } + + /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */ + + status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, path, + SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */ + SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */ + SEC_STD_SYNCHRONIZE| + SEC_DIR_LIST| + SEC_DIR_ADD_FILE, /* desired_access, */ + 0, /* file_attributes, */ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */ + FILE_OPEN, /* create_disposition, */ + FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */ + NULL, /* smb2_create_blobs *blobs */ + &fid_persistent, + &fid_volatile, + NULL, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_create '%s' (write FILE access) returned %s\n", + path, + nt_errstr(status)); + return false; + } + + status = smb2cli_query_directory( + cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon, + 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff, + talloc_tos(), &dir_data, &dir_data_length); + + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_query_directory returned %s\n", nt_errstr(status)); + return false; + } + + status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, fid_persistent, fid_volatile); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_flush on a directory returned %s\n", + nt_errstr(status)); + return false; + } + + status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, 0, fid_persistent, fid_volatile); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_close returned %s\n", nt_errstr(status)); + return false; + } + + /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */ + + status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, path, + SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */ + SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */ + SEC_STD_SYNCHRONIZE| + SEC_DIR_LIST| + SEC_DIR_ADD_SUBDIR, /* desired_access, */ + 0, /* file_attributes, */ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */ + FILE_OPEN, /* create_disposition, */ + FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */ + NULL, /* smb2_create_blobs *blobs */ + &fid_persistent, + &fid_volatile, + NULL, NULL, NULL); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_create '%s' (write DIR access) returned %s\n", + path, + nt_errstr(status)); + return false; + } + + status = smb2cli_query_directory( + cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon, + 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff, + talloc_tos(), &dir_data, &dir_data_length); + + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_query_directory returned %s\n", nt_errstr(status)); + return false; + } + + status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, fid_persistent, fid_volatile); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_flush on a directory returned %s\n", + nt_errstr(status)); + return false; + } + + status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session, + cli->smb2.tcon, 0, fid_persistent, fid_volatile); + if (!NT_STATUS_IS_OK(status)) { + printf("smb2cli_close returned %s\n", nt_errstr(status)); + return false; + } + + + return true; +} + +bool run_smb2_dir_fsync(int dummy) +{ + struct cli_state *cli = NULL; + NTSTATUS status; + bool bret = false; + const char *dname = "fsync_test_dir"; + + printf("Starting SMB2-DIR-FSYNC\n"); + + if (!torture_init_connection(&cli)) { + return false; + } + + status = smbXcli_negprot(cli->conn, cli->timeout, + PROTOCOL_SMB2_02, PROTOCOL_SMB2_02); + 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; + } + + (void)cli_rmdir(cli, dname); + status = cli_mkdir(cli, dname); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_mkdir(%s) returned %s\n", + dname, + nt_errstr(status)); + return false; + } + + /* Test on a subdirectory. */ + bret = test_dir_fsync(cli, dname); + if (bret == false) { + (void)cli_rmdir(cli, dname); + return false; + } + (void)cli_rmdir(cli, dname); + + /* Test on the root handle of a share. */ + bret = test_dir_fsync(cli, ""); + if (bret == false) { + return false; + } + return true; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 3bc4f9cca45..245a72300c4 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -11650,6 +11650,7 @@ static struct { { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel }, { "SMB2-SESSION-REAUTH", run_smb2_session_reauth }, { "SMB2-FTRUNCATE", run_smb2_ftruncate }, + { "SMB2-DIR-FSYNC", run_smb2_dir_fsync }, { "CLEANUP1", run_cleanup1 }, { "CLEANUP2", run_cleanup2 }, { "CLEANUP3", run_cleanup3 }, |