Example #1
0
static bool test_afdgets(struct torture_context *tctx)
{
	int fd;
	char *line;
	TALLOC_CTX *mem_ctx = tctx;
	bool ret = false;
	
	torture_assert(tctx, file_save(TEST_FILENAME, (const void *)TEST_DATA, 
							 strlen(TEST_DATA)),
				   "saving file");

	fd = open(TEST_FILENAME, O_RDONLY);
	
	torture_assert(tctx, fd != -1, "opening file");

	line = afdgets(fd, mem_ctx, 8);
	torture_assert_goto(tctx, strcmp(line, TEST_LINE1) == 0, ret, done,
			    "line 1 mismatch");

	line = afdgets(fd, mem_ctx, 8);
	torture_assert_goto(tctx, strcmp(line, TEST_LINE2) == 0, ret, done,
			    "line 2 mismatch");

	line = afdgets(fd, mem_ctx, 8);
	torture_assert_goto(tctx, strcmp(line, TEST_LINE3) == 0, ret, done,
			    "line 3 mismatch");
	ret = true;
done:
	close(fd);

	unlink(TEST_FILENAME);
	return ret;
}
Example #2
0
/**
 * Find out user's samAccountName for given
 * user RDN. We need samAccountName value
 * when deleting users.
 */
static bool _get_account_name_for_user_rdn(struct torture_context *tctx,
					   const char *user_rdn,
					   TALLOC_CTX *mem_ctx,
					   const char **_account_name)
{
	const char *url;
	struct ldb_context *ldb;
	TALLOC_CTX *tmp_ctx;
	bool test_res = true;
	const char *hostname = torture_setting_string(tctx, "host", NULL);
	int ldb_ret;
	struct ldb_result *ldb_res;
	const char *account_name = NULL;
	static const char *attrs[] = {
		"samAccountName",
		NULL
	};

	torture_assert(tctx, hostname != NULL, "Failed to get hostname");

	tmp_ctx = talloc_new(tctx);
	torture_assert(tctx, tmp_ctx != NULL, "Failed to create temporary mem context");

	url = talloc_asprintf(tmp_ctx, "ldap://%s/", hostname);
	torture_assert_goto(tctx, url != NULL, test_res, done, "Failed to allocate URL for ldb");

	ldb = ldb_wrap_connect(tmp_ctx,
	                       tctx->ev, tctx->lp_ctx,
	                       url, NULL, cmdline_credentials, 0);
	torture_assert_goto(tctx, ldb != NULL, test_res, done, "Failed to make LDB connection");

	ldb_ret = ldb_search(ldb, tmp_ctx, &ldb_res,
	                     ldb_get_default_basedn(ldb), LDB_SCOPE_SUBTREE,
	                     attrs,
	                     "(&(objectClass=user)(name=%s))", user_rdn);
	if (LDB_SUCCESS == ldb_ret && 1 == ldb_res->count) {
		account_name = ldb_msg_find_attr_as_string(ldb_res->msgs[0], "samAccountName", NULL);
	}

	/* return user_rdn by default */
	if (!account_name) {
		account_name = user_rdn;
	}

	/* duplicate memory in parent context */
	*_account_name = talloc_strdup(mem_ctx, account_name);

done:
	talloc_free(tmp_ctx);
	return test_res;
}
Example #3
0
bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_state *cli)
{
	union smb_open io;
	const char *fname = "testfile";
	bool ret = false;
	struct smbcli_request *req;
	struct smb_echo echo_req;

	smbcli_unlink(cli->tree, fname);

	ZERO_STRUCT(io);
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
	io.ntcreatex.in.root_fid.fnum = 0;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.access_mask =
		SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.fname = "testfile";
	torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
					   NT_STATUS_OK,
					   ret, done, "first smb_open on the file failed");

	/*
	 * Create a conflicting open, causing the one-second delay
	 */

	torture_assert_goto(tctx, req = smb_raw_open_send(cli->tree, &io),
			    ret, done, "smb_raw_open_send on the file failed");

	/*
	 * Pull the VUID from under that request. As of Nov 3, 2008 all Samba3
	 * versions (3.0, 3.2 and master) would spin sending ERRinvuid errors
	 * as long as the client is still connected.
	 */

	torture_assert_ntstatus_equal_goto(tctx, smb_raw_ulogoff(cli->session),
					   NT_STATUS_OK,
					   ret, done, "ulogoff failed failed");

	echo_req.in.repeat_count = 1;
	echo_req.in.size = 1;
	echo_req.in.data = discard_const_p(uint8_t, "");

	torture_assert_ntstatus_equal_goto(tctx, smb_raw_echo(cli->session->transport, &echo_req),
					   NT_STATUS_OK,
					   ret, done, "smb_raw_echo failed");

	ret = true;
 done:
	return ret;
}
Example #4
0
static bool test_session_reauth1(struct torture_context *tctx,
				 struct smbcli_state *cli)
{
	NTSTATUS status;
	struct smb_composite_sesssetup io;
	int fnum, num;
	const int dlen = 255;
	char *data;
	char fname[256];
	char buf[dlen+1];
	bool ok = true;
	uint16_t vuid1 = cli->session->vuid;

