Exemplo n.º 1
0
/*
  test SMB2 open with a leading slash on the path.
  Trying to create a directory with a leading slash
  should give NT_STATUS_INVALID_PARAMETER error
*/
static bool test_smb2_leading_slash(struct torture_context *tctx,
                                    struct smb2_tree *tree)
{
    union smb_open io;
    const char *dnameslash = "\\"DNAME;
    NTSTATUS status;
    bool ret = true;

    torture_comment(tctx,
                    "Trying to create a directory with leading slash on path\n");
    smb2_deltree(tree, dnameslash);

    ZERO_STRUCT(io.smb2);
    io.generic.level = RAW_OPEN_SMB2;
    io.smb2.in.oplock_level = 0;
    io.smb2.in.desired_access = SEC_RIGHTS_DIR_ALL;
    io.smb2.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
    io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
                              NTCREATEX_SHARE_ACCESS_WRITE |
                              NTCREATEX_SHARE_ACCESS_DELETE;
    io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    io.smb2.in.fname = dnameslash;

    status = smb2_create(tree, tree, &(io.smb2));
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    smb2_deltree(tree, dnameslash);
    return ret;
}
Exemplo n.º 2
0
/* basic testing of all SMB2 getinfo levels
*/
bool torture_smb2_getinfo(struct torture_context *torture)
{
	TALLOC_CTX *mem_ctx = talloc_new(NULL);
	struct smb2_tree *tree;
	bool ret = true;
	NTSTATUS status;

	if (!torture_smb2_connection(torture, &tree)) {
		return false;
	}

	smb2_deltree(tree, FNAME);
	smb2_deltree(tree, DNAME);

	status = torture_setup_complex_file(tree, FNAME);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}
	torture_setup_complex_file(tree, FNAME ":streamtwo");
	status = torture_setup_complex_dir(tree, DNAME);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}
	torture_setup_complex_file(tree, DNAME ":streamtwo");

	ret &= torture_smb2_fileinfo(torture, tree);
	ret &= torture_smb2_fsinfo(tree);
	ret &= torture_smb2_buffercheck(tree);

	talloc_free(mem_ctx);

	return ret;
}
Exemplo n.º 3
0
/*
   basic testing of change notify on directories
*/
static bool torture_smb2_notify_disabled(struct torture_context *torture,
					 struct smb2_tree *tree1)
{
	bool ret = true;
	NTSTATUS status;
	union smb_notify notify;
	union smb_open io;
	struct smb2_handle h1;
	struct smb2_request *req;

	torture_comment(torture, "TESTING CHANGE NOTIFY DISABLED\n");

	smb2_deltree(tree1, BASEDIR);
	smb2_util_rmdir(tree1, BASEDIR);
	/*
	  get a handle on the directory
	*/
	ZERO_STRUCT(io.smb2);
	io.generic.level = RAW_OPEN_SMB2;
	io.smb2.in.create_flags = 0;
	io.smb2.in.desired_access = SEC_FILE_ALL;
	io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
	io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
				NTCREATEX_SHARE_ACCESS_WRITE;
	io.smb2.in.alloc_size = 0;
	io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
	io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
	io.smb2.in.security_flags = 0;
	io.smb2.in.fname = BASEDIR;

	status = smb2_create(tree1, torture, &(io.smb2));
	torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OK,
					   ret, done, "smb2_create");
	h1 = io.smb2.out.file.handle;

	ZERO_STRUCT(notify.smb2);
	notify.smb2.level = RAW_NOTIFY_SMB2;
	notify.smb2.in.buffer_size = 1000;
	notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
	notify.smb2.in.file.handle = h1;
	notify.smb2.in.recursive = true;

	req = smb2_notify_send(tree1, &(notify.smb2));
	status = smb2_notify_recv(req, torture, &(notify.smb2));
	torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_NOT_IMPLEMENTED,
					   ret, done, "smb2_notify_recv");

	status = smb2_util_close(tree1, h1);
	torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OK,
					   ret, done, "smb2_create");

done:
	smb2_deltree(tree1, BASEDIR);
	return ret;
}
Exemplo n.º 4
0
static NTSTATUS populate_tree(struct torture_context *tctx,
			      TALLOC_CTX *mem_ctx,
			      struct smb2_tree *tree,
			      struct file_elem *files,
			      int nfiles,
			      struct smb2_handle *h_out)
{
	struct smb2_create create;
	char **strs = NULL;
	NTSTATUS status;
	bool ret;
	int i;

	smb2_deltree(tree, DNAME);

	ZERO_STRUCT(create);
	create.in.desired_access = SEC_RIGHTS_DIR_ALL;
	create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
	create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
				 NTCREATEX_SHARE_ACCESS_WRITE |
				 NTCREATEX_SHARE_ACCESS_DELETE;
	create.in.create_disposition = NTCREATEX_DISP_CREATE;
	create.in.fname = DNAME;

	status = smb2_create(tree, mem_ctx, &create);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");
	*h_out = create.out.file.handle;

	ZERO_STRUCT(create);
	create.in.desired_access = SEC_RIGHTS_FILE_ALL;
	create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
	create.in.create_disposition = NTCREATEX_DISP_CREATE;

	strs = generate_unique_strs(mem_ctx, 8, nfiles);
	if (strs == NULL) {
		status = NT_STATUS_OBJECT_NAME_COLLISION;
		goto done;
	}
	for (i = 0; i < nfiles; i++) {
		files[i].name = strs[i];
		create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
		    DNAME, files[i].name);
		status = smb2_create(tree, mem_ctx, &create);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");
		smb2_util_close(tree, create.out.file.handle);
	}
 done:
	return status;
}
Exemplo n.º 5
0
/**
 * test renaming after reauth.
 * compare security descriptors before and after rename/reauth
 */
