Ejemplo n.º 1
0
/*
  test fileinfo levels
*/
static bool torture_smb2_fileinfo(struct torture_context *tctx, struct smb2_tree *tree)
{
	struct smb2_handle hfile, hdir;
	NTSTATUS status;
	int i;

	status = torture_smb2_testfile(tree, FNAME, &hfile);
	if (!NT_STATUS_IS_OK(status)) {
		printf(__location__ " Unable to create test file '%s' - %s\n", FNAME, nt_errstr(status));
		goto failed;
	}

	status = torture_smb2_testdir(tree, DNAME, &hdir);
	if (!NT_STATUS_IS_OK(status)) {
		printf(__location__ " Unable to create test directory '%s' - %s\n", DNAME, nt_errstr(status));
		goto failed;
	}

	printf("Testing file info levels\n");
	torture_smb2_all_info(tree, hfile);
	torture_smb2_all_info(tree, hdir);

	for (i=0;i<ARRAY_SIZE(file_levels);i++) {
		if (file_levels[i].level == RAW_FILEINFO_SEC_DESC) {
			file_levels[i].finfo.query_secdesc.in.secinfo_flags = 0x7;
			file_levels[i].dinfo.query_secdesc.in.secinfo_flags = 0x7;
		}
		if (file_levels[i].level == RAW_FILEINFO_SMB2_ALL_EAS) {
			file_levels[i].finfo.all_eas.in.continue_flags = 
				SMB2_CONTINUE_FLAG_RESTART;
			file_levels[i].dinfo.all_eas.in.continue_flags = 
				SMB2_CONTINUE_FLAG_RESTART;
		}
		file_levels[i].finfo.generic.level = file_levels[i].level;
		file_levels[i].finfo.generic.in.file.handle = hfile;
		file_levels[i].fstatus = smb2_getinfo_file(tree, tree, &file_levels[i].finfo);
		if (!NT_STATUS_IS_OK(file_levels[i].fstatus)) {
			printf("(%s) %s failed on file - %s\n", __location__,
				file_levels[i].name, nt_errstr(file_levels[i].fstatus));
			goto failed;
		}
		file_levels[i].dinfo.generic.level = file_levels[i].level;
		file_levels[i].dinfo.generic.in.file.handle = hdir;
		file_levels[i].dstatus = smb2_getinfo_file(tree, tree, &file_levels[i].dinfo);
		if (!NT_STATUS_IS_OK(file_levels[i].dstatus)) {
			printf("(%s) %s failed on dir - %s\n", __location__,
				file_levels[i].name, nt_errstr(file_levels[i].dstatus));
			goto failed;
		}
	}

	return true;

failed:
	return false;
}
Ejemplo n.º 2
0
static bool test_read_dir(struct torture_context *torture, struct smb2_tree *tree)
{
	bool ret = true;
	NTSTATUS status;
	struct smb2_handle h;
	struct smb2_read rd;
	TALLOC_CTX *tmp_ctx = talloc_new(tree);

	status = torture_smb2_testdir(tree, DNAME, &h);
	if (!NT_STATUS_IS_OK(status)) {
		printf(__location__ " Unable to create test directory '%s' - %s\n", DNAME, nt_errstr(status));
		return false;
	}

	ZERO_STRUCT(rd);
	rd.in.file.handle = h;
	rd.in.length = 10;
	rd.in.offset = 0;
	rd.in.min_count = 1;

	status = smb2_read(tree, tmp_ctx, &rd);
	CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
	
	rd.in.min_count = 11;
	status = smb2_read(tree, tmp_ctx, &rd);
	CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);

	rd.in.length = 0;
	rd.in.min_count = 2592;
	status = smb2_read(tree, tmp_ctx, &rd);
	if (torture_setting_bool(torture, "windows", false)) {
		CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
	} else {
		CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
	}

	rd.in.length = 0;
	rd.in.min_count = 0;
	rd.in.channel = 0;
	status = smb2_read(tree, tmp_ctx, &rd);
	if (torture_setting_bool(torture, "windows", false)) {
		CHECK_STATUS(status, NT_STATUS_OK);
	} else {
		CHECK_STATUS(status, NT_STATUS_INVALID_DEVICE_REQUEST);
	}
	
done:
	talloc_free(tmp_ctx);
	return ret;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
/*
   basic testing of all File Information Classes using a single file
*/
static bool test_one_file(struct torture_context *tctx,
			  struct smb2_tree *tree)
{
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	bool ret = true;
	const char *fname =  "torture_search.txt";
	NTSTATUS status;
	int i;
	unsigned int count;
	union smb_fileinfo all_info2, alt_info, internal_info;
	union smb_search_data *s;
	union smb_search_data d;
	struct smb2_handle h, h2;

	status = torture_smb2_testdir(tree, DNAME, &h);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