	data = generate_random_str(tctx, dlen);
	torture_assert(tctx, (data != NULL), "memory allocation failed");
	snprintf(fname, sizeof(fname), "raw_session_reconnect_%.8s.dat", data);

	fnum = smbcli_nt_create_full(cli->tree, fname, 0,
				     SEC_RIGHTS_FILE_ALL,
				     FILE_ATTRIBUTE_NORMAL,
				     NTCREATEX_SHARE_ACCESS_NONE,
				     NTCREATEX_DISP_OPEN_IF,
				     NTCREATEX_OPTIONS_DELETE_ON_CLOSE,
				     0);
	torture_assert_ntstatus_ok_goto(tctx, smbcli_nt_error(cli->tree), ok,
					done, "create file");
	torture_assert_goto(tctx, fnum > 0, ok, done, "create file");

	num = smbcli_smbwrite(cli->tree, fnum, data, 0, dlen);
	torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "write file");

	ZERO_STRUCT(io);
	io.in.sesskey         = cli->transport->negotiate.sesskey;
	io.in.capabilities    = cli->transport->negotiate.capabilities;
	io.in.credentials     = cmdline_credentials;
	io.in.workgroup       = lpcfg_workgroup(tctx->lp_ctx);
	io.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx);
	status = smb_composite_sesssetup(cli->session, &io);
	torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "setup2");
	torture_assert_int_equal_goto(tctx, io.out.vuid, vuid1, ok, done, "setup2");

	buf[dlen] = '\0';

	num = smbcli_read(cli->tree, fnum, &buf, 0, dlen);
	torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "read file");
	torture_assert_str_equal_goto(tctx, buf, data, ok, done, "read file");