bool test_session_reauth5(struct torture_context *tctx, struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char dname[256];
	char fname[256];
	char fname2[256];
	struct smb2_handle _dh1;
	struct smb2_handle *dh1 = NULL;
	struct smb2_handle _h1;
	struct smb2_handle *h1 = NULL;
	struct smb2_create io1;
	bool ret = true;
	bool ok;
	union smb_fileinfo qfinfo;
	union smb_setfileinfo sfinfo;
	struct cli_credentials *anon_creds = NULL;
	uint32_t secinfo_flags = SECINFO_OWNER
				| SECINFO_GROUP
				| SECINFO_DACL
				| SECINFO_PROTECTED_DACL
				| SECINFO_UNPROTECTED_DACL;
	struct security_descriptor *f_sd1;
	struct security_descriptor *d_sd1 = NULL;
	struct security_ace ace;
	struct dom_sid *extra_sid;

	/* Add some random component to the file name. */
	snprintf(dname, 256, "session_reauth5_%s.d",
		 generate_random_str(tctx, 8));
	snprintf(fname, 256, "%s\\file.dat", dname);

	ok = smb2_util_setup_dir(tctx, tree, dname);
	CHECK_VAL(ok, true);

	status = torture_smb2_testdir(tree, dname, &_dh1);
	CHECK_STATUS(status, NT_STATUS_OK);
	dh1 = &_dh1;

	smb2_oplock_create_share(&io1, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));

	status = smb2_create(tree, mem_ctx, &io1);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h1 = io1.out.file.handle;
	h1 = &_h1;
	CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));

	/* get the security descriptor */

	ZERO_STRUCT(qfinfo);

	qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	qfinfo.query_secdesc.in.file.handle = _h1;
	qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

	status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	f_sd1 = qfinfo.query_secdesc.out.sd;

	/* re-authenticate as anonymous */

	anon_creds = cli_credentials_init_anon(mem_ctx);
	torture_assert(tctx, (anon_creds != NULL), "talloc error");

	status = smb2_session_setup_spnego(tree->session,
					   anon_creds,
					   0 /* previous_session_id */);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* try to rename the file: fails */

	snprintf(fname2, 256, "%s\\file2.dat", dname);

	smb2_util_unlink(tree, fname2);

	ZERO_STRUCT(sfinfo);
	sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
	sfinfo.rename_information.in.file.handle = _h1;
	sfinfo.rename_information.in.overwrite = true;
	sfinfo.rename_information.in.new_name = fname2;

	status = smb2_setinfo_file(tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

	/* re-authenticate as original user again */

	status = smb2_session_setup_spnego(tree->session,
					   cmdline_credentials,
					   0 /* previous_session_id */);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* give full access on the file to anonymous */

	extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);

	ZERO_STRUCT(ace);
	ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
	ace.flags = 0;
	ace.access_mask = SEC_RIGHTS_FILE_ALL;
	ace.trustee = *extra_sid;

	status = security_descriptor_dacl_add(f_sd1, &ace);
	CHECK_STATUS(status, NT_STATUS_OK);

	ZERO_STRUCT(sfinfo);
	sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
	sfinfo.set_secdesc.in.file.handle = _h1;
	sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
	sfinfo.set_secdesc.in.sd = f_sd1;

	status = smb2_setinfo_file(tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* re-get the security descriptor */

	ZERO_STRUCT(qfinfo);

	qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	qfinfo.query_secdesc.in.file.handle = _h1;
	qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

	status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* re-authenticate as anonymous - again */

	anon_creds = cli_credentials_init_anon(mem_ctx);
	torture_assert(tctx, (anon_creds != NULL), "talloc error");

	status = smb2_session_setup_spnego(tree->session,
					   anon_creds,
					   0 /* previous_session_id */);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* try to rename the file: fails */

	ZERO_STRUCT(sfinfo);
	sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
	sfinfo.rename_information.in.file.handle = _h1;
	sfinfo.rename_information.in.overwrite = true;
	sfinfo.rename_information.in.new_name = fname2;

	status = smb2_setinfo_file(tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

	/* give full access on the parent dir to anonymous */

	ZERO_STRUCT(qfinfo);

	qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	qfinfo.query_secdesc.in.file.handle = _dh1;
	qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

	status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	d_sd1 = qfinfo.query_secdesc.out.sd;

	ZERO_STRUCT(ace);
	ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
	ace.flags = 0;
	ace.access_mask = SEC_RIGHTS_FILE_ALL;
	ace.trustee = *extra_sid;

	status = security_descriptor_dacl_add(d_sd1, &ace);
	CHECK_STATUS(status, NT_STATUS_OK);

	ZERO_STRUCT(sfinfo);
	sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
	sfinfo.set_secdesc.in.file.handle = _dh1;
	sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
	sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
	sfinfo.set_secdesc.in.sd = d_sd1;

	status = smb2_setinfo_file(tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	ZERO_STRUCT(qfinfo);

	qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	qfinfo.query_secdesc.in.file.handle = _dh1;
	qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

	status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	smb2_util_close(tree, _dh1);
	dh1 = NULL;

	/* try to rename the file: still fails */

	ZERO_STRUCT(sfinfo);
	sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
	sfinfo.rename_information.in.file.handle = _h1;
	sfinfo.rename_information.in.overwrite = true;
	sfinfo.rename_information.in.new_name = fname2;

	status = smb2_setinfo_file(tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

	/* re-authenticate as original user - again */

	status = smb2_session_setup_spnego(tree->session,
					   cmdline_credentials,
					   0 /* previous_session_id */);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* rename the file - for verification that it works */

	ZERO_STRUCT(sfinfo);
	sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
	sfinfo.rename_information.in.file.handle = _h1;
	sfinfo.rename_information.in.overwrite = true;
	sfinfo.rename_information.in.new_name = fname2;

	status = smb2_setinfo_file(tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* closs the file, check it is gone and reopen under the new name */

	smb2_util_close(tree, _h1);

	ZERO_STRUCT(io1);

	smb2_generic_create_share(&io1,
				  NULL /* lease */, false /* dir */,
				  fname,
				  NTCREATEX_DISP_OPEN,
				  smb2_util_share_access(""),
				  smb2_util_oplock_level("b"),
				  0 /* leasekey */, 0 /* leasestate */);

	status = smb2_create(tree, mem_ctx, &io1);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	ZERO_STRUCT(io1);

	smb2_generic_create_share(&io1,
				  NULL /* lease */, false /* dir */,
				  fname2,
				  NTCREATEX_DISP_OPEN,
				  smb2_util_share_access(""),
				  smb2_util_oplock_level("b"),
				  0 /* leasekey */, 0 /* leasestate */);

	status = smb2_create(tree, mem_ctx, &io1);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h1 = io1.out.file.handle;
	h1 = &_h1;
	CHECK_CREATED(&io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));

	/* try to access the file via the old handle */

	ZERO_STRUCT(qfinfo);

	qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	qfinfo.query_secdesc.in.file.handle = _h1;
	qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

	status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

done:
	if (dh1 != NULL) {
		smb2_util_close(tree, *dh1);
	}
	if (h1 != NULL) {
		smb2_util_close(tree, *h1);
	}

	smb2_deltree(tree, dname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Exemplo n.º 6
0
static bool test_smb2_open_for_delete(struct torture_context *tctx,
                                      struct smb2_tree *tree)
{
    union smb_open io;
    union smb_fileinfo finfo;
    const char *fname = DNAME "\\torture_open_for_delete.txt";
    NTSTATUS status;
    struct smb2_handle h, h1;
    bool ret = true;

    torture_comment(tctx,
                    "Checking SMB2_OPEN for delete on a readonly file.\n");
    smb2_util_unlink(tree, fname);
    smb2_deltree(tree, fname);

    status = torture_smb2_testdir(tree, DNAME, &h);
    CHECK_STATUS(status, NT_STATUS_OK);

    /* reasonable default parameters */
    ZERO_STRUCT(io.smb2);
    io.generic.level = RAW_OPEN_SMB2;
    io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
    io.smb2.in.alloc_size = 0;
    io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    io.smb2.in.file_attributes = FILE_ATTRIBUTE_READONLY;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.smb2.in.create_options = 0;
    io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    io.smb2.in.security_flags = 0;
    io.smb2.in.fname = fname;

    /* Create the readonly file. */

    status = smb2_create(tree, tctx, &(io.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);
    h1 = io.smb2.out.file.handle;

    CHECK_VAL(io.smb2.out.oplock_level, 0);
    io.smb2.in.create_options = 0;
    CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
    CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
    smb2_util_close(tree, h1);

    /* Now try and open for delete only - should succeed. */
    io.smb2.in.desired_access = SEC_STD_DELETE;
    io.smb2.in.file_attributes = 0;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
                              NTCREATEX_SHARE_ACCESS_WRITE |
                              NTCREATEX_SHARE_ACCESS_DELETE;
    io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    status = smb2_create(tree, tctx, &(io.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);

    smb2_util_unlink(tree, fname);

    smb2_util_close(tree, h1);
    smb2_util_unlink(tree, fname);
    smb2_deltree(tree, DNAME);

    return ret;
}
Exemplo n.º 7
0
static bool test_smb2_open_multi(struct torture_context *tctx,
                                 struct smb2_tree *tree)
{
    const char *fname = "test_oplock.dat";
    NTSTATUS status;
    bool ret = true;
    union smb_open io;
    struct smb2_tree **trees;
    struct smb2_request **requests;
    union smb_open *ios;
    int i, num_files = 3;
    int num_ok = 0;
    int num_collision = 0;

    torture_comment(tctx,
                    "Testing SMB2 Open with multiple connections\n");
    trees = talloc_array(tctx, struct smb2_tree *, num_files);
    requests = talloc_array(tctx, struct smb2_request *, num_files);
    ios = talloc_array(tctx, union smb_open, num_files);
    if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
            (ios == NULL)) {
        torture_comment(tctx, ("talloc failed\n"));
        ret = false;
        goto done;
    }

    tree->session->transport->options.request_timeout = 60;

    for (i=0; i<num_files; i++) {
        if (!torture_smb2_connection(tctx, &(trees[i]))) {
            torture_comment(tctx,
                            "Could not open %d'th connection\n", i);
            ret = false;
            goto done;
        }
        trees[i]->session->transport->options.request_timeout = 60;
    }

    /* cleanup */
    smb2_util_unlink(tree, fname);

    /*
      base ntcreatex parms
    */
    ZERO_STRUCT(io.smb2);
    io.generic.level = RAW_OPEN_SMB2;
    io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    io.smb2.in.alloc_size = 0;
    io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
                              NTCREATEX_SHARE_ACCESS_WRITE|
                              NTCREATEX_SHARE_ACCESS_DELETE;
    io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.smb2.in.create_options = 0;
    io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    io.smb2.in.security_flags = 0;
    io.smb2.in.fname = fname;
    io.smb2.in.create_flags = 0;

    for (i=0; i<num_files; i++) {
        ios[i] = io;
        requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
        if (requests[i] == NULL) {
            torture_comment(tctx,
                            "could not send %d'th request\n", i);
            ret = false;
            goto done;
        }
    }

    torture_comment(tctx, "waiting for replies\n");
    while (1) {
        bool unreplied = false;
        for (i=0; i<num_files; i++) {
            if (requests[i] == NULL) {
                continue;
            }
            if (requests[i]->state < SMB2_REQUEST_DONE) {
                unreplied = true;
                break;
            }
            status = smb2_create_recv(requests[i], tctx,
                                      &(ios[i].smb2));

            torture_comment(tctx,
                            "File %d returned status %s\n", i,
                            nt_errstr(status));

            if (NT_STATUS_IS_OK(status)) {
                num_ok += 1;
            }

            if (NT_STATUS_EQUAL(status,
                                NT_STATUS_OBJECT_NAME_COLLISION)) {
                num_collision += 1;
            }

            requests[i] = NULL;
        }
        if (!unreplied) {
            break;
        }

        if (event_loop_once(tctx->ev) != 0) {
            torture_comment(tctx, "event_loop_once failed\n");
            ret = false;
            goto done;
        }
    }

    if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
        ret = false;
    }
done:
    smb2_deltree(tree, fname);

    return ret;
}
Exemplo n.º 8
0
static bool test_smb2_open_brlocked(struct torture_context *tctx,
                                    struct smb2_tree *tree)
{
    union smb_open io, io1;
    union smb_lock io2;
    struct smb2_lock_element lock[1];
    const char *fname = DNAME "\\torture_ntcreatex.txt";
    NTSTATUS status;
    bool ret = true;
    struct smb2_handle h;
    char b = 42;

    torture_comment(tctx,
                    "Testing SMB2 open with a byte range locked file\n");

    smb2_util_unlink(tree, fname);

    status = torture_smb2_testdir(tree, DNAME, &h);
    CHECK_STATUS(status, NT_STATUS_OK);

    ZERO_STRUCT(io.smb2);
    io.generic.level = RAW_OPEN_SMB2;
    io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
    io.smb2.in.desired_access = 0x2019f;
    io.smb2.in.alloc_size = 0;
    io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
                              NTCREATEX_SHARE_ACCESS_WRITE;
    io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    io.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
    io.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
    io.smb2.in.fname = fname;

    status = smb2_create(tree, tctx, &(io.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_util_write(tree, io.smb2.out.file.handle, &b, 0, 1);
    CHECK_STATUS(status, NT_STATUS_OK);

    ZERO_STRUCT(io2.smb2);
    io2.smb2.level = RAW_LOCK_SMB2;
    io2.smb2.in.file.handle = io.smb2.out.file.handle;
    io2.smb2.in.lock_count = 1;

    ZERO_STRUCT(lock);
    lock[0].offset = 0;
    lock[0].length = 1;
    lock[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
                    SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
    io2.smb2.in.locks = &lock[0];
    status = smb2_lock(tree, &(io2.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);

    ZERO_STRUCT(io1.smb2);
    io1.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
    io1.smb2.in.desired_access = 0x20196;
    io1.smb2.in.alloc_size = 0;
    io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
                               NTCREATEX_SHARE_ACCESS_WRITE;
    io1.smb2.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    io1.smb2.in.create_options = 0;
    io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
    io1.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
    io1.smb2.in.fname = fname;

    status = smb2_create(tree, tctx, &(io1.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);

    smb2_util_close(tree, io.smb2.out.file.handle);
    smb2_util_close(tree, io1.smb2.out.file.handle);
    smb2_util_unlink(tree, fname);
    smb2_deltree(tree, DNAME);

    return ret;
}
Exemplo n.º 9
0
/*
  test SMB2 open
*/
static bool test_smb2_open(struct torture_context *tctx,
                           struct smb2_tree *tree)
{
    union smb_open io;
    union smb_fileinfo finfo;
    const char *fname = DNAME "\\torture_ntcreatex.txt";
    const char *dname = DNAME "\\torture_ntcreatex.dir";
    NTSTATUS status;
    struct smb2_handle h, h1;
    bool ret = true;
    int i;
    struct {
        uint32_t create_disp;
        bool with_file;
        NTSTATUS correct_status;
    } open_funcs[] = {
        { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
        { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
        { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
        { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
        { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
        { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
        { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
        { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
        { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
        { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
        { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
        { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
        { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
        { 6,                            false, NT_STATUS_INVALID_PARAMETER },
    };

    torture_comment(tctx, "Checking SMB2 Open\n");

    smb2_util_unlink(tree, fname);
    smb2_util_rmdir(tree, dname);

    status = torture_smb2_testdir(tree, DNAME, &h);
    CHECK_STATUS(status, NT_STATUS_OK);

    ZERO_STRUCT(io.smb2);
    /* reasonable default parameters */
    io.generic.level = RAW_OPEN_SMB2;
    io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
    io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    io.smb2.in.alloc_size = 1024*1024;
    io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.smb2.in.create_options = 0;
    io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    io.smb2.in.security_flags = 0;
    io.smb2.in.fname = fname;

    /* test the create disposition */
    for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
        if (open_funcs[i].with_file) {
            io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
            status= smb2_create(tree, tctx, &(io.smb2));
            if (!NT_STATUS_IS_OK(status)) {
                torture_comment(tctx,
                                "Failed to create file %s status %s %d\n",
                                fname, nt_errstr(status), i);

                ret = false;
                goto done;
            }
            smb2_util_close(tree, io.smb2.out.file.handle);
        }
        io.smb2.in.create_disposition = open_funcs[i].create_disp;
        status = smb2_create(tree, tctx, &(io.smb2));
        if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
            torture_comment(tctx,
                            "(%s) incorrect status %s should be %s (i=%d "
                            "with_file=%d open_disp=%d)\n",
                            __location__, nt_errstr(status),
                            nt_errstr(open_funcs[i].correct_status),
                            i, (int)open_funcs[i].with_file,
                            (int)open_funcs[i].create_disp);

            ret = false;
            goto done;
        }
        if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
            smb2_util_close(tree, io.smb2.out.file.handle);
            smb2_util_unlink(tree, fname);
        }
    }

    /* basic field testing */
    io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;

    status = smb2_create(tree, tctx, &(io.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);
    h1 = io.smb2.out.file.handle;

    CHECK_VAL(io.smb2.out.oplock_level, 0);
    CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
    CHECK_NTTIME(io.smb2.out.create_time, create_time);
    CHECK_NTTIME(io.smb2.out.access_time, access_time);
    CHECK_NTTIME(io.smb2.out.write_time, write_time);
    CHECK_NTTIME(io.smb2.out.change_time, change_time);
    CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
    CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
    CHECK_ALL_INFO(io.smb2.out.size, size);

    /* check fields when the file already existed */
    smb2_util_close(tree, h1);
    smb2_util_unlink(tree, fname);

    status = smb2_create_complex_file(tree, fname, &h1);
    CHECK_STATUS(status, NT_STATUS_OK);

    smb2_util_close(tree, h1);

    io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    status = smb2_create(tree, tctx, &(io.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);
    h1 = io.smb2.out.file.handle;

    CHECK_VAL(io.smb2.out.oplock_level, 0);
    CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_EXISTED);
    CHECK_NTTIME(io.smb2.out.create_time, create_time);
    CHECK_NTTIME(io.smb2.out.access_time, access_time);
    CHECK_NTTIME(io.smb2.out.write_time, write_time);
    CHECK_NTTIME(io.smb2.out.change_time, change_time);
    CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
    CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
    CHECK_ALL_INFO(io.smb2.out.size, size);
    smb2_util_close(tree, h1);
    smb2_util_unlink(tree, fname);

    /* create a directory */
    io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    io.smb2.in.alloc_size = 0;
    io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    io.smb2.in.create_options = 0;
    io.smb2.in.fname = dname;
    fname = dname;

    smb2_util_rmdir(tree, fname);
    smb2_util_unlink(tree, fname);

    io.smb2.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
    io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
                              NTCREATEX_SHARE_ACCESS_WRITE;
    status = smb2_create(tree, tctx, &(io.smb2));
    CHECK_STATUS(status, NT_STATUS_OK);
    h1 = io.smb2.out.file.handle;

    CHECK_VAL(io.smb2.out.oplock_level, 0);
    CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
    CHECK_NTTIME(io.smb2.out.create_time, create_time);
    CHECK_NTTIME(io.smb2.out.access_time, access_time);
    CHECK_NTTIME(io.smb2.out.write_time, write_time);
    CHECK_NTTIME(io.smb2.out.change_time, change_time);
    CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
    CHECK_VAL(io.smb2.out.file_attr & ~FILE_ATTRIBUTE_NONINDEXED,
              FILE_ATTRIBUTE_DIRECTORY);
    CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
    CHECK_ALL_INFO(io.smb2.out.size, size);
    CHECK_VAL(io.smb2.out.size, 0);
    CHECK_VAL(io.smb2.out.alloc_size, 0);
    smb2_util_unlink(tree, fname);

done:
    smb2_util_close(tree, h1);
    smb2_util_unlink(tree, fname);
    smb2_deltree(tree, DNAME);
    return ret;
}
Exemplo n.º 10
0
/*
  try creating with acls
 */
static bool test_create_acl_ext(struct torture_context *tctx, struct smb2_tree *tree, bool test_dir)
{
    bool ret = true;
    struct smb2_create io;
    NTSTATUS status;
    struct security_ace ace;
    struct security_descriptor *sd;
    struct dom_sid *test_sid;
    union smb_fileinfo q = {};
    uint32_t attrib =
        FILE_ATTRIBUTE_HIDDEN |
        FILE_ATTRIBUTE_SYSTEM |
        (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
    NTSTATUS (*delete_func)(struct smb2_tree *, const char *) =
        test_dir ? smb2_util_rmdir : smb2_util_unlink;

    smb2_deltree(tree, FNAME);

    ZERO_STRUCT(io);
    io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
    io.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.in.share_access =
        NTCREATEX_SHARE_ACCESS_DELETE |
        NTCREATEX_SHARE_ACCESS_READ |
        NTCREATEX_SHARE_ACCESS_WRITE;
    io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT | 0x00200000 |
                           (test_dir ?  NTCREATEX_OPTIONS_DIRECTORY :
                            (NTCREATEX_OPTIONS_NON_DIRECTORY_FILE));

    io.in.fname = FNAME;

    torture_comment(tctx, "basic create\n");

    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    q.query_secdesc.in.file.handle = io.out.file.handle;
    q.query_secdesc.in.secinfo_flags =
        SECINFO_OWNER |
        SECINFO_GROUP |
        SECINFO_DACL;
    status = smb2_getinfo_file(tree, tctx, &q);
    CHECK_STATUS(status, NT_STATUS_OK);
    sd = q.query_secdesc.out.sd;

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "adding a new ACE\n");
    test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);

    ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
    ace.flags = 0;
    ace.access_mask = SEC_STD_ALL;
    ace.trustee = *test_sid;

    status = security_descriptor_dacl_add(sd, &ace);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating a file with an initial ACL\n");

    io.in.sec_desc = sd;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating with attributes\n");

    io.in.sec_desc = NULL;
    io.in.file_attributes = attrib;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating with attributes and ACL\n");

    io.in.sec_desc = sd;
    io.in.file_attributes = attrib;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
    FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating with attributes, ACL and owner\n");
    sd = security_descriptor_dacl_create(tctx,
                                         0, SID_WORLD, SID_BUILTIN_USERS,
                                         SID_WORLD,
                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
                                         0,
                                         NULL);

    io.in.sec_desc = sd;
    io.in.file_attributes = attrib;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
    FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));

done:
    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    return ret;
}
Exemplo n.º 11
0
static bool test_find(struct torture_context *tctx,
		      struct smb2_tree *tree)
{
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	struct smb2_handle h;
	struct smb2_find f;
	union smb_search_data *d;
	struct file_elem files[NFILES] = {};
	NTSTATUS status;
	bool ret = true;
	unsigned int count;
	int i, j, file_count = 0;

	status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);

	ZERO_STRUCT(f);
	f.in.file.handle	= h;
	f.in.pattern		= "*";
	f.in.continue_flags	= SMB2_CONTINUE_FLAG_SINGLE;
	f.in.max_response_size	= 0x100;
	f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;

	do {
		status = smb2_find_level(tree, tree, &f, &count, &d);
		if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
			break;
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

		for (i = 0; i < count; i++) {
			bool expected;
			const char *found = d[i].both_directory_info.name.s;

			if (!strcmp(found, ".") || !strcmp(found, ".."))
				continue;

			expected = false;
			for (j = 0; j < NFILES; j++) {
				if (!strcmp(files[j].name, found)) {
					files[j].found = true;
					expected = true;
					break;
				}
			}

			if (expected)
				continue;

			torture_result(tctx, TORTURE_FAIL,
			    "(%s): didn't expect %s\n",
			    __location__, found);
			ret = false;
			goto done;
		}

		file_count = file_count + i;
		f.in.continue_flags = 0;
		f.in.max_response_size	= 4096;
	} while (count != 0);

	torture_assert_int_equal_goto(tctx, file_count, NFILES + 2, ret, done,
				      "");

	for (i = 0; i < NFILES; i++) {
		if (files[j].found)
			continue;

		torture_result(tctx, TORTURE_FAIL,
		    "(%s): expected to find %s, but didn't\n",
		    __location__, files[j].name);
		ret = false;
		goto done;
	}

 done:
	smb2_deltree(tree, DNAME);
	talloc_free(mem_ctx);

	return ret;
}
Exemplo n.º 12
0
/*
  test some interesting combinations found by gentest
 */
static bool test_create_gentest(struct torture_context *tctx, struct smb2_tree *tree)
{
    struct smb2_create io;
    NTSTATUS status;
    uint32_t access_mask, file_attributes_set;
    uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
    uint32_t not_a_directory_mask, unexpected_mask;
    union smb_fileinfo q;

    ZERO_STRUCT(io);
    io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
    io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    io.in.share_access =
        NTCREATEX_SHARE_ACCESS_DELETE|
        NTCREATEX_SHARE_ACCESS_READ|
        NTCREATEX_SHARE_ACCESS_WRITE;
    io.in.create_options = 0;
    io.in.fname = FNAME;

    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    io.in.create_options = 0xF0000000;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    io.in.create_options = 0;

    io.in.file_attributes = FILE_ATTRIBUTE_DEVICE;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    io.in.create_disposition = NTCREATEX_DISP_OPEN;
    io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    io.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.in.desired_access = 0x08000000;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

    io.in.desired_access = 0x04000000;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

    io.in.file_attributes = 0;
    io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    ok_mask = 0;
    not_supported_mask = 0;
    invalid_parameter_mask = 0;
    not_a_directory_mask = 0;
    unexpected_mask = 0;
    {
        int i;
        for (i=0; i<32; i++) {
            io.in.create_options = 1<<i;
            if (io.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
                continue;
            }
            status = smb2_create(tree, tctx, &io);
            if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
                not_supported_mask |= 1<<i;
            } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
                invalid_parameter_mask |= 1<<i;
            } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
                not_a_directory_mask |= 1<<i;
            } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
                ok_mask |= 1<<i;
                status = smb2_util_close(tree, io.out.file.handle);
                CHECK_STATUS(status, NT_STATUS_OK);
            } else {
                unexpected_mask |= 1<<i;
                torture_comment(tctx,
                                "create option 0x%08x returned %s\n",
                                1<<i, nt_errstr(status));
            }
        }
    }
    io.in.create_options = 0;

    CHECK_EQUAL(ok_mask,                0x00efcf7e);
    CHECK_EQUAL(not_a_directory_mask,   0x00000001);
    CHECK_EQUAL(not_supported_mask,     0x00102080);
    CHECK_EQUAL(invalid_parameter_mask, 0xff000000);
    CHECK_EQUAL(unexpected_mask,        0x00000000);

    io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    io.in.file_attributes = 0;
    access_mask = 0;
    {
        int i;
        for (i=0; i<32; i++) {
            io.in.desired_access = 1<<i;
            status = smb2_create(tree, tctx, &io);
            if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
                    NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
                access_mask |= io.in.desired_access;
            } else {
                CHECK_STATUS(status, NT_STATUS_OK);
                status = smb2_util_close(tree, io.out.file.handle);
                CHECK_STATUS(status, NT_STATUS_OK);
            }
        }
    }

    if (TARGET_IS_WIN7(tctx)) {
        CHECK_EQUAL(access_mask, 0x0de0fe00);
    } else if (torture_setting_bool(tctx, "samba4", false)) {
        CHECK_EQUAL(access_mask, 0x0cf0fe00);
    } else {
        CHECK_EQUAL(access_mask, 0x0df0fe00);
    }

    io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
    io.in.file_attributes = 0;
    ok_mask = 0;
    invalid_parameter_mask = 0;
    unexpected_mask = 0;
    file_attributes_set = 0;
    {
        int i;
        for (i=0; i<32; i++) {
            io.in.file_attributes = 1<<i;
            if (io.in.file_attributes & FILE_ATTRIBUTE_ENCRYPTED) {
                continue;
            }
            smb2_deltree(tree, FNAME);
            status = smb2_create(tree, tctx, &io);
            if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
                invalid_parameter_mask |= 1<<i;
            } else if (NT_STATUS_IS_OK(status)) {
                uint32_t expected;
                ok_mask |= 1<<i;

                expected = (io.in.file_attributes | FILE_ATTRIBUTE_ARCHIVE) & 0x00005127;
                CHECK_EQUAL(io.out.file_attr, expected);
                file_attributes_set |= io.out.file_attr;

                status = smb2_util_close(tree, io.out.file.handle);
                CHECK_STATUS(status, NT_STATUS_OK);
            } else {
                unexpected_mask |= 1<<i;
                torture_comment(tctx,
                                "file attribute 0x%08x returned %s\n",
                                1<<i, nt_errstr(status));
            }
        }
    }

    CHECK_EQUAL(ok_mask,                0x00003fb7);
    CHECK_EQUAL(invalid_parameter_mask, 0xffff8048);
    CHECK_EQUAL(unexpected_mask,        0x00000000);
    CHECK_EQUAL(file_attributes_set,    0x00001127);

    smb2_deltree(tree, FNAME);

    /*
     * Standalone servers doesn't support encryption
     */
    io.in.file_attributes = FILE_ATTRIBUTE_ENCRYPTED;
    status = smb2_create(tree, tctx, &io);
    if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
        torture_comment(tctx,
                        "FILE_ATTRIBUTE_ENCRYPTED returned %s\n",
                        nt_errstr(status));
    } else {
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_EQUAL(io.out.file_attr, (FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_ARCHIVE));
        status = smb2_util_close(tree, io.out.file.handle);
        CHECK_STATUS(status, NT_STATUS_OK);
    }

    smb2_deltree(tree, FNAME);

    ZERO_STRUCT(io);
    io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    io.in.file_attributes    = 0;
    io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    io.in.share_access =
        NTCREATEX_SHARE_ACCESS_READ|
        NTCREATEX_SHARE_ACCESS_WRITE;
    io.in.create_options = 0;
    io.in.fname = FNAME ":stream1";
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    io.in.fname = FNAME;
    io.in.file_attributes = 0x8040;
    io.in.share_access =
        NTCREATEX_SHARE_ACCESS_READ;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    io.in.fname = FNAME;
    io.in.file_attributes = 0;
    io.in.desired_access  = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA;
    io.in.query_maximal_access = true;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);

    q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
    q.access_information.in.file.handle = io.out.file.handle;
    status = smb2_getinfo_file(tree, tctx, &q);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_EQUAL(q.access_information.out.access_flags, io.in.desired_access);

    io.in.file_attributes = 0;
    io.in.desired_access  = 0;
    io.in.query_maximal_access = false;
    io.in.share_access = 0;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

    smb2_deltree(tree, FNAME);

    return true;
}
Exemplo n.º 13
0
/* 
   recursively descend a tree deleting all files
   returns the number of files deleted, or -1 on error
*/
int smb2_deltree(struct smb2_tree *tree, const char *dname)
{
	NTSTATUS status;
	uint32_t total_deleted = 0;
	unsigned int count, i;
	union smb_search_data *list;
	TALLOC_CTX *tmp_ctx = talloc_new(tree);
	struct smb2_find f;
	struct smb2_create create_parm;
	bool did_delete;

	/* it might be a file */
	status = smb2_util_unlink(tree, dname);
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(tmp_ctx);
		return 1;
	}
	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
	    NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
	    NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_FILE)) {
		talloc_free(tmp_ctx);
		return 0;
	}

	if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
		/* it could be read-only */
		status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
		status = smb2_util_unlink(tree, dname);
	}
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(tmp_ctx);
		return 1;
	}

	ZERO_STRUCT(create_parm);
	create_parm.in.desired_access = SEC_FILE_READ_DATA;
	create_parm.in.share_access = 
		NTCREATEX_SHARE_ACCESS_READ|
		NTCREATEX_SHARE_ACCESS_WRITE;
	create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
	create_parm.in.fname = dname;

	status = smb2_create(tree, tmp_ctx, &create_parm);
	if (NT_STATUS_IS_ERR(status)) {
		DEBUG(2,("Failed to open %s - %s\n", dname, nt_errstr(status)));
		talloc_free(tmp_ctx);
		return -1;
	}
	

	do {
		did_delete = false;

		ZERO_STRUCT(f);
		f.in.file.handle       = create_parm.out.file.handle;
		f.in.max_response_size = 0x10000;
		f.in.level             = SMB2_FIND_NAME_INFO;
		f.in.pattern           = "*";
		
		status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
		if (NT_STATUS_IS_ERR(status)) {
			DEBUG(2,("Failed to list %s - %s\n", 
				 dname, nt_errstr(status)));
			smb2_util_close(tree, create_parm.out.file.handle);
			talloc_free(tmp_ctx);
			return -1;
		}
		
		for (i=0;i<count;i++) {
			char *name;
			if (strcmp(".", list[i].name_info.name.s) == 0 ||
			    strcmp("..", list[i].name_info.name.s) == 0) {
				continue;
			}
			name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
			status = smb2_util_unlink(tree, name);
			if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
				/* it could be read-only */
				status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
				status = smb2_util_unlink(tree, name);
			}
			
			if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
				int ret;
				ret = smb2_deltree(tree, name);
				if (ret > 0) total_deleted += ret;
			}
			talloc_free(name);
			if (NT_STATUS_IS_OK(status)) {
				total_deleted++;
				did_delete = true;
			}
		}
	} while (did_delete);

	smb2_util_close(tree, create_parm.out.file.handle);

	status = smb2_util_rmdir(tree, dname);
	if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
		/* it could be read-only */
		status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
		status = smb2_util_rmdir(tree, dname);
	}

	if (NT_STATUS_IS_ERR(status)) {
		DEBUG(2,("Failed to delete %s - %s\n", 
			 dname, nt_errstr(status)));
		talloc_free(tmp_ctx);
		return -1;
	}

	talloc_free(tmp_ctx);

	return total_deleted;
}
Exemplo n.º 14
0
/* Send a compound request where we expect the last request (Create, Notify)
 * to go asynchronous. This works against a Win7 server and the reply is
 * sent in two different packets. */
static bool test_compound_interim1(struct torture_context *tctx,
				   struct smb2_tree *tree)
{
    struct smb2_handle hd;
    struct smb2_create cr;
    NTSTATUS status = NT_STATUS_OK;
    const char *dname = "compound_interim_dir";
    struct smb2_notify nt;
    bool ret = true;
    struct smb2_request *req[2];

    /* Win7 compound request implementation deviates substantially from the
     * SMB2 spec as noted in MS-SMB2 <159>, <162>.  This, test currently
     * verifies the Windows behavior, not the general spec behavior. */

    smb2_transport_credits_ask_num(tree->session->transport, 5);

    smb2_deltree(tree, dname);

    smb2_transport_credits_ask_num(tree->session->transport, 1);

    ZERO_STRUCT(cr);
    cr.in.desired_access	= SEC_RIGHTS_FILE_ALL;
    cr.in.create_options	= NTCREATEX_OPTIONS_DIRECTORY;
    cr.in.file_attributes	= FILE_ATTRIBUTE_DIRECTORY;
    cr.in.share_access		= NTCREATEX_SHARE_ACCESS_READ |
				  NTCREATEX_SHARE_ACCESS_WRITE |
				  NTCREATEX_SHARE_ACCESS_DELETE;
    cr.in.create_disposition	= NTCREATEX_DISP_CREATE;
    cr.in.fname			= dname;

    smb2_transport_compound_start(tree->session->transport, 2);

    req[0] = smb2_create_send(tree, &cr);

    smb2_transport_compound_set_related(tree->session->transport, true);

    hd.data[0] = UINT64_MAX;
    hd.data[1] = UINT64_MAX;

    ZERO_STRUCT(nt);
    nt.in.recursive          = true;
    nt.in.buffer_size        = 0x1000;
    nt.in.file.handle        = hd;
    nt.in.completion_filter  = FILE_NOTIFY_CHANGE_NAME;
    nt.in.unknown            = 0x00000000;

    req[1] = smb2_notify_send(tree, &nt);

    status = smb2_create_recv(req[0], tree, &cr);
    CHECK_STATUS(status, NT_STATUS_OK);

    smb2_cancel(req[1]);
    status = smb2_notify_recv(req[1], tree, &nt);
    CHECK_STATUS(status, NT_STATUS_CANCELLED);

    smb2_util_close(tree, cr.out.file.handle);

    smb2_deltree(tree, dname);
done:
    return ret;
}
Exemplo n.º 15
0
static bool test_fixed(struct torture_context *tctx,
		       struct smb2_tree *tree)
{
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	struct smb2_create create;
	struct smb2_handle h, h2;
	struct smb2_find f;
	union smb_search_data *d;
	struct file_elem files[NFILES] = {};
	NTSTATUS status;
	bool ret = true;
	unsigned int count;
	int i;

	status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);

	ZERO_STRUCT(create);
	create.in.desired_access = SEC_RIGHTS_DIR_ALL;
	create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
	create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
				 NTCREATEX_SHARE_ACCESS_WRITE |
				 NTCREATEX_SHARE_ACCESS_DELETE;
	create.in.create_disposition = NTCREATEX_DISP_OPEN;
	create.in.fname = DNAME;

	status = smb2_create(tree, mem_ctx, &create);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");
	h2 = create.out.file.handle;

	ZERO_STRUCT(f);
	f.in.file.handle	= h;
	f.in.pattern		= "*";
	f.in.continue_flags	= SMB2_CONTINUE_FLAG_SINGLE;
	f.in.max_response_size	= 0x100;
	f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;

	/* Start enumeration on h, then delete all from h2 */
	status = smb2_find_level(tree, tree, &f, &count, &d);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

	f.in.file.handle	= h2;

	do {
		status = smb2_find_level(tree, tree, &f, &count, &d);
		if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
			break;
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

		for (i = 0; i < count; i++) {
			const char *found = d[i].both_directory_info.name.s;
			char *path = talloc_asprintf(mem_ctx, "%s\\%s",
			    DNAME, found);

			if (!strcmp(found, ".") || !strcmp(found, ".."))
				continue;

			status = smb2_util_unlink(tree, path);
			torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
							"");

			talloc_free(path);
		}

		f.in.continue_flags = 0;
		f.in.max_response_size	= 4096;
	} while (count != 0);

	/* Now finish h enumeration. */
	f.in.file.handle = h;

	do {
		status = smb2_find_level(tree, tree, &f, &count, &d);
		if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
			break;
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

		for (i = 0; i < count; i++) {
			const char *found = d[i].both_directory_info.name.s;

			if (!strcmp(found, ".") || !strcmp(found, ".."))
				continue;

			torture_result(tctx, TORTURE_FAIL,
			    "(%s): didn't expect %s\n",
			    __location__, found);
			ret = false;
			goto done;
		}

		f.in.continue_flags = 0;
		f.in.max_response_size	= 4096;
	} while (count != 0);

 done:
	smb2_util_close(tree, h);
	smb2_util_close(tree, h2);
	smb2_deltree(tree, DNAME);
	talloc_free(mem_ctx);

	return ret;
}
Exemplo n.º 16
0
static bool test_default_acl_posix(struct torture_context *tctx,
				   struct smb2_tree *tree_unused)
{
	struct smb2_tree *tree = NULL;
	NTSTATUS status;
	bool ok;
	bool ret = true;
	const char *dname = BASEDIR "\\testdir";
	const char *fname = BASEDIR "\\testdir\\testfile";
	struct smb2_handle fhandle = {{0}};
	struct smb2_handle dhandle = {{0}};
	union smb_fileinfo q;
	union smb_setfileinfo set;
	struct security_descriptor *sd = NULL;
	struct security_descriptor *exp_sd = NULL;
	char *owner_sid = NULL;
	char *group_sid = NULL;

	ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_posix", &tree);
	torture_assert_goto(tctx, ok == true, ret, done,
			    "Unable to connect to 'acl_xattr_ign_sysacl_posix'\n");

	ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
	torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");