	status = smb2_create_complex_file(tree, DNAME "\\torture_search.txt",
					  &h2);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

	/* call all the File Information Classes */
	for (i=0;i<ARRAY_SIZE(levels);i++) {
		torture_comment(tctx, "testing %s %d\n", levels[i].name,
				levels[i].level);

		levels[i].status = torture_single_file_search(tree, mem_ctx,
				   fname, levels[i].level, levels[i].data_level,
				   i, &d, &count, &h);
		torture_assert_ntstatus_ok_goto(tctx, levels[i].status, ret,
						done, "");
	}

	/* get the all_info file into to check against */
	all_info2.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
	all_info2.generic.in.file.handle = h2;
	status = smb2_getinfo_file(tree, tctx, &all_info2);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"RAW_FILEINFO_ALL_INFO failed");

	alt_info.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
	alt_info.generic.in.file.handle = h2;
	status = smb2_getinfo_file(tree, tctx, &alt_info);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"RAW_FILEINFO_ALT_NAME_INFO failed");

	internal_info.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;
	internal_info.generic.in.file.handle = h2;
	status = smb2_getinfo_file(tree, tctx, &internal_info);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"RAW_FILEINFO_INTERNAL_INFORMATION "
				        "failed");

#define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if ((s->sname1.field1) != (v.sname2.out.field2)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \
			    __location__, \
			    #sname1, #field1, (int)s->sname1.field1, \
			    #sname2, #field2, (int)v.sname2.out.field2); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if (s->sname1.field1 != \
		    (~1 & nt_time_to_unix(v.sname2.out.field2))) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%s) %s/%s [%s] != %s/%s [%s]\n", \
			    __location__, \
			    #sname1, #field1, \
			    timestring(tctx, s->sname1.field1), \
			    #sname2, #field2, \
			    nt_time_string(tctx, v.sname2.out.field2)); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if (s->sname1.field1 != v.sname2.out.field2) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%s) %s/%s [%s] != %s/%s [%s]\n", \
			    __location__, \
			    #sname1, #field1, \
			    nt_time_string(tctx, s->sname1.field1), \
			    #sname2, #field2, \
			    nt_time_string(tctx, v.sname2.out.field2)); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1 || \
		    strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%s) %s/%s [%s] != %s/%s [%s]\n", \
			    __location__, \
			    #sname1, #field1, s->sname1.field1, \
			    #sname2, #field2, v.sname2.out.field2.s); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1.s || \
		    strcmp(s->sname1.field1.s, v.sname2.out.field2.s)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%s) %s/%s [%s] != %s/%s [%s]\n", \
			    __location__, \
			    #sname1, #field1, s->sname1.field1.s, \
			    #sname2, #field2, v.sname2.out.field2.s); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_NAME(name, sname1, field1, fname, flags) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1.s || \
		    strcmp(s->sname1.field1.s, fname)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%s) %s/%s [%s] != %s\n", \
			    __location__, \
			    #sname1, #field1, s->sname1.field1.s, fname); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1 || \
		    strcmp(s->sname1.field1, fname)) { \
			torture_result(tctx, TORTURE_FAIL, \
			   "(%s) %s/%s [%s] != %s\n", \
			    __location__, \
			    #sname1, #field1, s->sname1.field1, fname); \
			ret = false; \
		} \
	}} while (0)

	/* check that all the results are as expected */
	CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, attrib, all_info2, all_info2, attrib);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, write_time, all_info2, all_info2, write_time);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, create_time, all_info2, all_info2, create_time);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, access_time, all_info2, all_info2, access_time);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, change_time, all_info2, all_info2, change_time);

	CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, size, all_info2, all_info2, size);

	CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, alloc_size, all_info2, all_info2, alloc_size);

	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    ea_size, all_info2, all_info2, ea_size);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    ea_size, all_info2, all_info2, ea_size);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, ea_size, all_info2, all_info2, ea_size);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, ea_size, all_info2, all_info2, ea_size);

	CHECK_NAME("SMB2_FIND_DIRECTORY_INFO",           directory_info,         name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_FULL_DIRECTORY_INFO",      full_directory_info,    name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_NAME_INFO",                name_info,              name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_BOTH_DIRECTORY_INFO",      both_directory_info,    name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_ID_FULL_DIRECTORY_INFO",   id_full_directory_info, name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",   id_both_directory_info, name, fname, STR_TERMINATE_ASCII);

	CHECK_WSTR("SMB2_FIND_BOTH_DIRECTORY_INFO",      both_directory_info,    short_name, alt_info, alt_name_info, fname, STR_UNICODE);

	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, file_id, internal_info, internal_information, file_id);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, file_id, internal_info, internal_information, file_id);

done:
	smb2_util_close(tree, h);
	smb2_util_unlink(tree, fname);
	talloc_free(mem_ctx);

	return ret;
}