done:
	talloc_free(data);

	if (fnum > 0) {
		status = smbcli_close(cli->tree, fnum);
		torture_assert_ntstatus_ok(tctx, status, "close");
	}
	return ok;
}
Example #5
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;
}
Example #6
0
bool torture_samba3_badpath(struct torture_context *torture)
{
	struct smbcli_state *cli_nt = NULL;
	struct smbcli_state *cli_dos = NULL;
	const char *fname = "test.txt";
	const char *fname1 = "test1.txt";
	const char *dirname = "testdir";
	char *fpath;
	char *fpath1;
	int fnum;
	NTSTATUS status;
	bool ret = true;
	TALLOC_CTX *mem_ctx;
	bool nt_status_support;

	torture_assert(torture, mem_ctx = talloc_init("torture_samba3_badpath"), "talloc_init failed");

	nt_status_support = lpcfg_nt_status_support(torture->lp_ctx);

	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes"), ret, fail, "Could not set 'nt status support = yes'\n");

	torture_assert_goto(torture, torture_open_connection(&cli_nt, torture, 0), ret, fail, "Could not open NTSTATUS connection\n");

	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no"), ret, fail, "Could not set 'nt status support = no'\n");

	torture_assert_goto(torture, torture_open_connection(&cli_dos, torture, 1), ret, fail, "Could not open DOS connection\n");

	torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support",
						       nt_status_support ? "yes":"no"), 
			    ret, fail, "Could not set 'nt status support' back to where it was\n");

	torture_assert(torture, torture_setup_dir(cli_nt, dirname), "creating test directory");

	status = smbcli_chkpath(cli_nt->tree, dirname);
	CHECK_STATUS(torture, status, NT_STATUS_OK);

	status = smbcli_chkpath(cli_nt->tree,
				talloc_asprintf(mem_ctx, "%s\\bla", dirname));
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	status = smbcli_chkpath(cli_dos->tree,
				talloc_asprintf(mem_ctx, "%s\\bla", dirname));
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree,
				talloc_asprintf(mem_ctx, "%s\\bla\\blub",
						dirname));
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
	status = smbcli_chkpath(cli_dos->tree,
				talloc_asprintf(mem_ctx, "%s\\bla\\blub",
						dirname));
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	torture_assert_goto(torture, fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname), 
			    ret, fail, "Could not allocate fpath\n");

	fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s\n", fpath,
			 smbcli_errstr(cli_nt->tree));
		goto fail;
	}
	smbcli_close(cli_nt->tree, fnum);

	if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
		goto fail;
	}
	fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s\n", fpath1,
			 smbcli_errstr(cli_nt->tree));
		goto fail;
	}
	smbcli_close(cli_nt->tree, fnum);

	/*
	 * Do a whole bunch of error code checks on chkpath
	 */

	status = smbcli_chkpath(cli_nt->tree, fpath);
	CHECK_STATUS(torture, status, NT_STATUS_NOT_A_DIRECTORY);
	status = smbcli_chkpath(cli_dos->tree, fpath);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "..");
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
	status = smbcli_chkpath(cli_dos->tree, "..");
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));

	status = smbcli_chkpath(cli_nt->tree, ".");
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, ".");
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "\t");
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "\t");
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "\t\\bla");
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "\t\\bla");
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "<");
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "<");
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "<\\bla");
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "<\\bla");
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	/*
	 * .... And the same gang against getatr. Note that the DOS error codes
	 * differ....
	 */

	status = smbcli_getatr(cli_nt->tree, fpath, NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OK);
	status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OK);

	status = smbcli_getatr(cli_nt->tree, "..", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
	status = smbcli_getatr(cli_dos->tree, "..", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));

	status = smbcli_getatr(cli_nt->tree, ".", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, ".", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "\t", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "\t", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "\t\\bla", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "\t\\bla", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "<", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "<", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	/* Try the same set with openX. */

	status = raw_smbcli_open(cli_nt->tree, "..", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
	status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));

	status = raw_smbcli_open(cli_nt->tree, ".", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, ".", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "\t", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "\t", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "<", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "<", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	/* Let's test EEXIST error code mapping. */
	status = raw_smbcli_open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
	status = raw_smbcli_open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));

	status = raw_smbcli_t2open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
	    || !torture_setting_bool(torture, "samba3", false)) {
		/* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
		CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
	}
	status = raw_smbcli_t2open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,ERReasnotsupported))
	    || !torture_setting_bool(torture, "samba3", false)) {
		/* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
		CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
	}

	status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
	status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
	CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));

	/* Try the rename test. */
	{
		union smb_rename io;
		memset(&io, '\0', sizeof(io));
		io.rename.in.pattern1 = fpath1;
		io.rename.in.pattern2 = fpath;

		/* Try with SMBmv rename. */
		status = smb_raw_rename(cli_nt->tree, &io);
		CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
		status = smb_raw_rename(cli_dos->tree, &io);
		CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRrename));

		/* Try with NT rename. */
		io.generic.level = RAW_RENAME_NTRENAME;
		io.ntrename.in.old_name = fpath1;
		io.ntrename.in.new_name = fpath;
		io.ntrename.in.attrib = 0;
		io.ntrename.in.cluster_size = 0;
		io.ntrename.in.flags = RENAME_FLAG_RENAME;

		status = smb_raw_rename(cli_nt->tree, &io);
		CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
		status = smb_raw_rename(cli_dos->tree, &io);
		CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRrename));
	}

	goto done;

 fail:
	ret = false;

 done:
	if (cli_nt != NULL) {
		smbcli_deltree(cli_nt->tree, dirname);
		torture_close_connection(cli_nt);
	}
	if (cli_dos != NULL) {
		torture_close_connection(cli_dos);
	}
	talloc_free(mem_ctx);

	return ret;
}
Example #7
0
/**
 * basic test for doing a session reconnect
 */