	ZERO_STRUCT(dhandle);
	status = torture_smb2_testdir(tree, dname, &dhandle);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");

	torture_comment(tctx, "Get the original sd\n");

	ZERO_STRUCT(q);
	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	q.query_secdesc.in.file.handle = dhandle;
	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
	status = smb2_getinfo_file(tree, tctx, &q);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");

	sd = q.query_secdesc.out.sd;
	owner_sid = dom_sid_string(tctx, sd->owner_sid);
	group_sid = dom_sid_string(tctx, sd->group_sid);
	torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);

	torture_comment(tctx, "Set ACL with no inheritable ACE\n");

	sd = security_descriptor_dacl_create(tctx,
					     0, NULL, NULL,
					     owner_sid,
					     SEC_ACE_TYPE_ACCESS_ALLOWED,
					     SEC_RIGHTS_DIR_ALL,
					     0,
					     NULL);

	ZERO_STRUCT(set);
	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
	set.set_secdesc.in.file.handle = dhandle;
	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
	set.set_secdesc.in.sd = sd;
	status = smb2_setinfo_file(tree, &set);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");

	TALLOC_FREE(sd);
	smb2_util_close(tree, dhandle);

	torture_comment(tctx, "Create file\n");

	ZERO_STRUCT(fhandle);
	status = torture_smb2_testfile(tree, fname, &fhandle);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");

	torture_comment(tctx, "Query file SD\n");

	ZERO_STRUCT(q);
	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	q.query_secdesc.in.file.handle = fhandle;
	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
	status = smb2_getinfo_file(tree, tctx, &q);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
	sd = q.query_secdesc.out.sd;

	smb2_util_close(tree, fhandle);
	ZERO_STRUCT(fhandle);

	torture_comment(tctx, "Checking actual file SD against expected SD\n");

	exp_sd = security_descriptor_dacl_create(
		tctx, 0, owner_sid, group_sid,
		owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
		group_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
		SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
		SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
		NULL);

	CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);

