diff options
author | Jeremy Allison <jra@samba.org> | 2018-07-12 12:15:12 -0700 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2018-08-13 12:56:35 +0200 |
commit | 41302b40301b410ca618c92df67394de51d6b1bc (patch) | |
tree | 4ede5031b255e6508a285cb2d9e9dd13e5b61ffa /source3 | |
parent | a96f69a346a4d7a46873c1d3d65d90578fdf15e6 (diff) | |
download | samba-41302b40301b410ca618c92df67394de51d6b1bc.tar.gz |
s3: torture: Test SMB1 cli_splice() fallback path when doing a non-full file splice.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13527
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
(cherry picked from commit 1c8d1cceff852acaca4a0ec0da37b053ed03fe4a)
(cherry picked from commit 49d6c3f061284aac31c3ef21f88f9d69bdd86bd8)
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat Jul 14 00:14:13 CEST 2018 on sn-devel-144
Diffstat (limited to 'source3')
-rwxr-xr-x | source3/selftest/tests.py | 5 | ||||
-rw-r--r-- | source3/torture/torture.c | 153 |
2 files changed, 157 insertions, 1 deletions
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 1e18acc80f2..07fab8af254 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -74,7 +74,7 @@ tests = ["FDPASS", "LOCK1", "LOCK2", "LOCK3", "LOCK4", "LOCK5", "LOCK6", "LOCK7" "DIR", "DIR1", "DIR-CREATETIME", "TCON", "TCONDEV", "RW1", "RW2", "RW3", "LARGE_READX", "RW-SIGNING", "OPEN", "XCOPY", "RENAME", "DELETE", "DELETE-LN", "WILDDELETE", "PROPERTIES", "W2K", "TCON2", "IOCTL", "CHKPATH", "FDSESS", "CHAIN1", "CHAIN2", "OWNER-RIGHTS", - "CHAIN3", "PIDHIGH", + "CHAIN3", "PIDHIGH", "CLI_SPLICE", "UID-REGRESSION-TEST", "SHORTNAME-TEST", "CASE-INSENSITIVE-CREATE", "SMB2-BASIC", "NTTRANS-FSCTL", "SMB2-NEGPROT", "SMB2-SESSION-REAUTH", "SMB2-SESSION-RECONNECT", "SMB2-FTRUNCATE", @@ -91,6 +91,9 @@ for t in tests: # this is a negative test to verify that the server rejects # access without encryption plantestsuite("samba3.smbtorture_s3.crypt_server(nt4_dc).%s" % t, "nt4_dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/tmpenc', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"]) + if t == "CLI_SPLICE": + # We must test this against the SMB1 fallback. + plantestsuite("samba3.smbtorture_s3.plain(fileserver).%s" % t, "fileserver", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH", "-mNT1"]) plantestsuite("samba3.smbtorture_s3.plain(ad_dc_ntvfs).%s" % t, "ad_dc_ntvfs", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"]) # diff --git a/source3/torture/torture.c b/source3/torture/torture.c index dc35bda21d0..ed7390a47a7 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -43,6 +43,7 @@ #include "lib/util/sys_rw_data.h" #include "lib/util/base64.h" #include "lib/util/time.h" +#include "lib/crypto/md5.h" extern char *optarg; extern int optind; @@ -9239,6 +9240,157 @@ static bool run_cli_echo(int dummy) return NT_STATUS_IS_OK(status); } +static int splice_status(off_t written, void *priv) +{ + return true; +} + +static bool run_cli_splice(int dummy) +{ + uint8_t *buf = NULL; + struct cli_state *cli1 = NULL; + bool correct = false; + const char *fname_src = "\\splice_src.dat"; + const char *fname_dst = "\\splice_dst.dat"; + NTSTATUS status; + uint16_t fnum1 = UINT16_MAX; + uint16_t fnum2 = UINT16_MAX; + size_t file_size = 2*1024*1024; + size_t splice_size = 1*1024*1024 + 713; + MD5_CTX md5_ctx; + uint8_t digest1[16], digest2[16]; + off_t written = 0; + size_t nread = 0; + TALLOC_CTX *frame = talloc_stackframe(); + + printf("starting cli_splice test\n"); + + if (!torture_open_connection(&cli1, 0)) { + goto out; + } + + cli_unlink(cli1, fname_src, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_unlink(cli1, fname_dst, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + /* Create a file */ + status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, + 0, 0, &fnum1, NULL); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("open %s failed: %s\n", fname_src, nt_errstr(status)); + goto out; + } + + /* Write file_size bytes - must be bigger than splice_size. */ + buf = talloc_zero_array(frame, uint8_t, file_size); + if (buf == NULL) { + d_printf("talloc_fail\n"); + goto out; + } + + /* Fill it with random numbers. */ + generate_random_buffer(buf, file_size); + + /* MD5 the first 1MB + 713 bytes. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, buf, splice_size); + MD5Final(digest1, &md5_ctx); + + status = cli_writeall(cli1, + fnum1, + 0, + buf, + 0, + file_size, + NULL); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_writeall failed: %s\n", nt_errstr(status)); + goto out; + } + + status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS, + FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, + 0, 0, &fnum2, NULL); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status)); + goto out; + } + + /* Now splice 1MB + 713 bytes. */ + status = cli_splice(cli1, + cli1, + fnum1, + fnum2, + splice_size, + 0, + 0, + &written, + splice_status, + NULL); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_splice failed: %s\n", nt_errstr(status)); + goto out; + } + + /* Clear the old buffer. */ + memset(buf, '\0', file_size); + + /* Read the new file. */ + status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread); + if (!NT_STATUS_IS_OK(status)) { + d_printf("cli_read failed: %s\n", nt_errstr(status)); + goto out; + } + if (nread != splice_size) { + d_printf("bad read of 0x%x, should be 0x%x\n", + (unsigned int)nread, + (unsigned int)splice_size); + goto out; + } + + /* MD5 the first 1MB + 713 bytes. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, buf, splice_size); + MD5Final(digest2, &md5_ctx); + + /* Must be the same. */ + if (memcmp(digest1, digest2, 16) != 0) { + d_printf("bad MD5 compare\n"); + goto out; + } + + correct = true; + printf("Success on cli_splice test\n"); + + out: + + if (cli1) { + if (fnum1 != UINT16_MAX) { + cli_close(cli1, fnum1); + } + if (fnum2 != UINT16_MAX) { + cli_close(cli1, fnum2); + } + + cli_unlink(cli1, fname_src, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_unlink(cli1, fname_dst, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + + if (!torture_close_connection(cli1)) { + correct = false; + } + } + + TALLOC_FREE(frame); + return correct; +} + static bool run_uid_regression_test(int dummy) { static struct cli_state *cli; @@ -11650,6 +11802,7 @@ static struct { { "NTTRANS-CREATE", run_nttrans_create, 0}, { "NTTRANS-FSCTL", run_nttrans_fsctl, 0}, { "CLI_ECHO", run_cli_echo, 0}, + { "CLI_SPLICE", run_cli_splice, 0}, { "TLDAP", run_tldap }, { "STREAMERROR", run_streamerror }, { "NOTIFY-BENCH", run_notify_bench }, |