bool test_session_reconnect1(struct torture_context *tctx, struct smb2_tree *tree)
{
    NTSTATUS status;
    TALLOC_CTX *mem_ctx = talloc_new(tctx);
    char fname[256];
    struct smb2_handle _h1;
    struct smb2_handle *h1 = NULL;
    struct smb2_handle _h2;
    struct smb2_handle *h2 = NULL;
    struct smb2_create io1, io2;
    uint64_t previous_session_id;
    bool ret = true;
    struct smb2_tree *tree2 = NULL;
    union smb_fileinfo qfinfo;

    /* Add some random component to the file name. */
    snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
             generate_random_str(tctx, 8));

    smb2_util_unlink(tree, fname);

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

    status = smb2_create(tree, mem_ctx, &io1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");
    _h1 = io1.out.file.handle;
    h1 = &_h1;
    CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");

    /* disconnect, reconnect and then do durable reopen */
    previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);

    torture_assert_goto(tctx, torture_smb2_connection_ext(tctx, previous_session_id,
                        &tree->session->transport->options, &tree2),
                        ret, done,
                        "session reconnect failed\n");

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

    ZERO_STRUCT(qfinfo);
    qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
    qfinfo.generic.in.file.handle = _h1;
    status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_USER_SESSION_DELETED,
                                       ret, done, "smb2_getinfo_file "
                                       "returned unexpected status");
    h1 = NULL;

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

    status = smb2_create(tree2, mem_ctx, &io2);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");

    CHECK_CREATED(tctx, &io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");
    _h2 = io2.out.file.handle;
    h2 = &_h2;

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

    if (tree2 != NULL) {
        smb2_util_unlink(tree2, fname);
    }
    smb2_util_unlink(tree, fname);

    talloc_free(tree);
    talloc_free(tree2);

    talloc_free(mem_ctx);

    return ret;
}
Example #8
0
bool torture_net_become_dc(struct torture_context *torture)
{
	bool ret = true;
	NTSTATUS status;
	struct libnet_BecomeDC b;
	struct libnet_UnbecomeDC u;
	struct libnet_vampire_cb_state *s;
	struct ldb_message *msg;
	int ldb_ret;
	uint32_t i;
	char *private_dir;
	const char *address;
	struct nbt_name name;
	const char *netbios_name;
	struct cli_credentials *machine_account;
	struct test_join *tj;
	struct loadparm_context *lp_ctx;
	struct ldb_context *ldb;
	struct libnet_context *ctx;
	struct dsdb_schema *schema;

	char *location = NULL;
	torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location), 
				   "torture_temp_dir should return NT_STATUS_OK" );

	netbios_name = lpcfg_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
	if (!netbios_name || !netbios_name[0]) {
		netbios_name = "smbtorturedc";
	}

	make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));

	/* do an initial name resolution to find its IP */
	status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
				 0, 0,
				 &name, torture, &address, torture->ev);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "Failed to resolve %s - %s\n",
				   name.name, nt_errstr(status)));


	/* Join domain as a member server. */
	tj = torture_join_domain(torture, netbios_name,
				 ACB_WSTRUST,
				 &machine_account);
	torture_assert(torture, tj, talloc_asprintf(torture,
						    "%s failed to join domain as workstation\n",
						    netbios_name));

	s = libnet_vampire_cb_state_init(torture, torture->lp_ctx, torture->ev,
			       netbios_name,
			       torture_join_dom_netbios_name(tj),
			       torture_join_dom_dns_name(tj),
			       location);
	torture_assert(torture, s, "libnet_vampire_cb_state_init");

	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
	ctx->cred = cmdline_credentials;

	ZERO_STRUCT(b);
	b.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	b.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	b.in.domain_sid			= torture_join_sid(tj);
	b.in.source_dsa_address		= address;
	b.in.dest_dsa_netbios_name	= netbios_name;

	b.in.callbacks.private_data	= s;
	b.in.callbacks.check_options	= libnet_vampire_cb_check_options;
	b.in.callbacks.prepare_db       = libnet_vampire_cb_prepare_db;
	b.in.callbacks.schema_chunk	= libnet_vampire_cb_schema_chunk;
	b.in.callbacks.config_chunk	= libnet_vampire_cb_store_chunk;
	b.in.callbacks.domain_chunk	= libnet_vampire_cb_store_chunk;

	status = libnet_BecomeDC(ctx, s, &b);
	torture_assert_ntstatus_ok_goto(torture, status, ret, cleanup, talloc_asprintf(torture,
				   "libnet_BecomeDC() failed - %s %s\n",
				   nt_errstr(status), b.out.error_string));
	ldb = libnet_vampire_cb_ldb(s);

	msg = ldb_msg_new(s);
	torture_assert_int_equal_goto(torture, (msg?1:0), 1, ret, cleanup,
				      "ldb_msg_new() failed\n");
	msg->dn = ldb_dn_new(msg, ldb, "@ROOTDSE");
	torture_assert_int_equal_goto(torture, (msg->dn?1:0), 1, ret, cleanup,
				      "ldb_msg_new(@ROOTDSE) failed\n");

	ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_msg_add_string(msg, isSynchronized, TRUE) failed\n");

	for (i=0; i < msg->num_elements; i++) {
		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
	}

	torture_comment(torture, "mark ROOTDSE with isSynchronized=TRUE\n");
	ldb_ret = ldb_modify(libnet_vampire_cb_ldb(s), msg);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_modify() failed\n");
	
	/* commit the transaction now we know the secrets were written
	 * out properly
	*/
	ldb_ret = ldb_transaction_commit(ldb);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_transaction_commit() failed\n");

	/* reopen the ldb */
	talloc_unlink(s, ldb);

	lp_ctx = libnet_vampire_cb_lp_ctx(s);
	private_dir = talloc_asprintf(s, "%s/%s", location, "private");
	lpcfg_set_cmdline(lp_ctx, "private dir", private_dir);
	torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir);
	ldb = samdb_connect(s, torture->ev, lp_ctx, system_session(lp_ctx), 0);
	torture_assert_goto(torture, ldb != NULL, ret, cleanup,
				      talloc_asprintf(torture,
				      "Failed to open '%s/sam.ldb'\n", private_dir));

	torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup,
						"Uses global schema");

	schema = dsdb_get_schema(ldb, s);
	torture_assert_goto(torture, schema != NULL, ret, cleanup,
				      "Failed to get loaded dsdb_schema\n");

	/* Make sure we get this from the command line */
	if (lpcfg_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
		talloc_free(s);
		return ret;
	}