done:
	if (!smb2_util_handle_empty(fhandle)) {
		smb2_util_close(tree, fhandle);
	}
	if (!smb2_util_handle_empty(dhandle)) {
		smb2_util_close(tree, dhandle);
	}
	if (tree != NULL) {
		smb2_deltree(tree, BASEDIR);
		smb2_tdis(tree);
	}

	return ret;
}
Exemplo n.º 17
0
/*
  try the various request blobs
 */
static bool test_create_blob(struct torture_context *tctx, struct smb2_tree *tree)
{
    struct smb2_create io;
    NTSTATUS status;

    smb2_deltree(tree, FNAME);

    ZERO_STRUCT(io);
    io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
    io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    io.in.share_access =
        NTCREATEX_SHARE_ACCESS_DELETE|
        NTCREATEX_SHARE_ACCESS_READ|
        NTCREATEX_SHARE_ACCESS_WRITE;
    io.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
                                  NTCREATEX_OPTIONS_ASYNC_ALERT	|
                                  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
                                  0x00200000;
    io.in.fname = FNAME;

    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Testing alloc size\n");
    io.in.alloc_size = 4096;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_EQUAL(io.out.alloc_size, io.in.alloc_size);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Testing durable open\n");
    io.in.durable_open = true;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Testing query maximal access\n");
    io.in.query_maximal_access = true;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Testing timewarp\n");
    io.in.timewarp = 10000;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    io.in.timewarp = 0;

    torture_comment(tctx, "Testing query_on_disk\n");
    io.in.query_on_disk_id = true;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Testing unknown tag\n");
    status = smb2_create_blob_add(tctx, &io.in.blobs,
                                  "FooO", data_blob(NULL, 0));
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Testing bad tag length\n");
    status = smb2_create_blob_add(tctx, &io.in.blobs,
                                  "xxx", data_blob(NULL, 0));
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    smb2_deltree(tree, FNAME);

    return true;
}
Exemplo n.º 18
0
static bool test_lease_v2_request(struct torture_context *tctx,
				  struct smb2_tree *tree)
{
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	struct smb2_create io;
	struct smb2_lease ls;
	struct smb2_handle h1, h2, h3, h4, h5;
	struct smb2_write w;
	NTSTATUS status;
	const char *fname = "lease.dat";
	const char *dname = "lease.dir";
	const char *dnamefname = "lease.dir\\lease.dat";
	const char *dnamefname2 = "lease.dir\\lease2.dat";
	bool ret = true;

