summaryrefslogtreecommitdiff
path: root/source4/torture/raw
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture/raw')
-rw-r--r--source4/torture/raw/lock.c120
-rw-r--r--source4/torture/raw/open.c198
2 files changed, 271 insertions, 47 deletions
diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c
index 7eb461048b..6c86a6f615 100644
--- a/source4/torture/raw/lock.c
+++ b/source4/torture/raw/lock.c
@@ -80,10 +80,14 @@
#define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \
(torture_setting_bool(_tctx, "invalid_lock_range_support", true))
+#define TARGET_SUPPORTS_SMBEXIT(_tctx) \
+ (torture_setting_bool(_tctx, "smbexit_pdu_support", true))
#define TARGET_SUPPORTS_SMBLOCK(_tctx) \
(torture_setting_bool(_tctx, "smblock_pdu_support", true))
#define TARGET_SUPPORTS_OPENX_DENY_DOS(_tctx) \
(torture_setting_bool(_tctx, "openx_deny_dos_support", true))
+#define TARGET_RETURNS_RANGE_NOT_LOCKED(_tctx) \
+ (torture_setting_bool(_tctx, "range_not_locked_on_file_close", true))
/*
test SMBlock and SMBunlock ops
*/
@@ -786,7 +790,10 @@ static bool test_async(struct torture_context *tctx,
CHECK_STATUS(status, NT_STATUS_OK);
status = smbcli_request_simple_recv(req);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ if (TARGET_RETURNS_RANGE_NOT_LOCKED(tctx))
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ else
+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx,
"lock cancel by close was not immediate (%s)\n", __location__));
@@ -816,46 +823,57 @@ static bool test_async(struct torture_context *tctx,
tree->tid = tcon.tconx.out.tid;
torture_comment(tctx, "testing cancel by exit\n");
- fname = BASEDIR "\\test_exit.txt";
- fnum = smbcli_open(tree, fname, O_RDWR|O_CREAT, DENY_NONE);
- torture_assert(tctx,(fnum != -1), talloc_asprintf(tctx,
- "Failed to reopen %s - %s\n",
- fname, smbcli_errstr(tree)));
-
- io.lockx.level = RAW_LOCK_LOCKX;
- io.lockx.in.file.fnum = fnum;
- io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
- io.lockx.in.timeout = 0;
- io.lockx.in.ulock_cnt = 0;
- io.lockx.in.lock_cnt = 1;
- lock[0].pid = session->pid;
- lock[0].offset = 100;
- lock[0].count = 10;
- io.lockx.in.locks = &lock[0];
- status = smb_raw_lock(tree, &io);
- CHECK_STATUS(status, NT_STATUS_OK);
-
- io.lockx.in.ulock_cnt = 0;
- io.lockx.in.lock_cnt = 1;
- io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
- io.lockx.in.timeout = 0;
- status = smb_raw_lock(tree, &io);
- CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+ if (TARGET_SUPPORTS_SMBEXIT(tctx)) {
+ fname = BASEDIR "\\test_exit.txt";
+ fnum = smbcli_open(tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+ torture_assert(tctx,(fnum != -1), talloc_asprintf(tctx,
+ "Failed to reopen %s - %s\n",
+ fname, smbcli_errstr(tree)));
+
+ io.lockx.level = RAW_LOCK_LOCKX;
+ io.lockx.in.file.fnum = fnum;
+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
+ io.lockx.in.timeout = 0;
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ lock[0].pid = session->pid;
+ lock[0].offset = 100;
+ lock[0].count = 10;
+ io.lockx.in.locks = &lock[0];
+ status = smb_raw_lock(tree, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
- io.lockx.in.timeout = 10000;
- t = time(NULL);
- req = smb_raw_lock_send(tree, &io);
- torture_assert(tctx,(req != NULL), talloc_asprintf(tctx,
- "Failed to setup timed lock (%s)\n", __location__));
+ io.lockx.in.ulock_cnt = 0;
+ io.lockx.in.lock_cnt = 1;
+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
+ io.lockx.in.timeout = 0;
+ status = smb_raw_lock(tree, &io);
+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
+
+ io.lockx.in.timeout = 10000;
+ t = time(NULL);
+ req = smb_raw_lock_send(tree, &io);
+ torture_assert(tctx,(req != NULL), talloc_asprintf(tctx,
+ "Failed to setup timed lock (%s)\n",
+ __location__));
+
+ status = smb_raw_exit(session);
+ CHECK_STATUS(status, NT_STATUS_OK);
- status = smb_raw_exit(session);
- CHECK_STATUS(status, NT_STATUS_OK);
+ status = smbcli_request_simple_recv(req);
+ if (TARGET_RETURNS_RANGE_NOT_LOCKED(tctx))
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ else
+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
- status = smbcli_request_simple_recv(req);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
-
- torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx,
- "lock cancel by exit was not immediate (%s)\n", __location__));
+ torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx,
+ "lock cancel by exit was not immediate (%s)\n",
+ __location__));
+ }
+ else {
+ torture_comment(tctx,
+ " skipping test, SMBExit not supported\n");
+ }
torture_comment(tctx, "testing cancel by ulogoff\n");
fname = BASEDIR "\\test_ulogoff.txt";
@@ -894,15 +912,20 @@ static bool test_async(struct torture_context *tctx,
CHECK_STATUS(status, NT_STATUS_OK);
status = smbcli_request_simple_recv(req);
- if (NT_STATUS_EQUAL(NT_STATUS_FILE_LOCK_CONFLICT, status)) {
- torture_result(tctx, TORTURE_FAIL,
- "lock not canceled by ulogoff - %s (ignored because of vfs_vifs fails it)\n",
- nt_errstr(status));
- smb_tree_disconnect(tree);
- smb_raw_exit(session);
- goto done;
+ if (TARGET_RETURNS_RANGE_NOT_LOCKED(tctx)) {
+ if (NT_STATUS_EQUAL(NT_STATUS_FILE_LOCK_CONFLICT, status)) {
+ torture_result(tctx, TORTURE_FAIL,
+ "lock not canceled by ulogoff - %s "
+ "(ignored because of vfs_vifs fails it)\n",
+ nt_errstr(status));
+ smb_tree_disconnect(tree);
+ smb_raw_exit(session);
+ goto done;
+ }
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ } else {
+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
}
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx,
"lock cancel by ulogoff was not immediate (%s)\n", __location__));
@@ -942,7 +965,10 @@ static bool test_async(struct torture_context *tctx,
CHECK_STATUS(status, NT_STATUS_OK);
status = smbcli_request_simple_recv(req);
- CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ if (TARGET_RETURNS_RANGE_NOT_LOCKED(tctx))
+ CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
+ else
+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
torture_assert(tctx,!(time(NULL) > t+2), talloc_asprintf(tctx,
"lock cancel by tdis was not immediate (%s)\n", __location__));
diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c
index 8c4311b530..e37fd8e09a 100644
--- a/source4/torture/raw/open.c
+++ b/source4/torture/raw/open.c
@@ -1879,6 +1879,203 @@ done:
return ret;
}
+/**
+ * Test what happens when trying to open a file with directory parameters and
+ * vice-versa. Also test that NTCREATEX_OPTIONS_DIRECTORY is treated as
+ * mandatory and FILE_ATTRIBUTE_DIRECTORY is advisory for directory
+ * creation/opening.
+ */
+static bool test_ntcreatexdir(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ union smb_open io;
+ union smb_fileinfo finfo;
+ const char *fname = BASEDIR "\\torture_ntcreatex.txt";
+ const char *dname = BASEDIR "\\torture_ntcreatex_dir";
+ NTSTATUS status, expected_status;
+ bool ret = true;
+ int i;
+ uint32_t access_mask = 0;
+
+ struct {
+ uint32_t open_disp;
+ uint32_t file_attr;
+ uint32_t create_options;
+ NTSTATUS correct_status;
+ } open_funcs[] = {
+ { NTCREATEX_DISP_SUPERSEDE, 0, NTCREATEX_OPTIONS_DIRECTORY,
+ NT_STATUS_INVALID_PARAMETER },
+ { NTCREATEX_DISP_OPEN, 0, NTCREATEX_OPTIONS_DIRECTORY,
+ NT_STATUS_OBJECT_NAME_NOT_FOUND },
+ { NTCREATEX_DISP_CREATE, 0, NTCREATEX_OPTIONS_DIRECTORY,
+ NT_STATUS_OK },
+ { NTCREATEX_DISP_OPEN_IF, 0, NTCREATEX_OPTIONS_DIRECTORY,
+ NT_STATUS_OK },
+ { NTCREATEX_DISP_OVERWRITE, 0, NTCREATEX_OPTIONS_DIRECTORY,
+ NT_STATUS_INVALID_PARAMETER },
+ { NTCREATEX_DISP_OVERWRITE_IF, 0, NTCREATEX_OPTIONS_DIRECTORY,
+ NT_STATUS_INVALID_PARAMETER },
+ { NTCREATEX_DISP_SUPERSEDE, FILE_ATTRIBUTE_DIRECTORY, 0,
+ NT_STATUS_OK },
+ { NTCREATEX_DISP_OPEN, FILE_ATTRIBUTE_DIRECTORY, 0,
+ NT_STATUS_OBJECT_NAME_NOT_FOUND },
+ { NTCREATEX_DISP_CREATE, FILE_ATTRIBUTE_DIRECTORY, 0,
+ NT_STATUS_OK },
+ { NTCREATEX_DISP_OPEN_IF, FILE_ATTRIBUTE_DIRECTORY, 0,
+ NT_STATUS_OK },
+ { NTCREATEX_DISP_OVERWRITE, FILE_ATTRIBUTE_DIRECTORY, 0,
+ NT_STATUS_OBJECT_NAME_NOT_FOUND },
+ { NTCREATEX_DISP_OVERWRITE_IF, FILE_ATTRIBUTE_DIRECTORY, 0,
+ NT_STATUS_OK },
+
+ };
+
+ if (!torture_setup_dir(cli, BASEDIR)) {
+ return false;
+ }
+
+ /* setup some base params. */
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
+ io.ntcreatex.in.root_fid.fnum = 0;
+ io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname;
+
+ /*
+ * Test the validity checking for create dispositions, which is done
+ * against the requested parameters rather than what's actually on
+ * disk.
+ */
+ for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
+ io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
+ io.ntcreatex.in.file_attr = open_funcs[i].file_attr;
+ io.ntcreatex.in.create_options = open_funcs[i].create_options;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s) incorrect status %s should be %s "
+ "(i=%d open_disp=%d)\n",
+ __location__, nt_errstr(status),
+ nt_errstr(open_funcs[i].correct_status),
+ i, (int)open_funcs[i].open_disp);
+ ret = false;
+ }
+ /* Close and delete the file. */
+ if (NT_STATUS_IS_OK(status)) {
+ if (open_funcs[i].create_options != 0) {
+ /* out attrib should be a directory. */
+ torture_assert_int_equal(tctx,
+ io.ntcreatex.out.attrib,
+ FILE_ATTRIBUTE_DIRECTORY, "should have "
+ "created a directory");
+
+ smbcli_close(cli->tree,
+ io.ntcreatex.out.file.fnum);
+
+ /* Make sure unlink fails. */
+ status = smbcli_unlink(cli->tree, fname);
+ torture_assert_ntstatus_equal(tctx, status,
+ NT_STATUS_FILE_IS_A_DIRECTORY,
+ "unlink should fail for a directory");
+
+ status = smbcli_rmdir(cli->tree, fname);
+ torture_assert_ntstatus_ok(tctx, status,
+ "rmdir failed");
+ } else {
+ torture_assert_int_equal(tctx,
+ io.ntcreatex.out.attrib,
+ FILE_ATTRIBUTE_ARCHIVE, "should not have "
+ "created a directory");
+
+ smbcli_close(cli->tree,
+ io.ntcreatex.out.file.fnum);
+
+ /* Make sure rmdir fails. */
+ status = smbcli_rmdir(cli->tree, fname);
+ torture_assert_ntstatus_equal(tctx, status,
+ NT_STATUS_NOT_A_DIRECTORY,
+ "rmdir should fail for a file");
+
+ status = smbcli_unlink(cli->tree, fname);
+ torture_assert_ntstatus_ok(tctx, status,
+ "unlink failed");
+ }
+ }
+ }
+
+ /* Create a file. */
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "Failed to create file.");
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+ /* Try and open the file with file_attr_dir and check the error. */
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+
+ status = smb_raw_open(cli->tree, tctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_DIRECTORY "
+ "doesn't produce a hard failure.");
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+ /* Try and open file with createx_option_dir and check the error. */
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+
+ status = smb_raw_open(cli->tree, tctx, &io);
+ torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_A_DIRECTORY,
+ "NTCREATEX_OPTIONS_DIRECTORY will a file from being opened.");
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+ /* Delete the file and move onto directory testing. */
+ smbcli_unlink(cli->tree, fname);
+
+ /* Now try some tests on a directory. */
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ io.ntcreatex.in.fname = dname;
+
+ status = smb_raw_open(cli->tree, tctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "Failed to create dir.");
+
+ /* out attrib should be a directory. */
+ torture_assert_int_equal(tctx, io.ntcreatex.out.attrib,
+ FILE_ATTRIBUTE_DIRECTORY, "should have created a directory");
+
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+ /* Try and open it with normal attr and check the error. */
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+
+ status = smb_raw_open(cli->tree, tctx, &io);
+ torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_NORMAL "
+ "doesn't produce a hard failure.");
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+ /* Try and open it with file create_options and check the error. */
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
+
+ status = smb_raw_open(cli->tree, tctx, &io);
+ torture_assert_ntstatus_equal(tctx, status,
+ NT_STATUS_FILE_IS_A_DIRECTORY,
+ "NTCREATEX_OPTIONS_NON_DIRECTORY_FILE should be returned ");
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+
+done:
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+ smbcli_deltree(cli->tree, BASEDIR);
+
+ return ret;
+}
/* basic testing of all RAW_OPEN_* calls
*/
@@ -1902,6 +2099,7 @@ struct torture_suite *torture_raw_open(TALLOC_CTX *mem_ctx)
torture_suite_add_1smb_test(suite, "OPENX-OVER-DIR", test_openx_over_dir);
torture_suite_add_1smb_test(suite, "OPEN-FOR-DELETE", test_open_for_delete);
torture_suite_add_1smb_test(suite, "OPENDISP-DIR", test_ntcreatex_opendisp_dir);
+ torture_suite_add_1smb_test(suite, "NTCREATEDIR", test_ntcreatexdir);
return suite;
}