cleanup:
	ZERO_STRUCT(u);
	u.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	u.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	u.in.source_dsa_address		= address;
	u.in.dest_dsa_netbios_name	= netbios_name;

	status = libnet_UnbecomeDC(ctx, s, &u);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "libnet_UnbecomeDC() failed - %s %s\n",
				   nt_errstr(status), u.out.error_string));

	/* Leave domain. */
	torture_leave_domain(torture, tj);

	talloc_free(s);
	return ret;
}
Example #9
0
static bool test_session_expire1(struct torture_context *tctx)
{
	NTSTATUS status;
	bool ret = false;
	struct smbcli_options options;
	struct smbcli_session_options session_options;
	const char *host = torture_setting_string(tctx, "host", NULL);
	const char *share = torture_setting_string(tctx, "share", NULL);
	struct cli_credentials *credentials = cmdline_credentials;
	struct smbcli_state *cli = NULL;
	enum credentials_use_kerberos use_kerberos;
	char fname[256];
	union smb_fileinfo qfinfo;
	uint16_t vuid;
	uint16_t fnum = 0;
	struct smb_composite_sesssetup io_sesssetup;
	size_t i;

	use_kerberos = cli_credentials_get_kerberos_state(credentials);
	if (use_kerberos != CRED_MUST_USE_KERBEROS) {
		torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
		torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
	}

	torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
				 "please use -k yes");

	lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");

	lpcfg_smbcli_options(tctx->lp_ctx, &options);

	lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);

	status = smbcli_full_connection(tctx, &cli,
					host,
					lpcfg_smb_ports(tctx->lp_ctx),
					share, NULL,
					lpcfg_socket_options(tctx->lp_ctx),
					credentials,
					lpcfg_resolve_context(tctx->lp_ctx),
					tctx->ev, &options, &session_options,
					lpcfg_gensec_settings(tctx, tctx->lp_ctx));
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"smbcli_full_connection failed");

	vuid = cli->session->vuid;

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

	smbcli_unlink(cli->tree, fname);

	fnum = smbcli_nt_create_full(cli->tree, fname, 0,
				     SEC_RIGHTS_FILE_ALL,
				     FILE_ATTRIBUTE_NORMAL,
				     NTCREATEX_SHARE_ACCESS_NONE,
				     NTCREATEX_DISP_OPEN_IF,
				     NTCREATEX_OPTIONS_DELETE_ON_CLOSE,
				     0);
	torture_assert_ntstatus_ok_goto(tctx, smbcli_nt_error(cli->tree), ret,
					done, "create file");
	torture_assert_goto(tctx, fnum > 0, ret, done, "create file");

	/* get the access information */

	ZERO_STRUCT(qfinfo);

	qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
	qfinfo.access_information.in.file.fnum = fnum;

	for (i=0; i < 2; i++) {
		torture_comment(tctx, "query info => OK\n");
		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"raw_fileinfo failed");

		torture_comment(tctx, "sleep 5 seconds\n");
		smb_msleep(5*1000);
	}

	/*
	 * the krb5 library may not handle expired creds
	 * well, lets start with an empty ccache.
	 */
	cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);

	/*
	 * now with CAP_DYNAMIC_REAUTH
	 *
	 * This should trigger NT_STATUS_NETWORK_SESSION_EXPIRED
	 */
	ZERO_STRUCT(io_sesssetup);
	io_sesssetup.in.sesskey      = cli->transport->negotiate.sesskey;
	io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities;
	io_sesssetup.in.capabilities |= CAP_DYNAMIC_REAUTH;
	io_sesssetup.in.credentials  = credentials;
	io_sesssetup.in.workgroup    = lpcfg_workgroup(tctx->lp_ctx);
	io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(tctx,
							tctx->lp_ctx);

	torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n");
	ZERO_STRUCT(io_sesssetup.out);
	status = smb_composite_sesssetup(cli->session, &io_sesssetup);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"reauth failed");
	torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
				      ret, done, "reauth");

	for (i=0; i < 2; i++) {
		torture_comment(tctx, "query info => OK\n");
		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"raw_fileinfo failed");

		torture_comment(tctx, "sleep 5 seconds\n");
		smb_msleep(5*1000);

		torture_comment(tctx, "query info => EXPIRED\n");
		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_equal_goto(tctx, status,
					NT_STATUS_NETWORK_SESSION_EXPIRED,
					ret, done, "raw_fileinfo expired");

		/*
		 * the krb5 library may not handle expired creds
		 * well, lets start with an empty ccache.
		 */
		cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);

		torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n");
		ZERO_STRUCT(io_sesssetup.out);
		status = smb_composite_sesssetup(cli->session, &io_sesssetup);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"reauth failed");
		torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
					      ret, done, "reauth");
	}

	torture_comment(tctx, "query info => OK\n");
	ZERO_STRUCT(qfinfo.access_information.out);
	status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"raw_fileinfo failed");

	/*
	 * the krb5 library may not handle expired creds
	 * well, lets start with an empty ccache.
	 */
	cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);

	/*
	 * now without CAP_DYNAMIC_REAUTH
	 *
	 * This should not trigger NT_STATUS_NETWORK_SESSION_EXPIRED
	 */
	torture_comment(tctx, "reauth without CAP_DYNAMIC_REAUTH => OK\n");
	io_sesssetup.in.capabilities &= ~CAP_DYNAMIC_REAUTH;

	ZERO_STRUCT(io_sesssetup.out);
	status = smb_composite_sesssetup(cli->session, &io_sesssetup);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"reauth failed");
	torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
				      ret, done, "reauth");

	for (i=0; i < 2; i++) {
		torture_comment(tctx, "query info => OK\n");

		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"raw_fileinfo failed");

		torture_comment(tctx, "sleep 5 seconds\n");
		smb_msleep(5*1000);
	}

	torture_comment(tctx, "query info => OK\n");
	ZERO_STRUCT(qfinfo.access_information.out);
	status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"raw_fileinfo failed");

	ret = true;
done:
	if (fnum > 0) {
		smbcli_close(cli->tree, fnum);
	}

	talloc_free(cli);
	lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
	return ret;
}