	smb2_util_unlink(tree, fname);
	smb2_deltree(tree, dname);

	tree->session->transport->lease.handler	= torture_lease_handler;
	tree->session->transport->lease.private_data = tree;
	tree->session->transport->oplock.handler = torture_oplock_handler;
	tree->session->transport->oplock.private_data = tree;

	ZERO_STRUCT(break_info);

	ZERO_STRUCT(io);
	smb2_lease_v2_create_share(&io, &ls, false, fname,
				   smb2_util_share_access("RWD"),
				   LEASE1, NULL,
				   smb2_util_lease_state("RHW"),
				   0);

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	h1 = io.out.file.handle;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_LEASE_V2(&io, "RHW", true, LEASE1, 0);

	ZERO_STRUCT(io);
	smb2_lease_v2_create_share(&io, &ls, true, dname,
				   smb2_util_share_access("RWD"),
				   LEASE2, NULL,
				   smb2_util_lease_state("RHW"),
				   0);
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	h2 = io.out.file.handle;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_DIRECTORY);
	CHECK_LEASE_V2(&io, "RH", true, LEASE2, 0);

	ZERO_STRUCT(io);
	smb2_lease_v2_create_share(&io, &ls, false, dnamefname,
				   smb2_util_share_access("RWD"),
				   LEASE3, &LEASE2,
				   smb2_util_lease_state("RHW"),
				   0);
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	h3 = io.out.file.handle;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_LEASE_V2(&io, "RHW", true, LEASE3,
		       SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET);

	torture_wait_for_lease_break(tctx);
	CHECK_VAL(break_info.count, 0);
	CHECK_VAL(break_info.failures, 0);

	ZERO_STRUCT(io);
	smb2_lease_v2_create_share(&io, &ls, false, dnamefname2,
				   smb2_util_share_access("RWD"),
				   LEASE4, NULL,
				   smb2_util_lease_state("RHW"),
				   0);
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	h4 = io.out.file.handle;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_LEASE_V2(&io, "RHW", true, LEASE4, 0);

	torture_wait_for_lease_break(tctx);
	torture_wait_for_lease_break(tctx);
	CHECK_BREAK_INFO("RH", "", LEASE2);
	torture_wait_for_lease_break(tctx);

	ZERO_STRUCT(break_info);

	ZERO_STRUCT(io);
	smb2_lease_v2_create_share(&io, &ls, true, dname,
				   smb2_util_share_access("RWD"),
				   LEASE2, NULL,
				   smb2_util_lease_state("RHW"),
				   0);
	io.in.create_disposition = NTCREATEX_DISP_OPEN;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	h5 = io.out.file.handle;
	CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_DIRECTORY);
	CHECK_LEASE_V2(&io, "RH", true, LEASE2, 0);
	smb2_util_close(tree, h5);

	ZERO_STRUCT(w);
	w.in.file.handle = h4;
	w.in.offset      = 0;
	w.in.data        = data_blob_talloc(mem_ctx, NULL, 4096);
	memset(w.in.data.data, 'o', w.in.data.length);
	status = smb2_write(tree, &w);
	CHECK_STATUS(status, NT_STATUS_OK);

	smb_msleep(2000);
	torture_wait_for_lease_break(tctx);
	CHECK_VAL(break_info.count, 0);
	CHECK_VAL(break_info.failures, 0);

	smb2_util_close(tree, h4);
	torture_wait_for_lease_break(tctx);
	torture_wait_for_lease_break(tctx);
	CHECK_BREAK_INFO("RH", "", LEASE2);
	torture_wait_for_lease_break(tctx);

 done:
	smb2_util_close(tree, h1);
	smb2_util_close(tree, h2);
	smb2_util_close(tree, h3);
	smb2_util_close(tree, h4);
	smb2_util_close(tree, h5);

	smb2_util_unlink(tree, fname);
	smb2_deltree(tree, dname);

	talloc_free(mem_ctx);

	return ret;
}