Example #1
0
/* 
   basic testing of session/tree context calls
*/
static BOOL torture_raw_context_int(void)
{
	struct smbcli_state *cli;
	BOOL ret = True;
	TALLOC_CTX *mem_ctx;

	if (!torture_open_connection(&cli, 0)) {
		return False;
	}

	mem_ctx = talloc_init("torture_raw_context");

	ret &= test_session(cli, mem_ctx);
	ret &= test_tree(cli, mem_ctx);
	ret &= test_tree_ulogoff(cli, mem_ctx);
	ret &= test_pid_exit_only_sees_open(cli, mem_ctx);
	ret &= test_pid_2sess(cli, mem_ctx);
	ret &= test_pid_2tcon(cli, mem_ctx);

	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);

	torture_close_connection(cli);
	talloc_free(mem_ctx);

	return ret;
}
Example #2
0
/* 
   basic testing of streams calls
*/
BOOL torture_raw_streams(struct torture_context *torture)
{
	struct smbcli_state *cli;
	BOOL ret = True;
	TALLOC_CTX *mem_ctx;

	if (!torture_open_connection(&cli, 0)) {
		return False;
	}

	mem_ctx = talloc_init("torture_raw_streams");

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	ret &= test_stream_io(cli, mem_ctx);

	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);

	torture_close_connection(cli);
	talloc_free(mem_ctx);
	return ret;
}
Example #3
0
bool torture_samba3_caseinsensitive(struct torture_context *torture)
{
	struct smbcli_state *cli;
	TALLOC_CTX *mem_ctx;
	NTSTATUS status;
	const char *dirname = "insensitive";
	const char *ucase_dirname = "InSeNsItIvE";
	const char *fname = "foo";
	char *fpath;
	int fnum;
	int counter = 0;
	bool ret = true;

	if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) {
		d_printf("talloc_init failed\n");
		return false;
	}

	if (!torture_open_connection(&cli, torture, 0)) {
		goto done;
	}

	smbcli_deltree(cli->tree, dirname);

	status = smbcli_mkdir(cli->tree, dirname);
	if (!NT_STATUS_IS_OK(status)) {
		d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
		goto done;
	}

	if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
		goto done;
	}
	fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		d_printf("Could not create file %s: %s\n", fpath,
			 smbcli_errstr(cli->tree));
		goto done;
	}
	smbcli_close(cli->tree, fnum);

	smbcli_list(cli->tree, talloc_asprintf(
			    mem_ctx, "%s\\*", ucase_dirname),
		    FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN
		    |FILE_ATTRIBUTE_SYSTEM,
		    count_fn, (void *)&counter);

	if (counter == 3) {
		ret = true;
	}
	else {
		d_fprintf(stderr, "expected 3 entries, got %d\n", counter);
		ret = false;
	}

 done:
	talloc_free(mem_ctx);
	return ret;
}
Example #4
0
/* run a test that simulates an approximate netbench client load */
bool torture_nbench(struct torture_context *torture)
{
	bool correct = true;
	int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
	struct smbcli_state *cli;
	const char *p;

	read_only = torture_setting_bool(torture, "readonly", false);

	nb_max_retries = torture_setting_int(torture, "nretries", 1);

	p = torture_setting_string(torture, "timelimit", NULL);
	if (p && *p) {
		timelimit = atoi(p);
	}

	warmup = timelimit / 20;

	loadfile = torture_setting_string(torture, "loadfile", NULL);
	if (!loadfile || !*loadfile) {
		loadfile = "client.txt";
	}

	if (torture_nprocs > 1) {
		if (!torture_open_connection(&cli, torture, 0)) {
			return false;
		}

		if (!read_only && !torture_setup_dir(cli, "\\clients")) {
			return false;
		}
	}

	nbio_shmem(torture_nprocs, timelimit, warmup);

	printf("Running for %d seconds with load '%s' and warmup %d secs\n", 
	       timelimit, loadfile, warmup);

	/* we need to reset SIGCHLD here as the name resolution
	   library may have changed it. We rely on correct signals
	   from childs in the main torture code which reaps
	   children. This is why smbtorture BENCH-NBENCH was sometimes
	   failing */
	signal(SIGCHLD, SIG_DFL);


	signal(SIGALRM, nb_alarm);
	alarm(1);
	torture_create_procs(torture, run_netbench, &correct);
	alarm(0);

	if (!read_only && torture_nprocs > 1) {
		smbcli_deltree(cli->tree, "\\clients");
	}

	printf("\nThroughput %g MB/sec\n", nbio_result());
	return correct;
}
Example #5
0
/**
  setup a directory ready for a test
*/
_PUBLIC_ bool torture_setup_dir(struct smbcli_state *cli, const char *dname)
{
	smb_raw_exit(cli->session);
	if (smbcli_deltree(cli->tree, dname) == -1 ||
	    NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
		printf("Unable to setup %s - %s\n", dname, smbcli_errstr(cli->tree));
		return false;
	}
	return true;
}
Example #6
0
File: dfs.c Project: AllardJ/Tomato
static bool test_DeleteDir(struct smbcli_state *cli,
			   const char *dir)
{
	printf("Deleting directory %s\n", dir);

	if (smbcli_deltree(cli->tree, dir) == -1) {
		printf("Unable to delete dir %s - %s\n", dir,
			smbcli_errstr(cli->tree));
		return false;
	}

	return true;
}
Example #7
0
/* 
   basic testing of multiplexing notify
*/
bool torture_raw_mux(struct torture_context *torture, struct smbcli_state *cli)
{
	bool ret = true;
		
	torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);

	ret &= test_mux_open(cli, torture);
	ret &= test_mux_write(cli, torture);
	ret &= test_mux_lock(cli, torture);

	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Example #8
0
/* 
   basic testing of session/tree context calls
*/
static bool torture_raw_context_int(struct torture_context *tctx, 
									struct smbcli_state *cli)
{
	bool ret = true;

	ret &= test_session(cli, tctx);
	ret &= test_tree(cli, tctx);
	ret &= test_tree_ulogoff(cli, tctx);
	ret &= test_pid_exit_only_sees_open(cli, tctx);
	ret &= test_pid_2sess(cli, tctx);
	ret &= test_pid_2tcon(cli, tctx);

	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);

	return ret;
}
Example #9
0
/* 
   basic testing of disconnects
*/
bool torture_disconnect(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx;
	int i;
	extern int torture_numops;
	struct smbcli_state *cli;

	mem_ctx = talloc_init("torture_raw_mux");

	if (!torture_open_connection(&cli, torture, 0)) {
		return false;
	}

	if (!torture_setup_dir(cli, BASEDIR)) {
		return false;
	}

	for (i=0;i<torture_numops;i++) {
		ret &= test_disconnect_lock(cli, mem_ctx);
		if (!torture_open_connection(&cli, torture, 0)) {
			return false;
		}

		ret &= test_disconnect_open(cli, mem_ctx);
		if (!torture_open_connection(&cli, torture, 0)) {
			return false;
		}

		if (torture_setting_bool(torture, "samba3", false)) {
			/*
			 * In Samba3 it might happen that the old smbd from
			 * test_disconnect_lock is not scheduled before the
			 * new process comes in. Try to get rid of the random
			 * failures in the build farm.
			 */
			smb_msleep(200);
		}
	}

	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	talloc_free(mem_ctx);
	return ret;
}
Example #10
0
/* 
   basic testing of libcli composite calls
*/
bool torture_raw_composite(struct torture_context *tctx, 
			   struct smbcli_state *cli)
{
	bool ret = true;

	if (!torture_setup_dir(cli, BASEDIR)) {
		return false;
	}

	ret &= test_fetchfile(cli, tctx);
	ret &= test_loadfile(cli, tctx);
 	ret &= test_appendacl(cli, tctx);
	ret &= test_fsinfo(cli, tctx);

	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);

	return ret;
}
Example #11
0
bool torture_samba3_checkfsp(struct torture_context *torture, struct smbcli_state *cli)
{
	const char *fname = "test.txt";
	const char *dirname = "testdir";
	int fnum;
	NTSTATUS status;
	bool ret = true;
	TALLOC_CTX *mem_ctx;
	ssize_t nread;
	char buf[16];
	struct smbcli_tree *tree2;

	torture_assert(torture, mem_ctx = talloc_init("torture_samba3_checkfsp"), "talloc_init failed\n");

	torture_assert_ntstatus_equal(torture, torture_second_tcon(torture, cli->session,
								   torture_setting_string(torture, "share", NULL),
								   &tree2), 
				      NT_STATUS_OK,
				      "creating second tcon");

	/* Try a read on an invalid FID */

	nread = smbcli_read(cli->tree, 4711, buf, 0, sizeof(buf));
	CHECK_STATUS(torture, smbcli_nt_error(cli->tree), NT_STATUS_INVALID_HANDLE);

	/* Try a read on a directory handle */

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

	/* Open the directory */
	{
		union smb_open 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.open_disposition = NTCREATEX_DISP_CREATE;
		io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
		io.ntcreatex.in.alloc_size = 0;
		io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
		io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
		io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
		io.ntcreatex.in.create_options = 0;
		io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
		io.ntcreatex.in.fname = dirname;
		status = smb_raw_open(cli->tree, mem_ctx, &io);
		if (!NT_STATUS_IS_OK(status)) {
			torture_result(torture, TORTURE_FAIL, "smb_open on the directory failed: %s\n",
				 nt_errstr(status));
			ret = false;
			goto done;
		}
		fnum = io.ntcreatex.out.file.fnum;
	}

	/* Try a read on the directory */

	nread = smbcli_read(cli->tree, fnum, buf, 0, sizeof(buf));
	if (nread >= 0) {
		torture_result(torture, TORTURE_FAIL, "smbcli_read on a directory succeeded, expected "
			 "failure\n");
		ret = false;
	}

	CHECK_STATUS(torture, smbcli_nt_error(cli->tree),
		     NT_STATUS_INVALID_DEVICE_REQUEST);

	/* Same test on the second tcon */

	nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
	if (nread >= 0) {
		torture_result(torture, TORTURE_FAIL, "smbcli_read on a directory succeeded, expected "
			 "failure\n");
		ret = false;
	}

	CHECK_STATUS(torture, smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);

	smbcli_close(cli->tree, fnum);

	/* Try a normal file read on a second tcon */

	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
	if (fnum == -1) {
		torture_result(torture, TORTURE_FAIL, "Failed to create %s - %s\n", fname,
			 smbcli_errstr(cli->tree));
		ret = false;
		goto done;
	}

	nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
	CHECK_STATUS(torture, smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);

	smbcli_close(cli->tree, fnum);

 done:
	smbcli_deltree(cli->tree, dirname);
	talloc_free(mem_ctx);

	return ret;
}
Example #12
0
/*
  test read for execute
*/
static BOOL test_read_for_execute(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_open op;
	union smb_write wr;
	union smb_read rd;
	NTSTATUS status;
	BOOL ret = True;
	int fnum=0;
	uint8_t *buf;
	const int maxsize = 900;
	const char *fname = BASEDIR "\\test.txt";
	const uint8_t data[] = "TEST DATA";

	buf = talloc_zero_size(mem_ctx, maxsize);

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	printf("Testing RAW_READ_READX with read_for_execute\n");

	op.generic.level = RAW_OPEN_NTCREATEX;
	op.ntcreatex.in.root_fid = 0;
	op.ntcreatex.in.flags = 0;
	op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	op.ntcreatex.in.create_options = 0;
	op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
	op.ntcreatex.in.alloc_size = 0;
	op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	op.ntcreatex.in.security_flags = 0;
	op.ntcreatex.in.fname = fname;
	status = smb_raw_open(cli->tree, mem_ctx, &op);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = op.ntcreatex.out.file.fnum;

	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = ARRAY_SIZE(data);
	wr.writex.in.data = data;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));

	status = smbcli_close(cli->tree, fnum);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("open file with SEC_FILE_EXECUTE\n");
	op.generic.level = RAW_OPEN_NTCREATEX;
	op.ntcreatex.in.root_fid = 0;
	op.ntcreatex.in.flags = 0;
	op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
	op.ntcreatex.in.create_options = 0;
	op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
	op.ntcreatex.in.alloc_size = 0;
	op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
	op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	op.ntcreatex.in.security_flags = 0;
	op.ntcreatex.in.fname = fname;
	status = smb_raw_open(cli->tree, mem_ctx, &op);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = op.ntcreatex.out.file.fnum;

	printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
	rd.generic.level = RAW_READ_READX;
	rd.readx.in.file.fnum = fnum;
	rd.readx.in.mincnt = 0;
	rd.readx.in.maxcnt = maxsize;
	rd.readx.in.offset = 0;
	rd.readx.in.remaining = 0;
	rd.readx.in.read_for_execute = True;
	rd.readx.out.data = buf;
	status = smb_raw_read(cli->tree, &rd);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
	CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(rd.readx.out.compaction_mode, 0);

	printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
	rd.generic.level = RAW_READ_READX;
	rd.readx.in.file.fnum = fnum;
	rd.readx.in.mincnt = 0;
	rd.readx.in.maxcnt = maxsize;
	rd.readx.in.offset = 0;
	rd.readx.in.remaining = 0;
	rd.readx.in.read_for_execute = False;
	rd.readx.out.data = buf;
	status = smb_raw_read(cli->tree, &rd);
	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

	status = smbcli_close(cli->tree, fnum);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("open file with SEC_FILE_READ_DATA\n");
	op.generic.level = RAW_OPEN_NTCREATEX;
	op.ntcreatex.in.root_fid = 0;
	op.ntcreatex.in.flags = 0;
	op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
	op.ntcreatex.in.create_options = 0;
	op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
	op.ntcreatex.in.alloc_size = 0;
	op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
	op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	op.ntcreatex.in.security_flags = 0;
	op.ntcreatex.in.fname = fname;
	status = smb_raw_open(cli->tree, mem_ctx, &op);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = op.ntcreatex.out.file.fnum;

	printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
	rd.generic.level = RAW_READ_READX;
	rd.readx.in.file.fnum = fnum;
	rd.readx.in.mincnt = 0;
	rd.readx.in.maxcnt = maxsize;
	rd.readx.in.offset = 0;
	rd.readx.in.remaining = 0;
	rd.readx.in.read_for_execute = True;
	rd.readx.out.data = buf;
	status = smb_raw_read(cli->tree, &rd);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
	CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(rd.readx.out.compaction_mode, 0);

	printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
	rd.generic.level = RAW_READ_READX;
	rd.readx.in.file.fnum = fnum;
	rd.readx.in.mincnt = 0;
	rd.readx.in.maxcnt = maxsize;
	rd.readx.in.offset = 0;
	rd.readx.in.remaining = 0;
	rd.readx.in.read_for_execute = False;
	rd.readx.out.data = buf;
	status = smb_raw_read(cli->tree, &rd);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
	CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(rd.readx.out.compaction_mode, 0);

done:
	smbcli_close(cli->tree, fnum);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Example #13
0
/* 
   benchmark open calls
*/
bool torture_bench_open(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	int i;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	struct timeval tv;
	struct benchopen_state *state;
	int total = 0;
	int total_retries = 0;
	int minops = 0;
	bool progress=false;

	progress = torture_setting_bool(torture, "progress", true);
	
	nprocs = torture_setting_int(torture, "nprocs", 4);

	state = talloc_zero_array(mem_ctx, struct benchopen_state, nprocs);

	printf("Opening %d connections\n", nprocs);
	for (i=0;i<nprocs;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].client_num = i;
		state[i].ev = torture->ev;
		if (!torture_open_connection_ev(&state[i].cli, i, torture, torture->ev)) {
			return false;
		}
		talloc_steal(mem_ctx, state);
		state[i].tree = state[i].cli->tree;
		state[i].dest_host = talloc_strdup(state[i].mem_ctx, 
						   state[i].cli->tree->session->transport->socket->hostname);
		state[i].dest_ports = talloc_array(state[i].mem_ctx, 
						   const char *, 2);
		state[i].dest_ports[0] = talloc_asprintf(state[i].dest_ports, 
							 "%u", state[i].cli->tree->session->transport->socket->port);
		state[i].dest_ports[1] = NULL;
		state[i].called_name  = talloc_strdup(state[i].mem_ctx,
						      state[i].cli->tree->session->transport->called.name);
		state[i].service_type = talloc_strdup(state[i].mem_ctx,
						      state[i].cli->tree->device);
	}

	num_connected = i;

	if (!torture_setup_dir(state[0].cli, BASEDIR)) {
		goto failed;
	}

	fnames = talloc_array(mem_ctx, char *, 3*nprocs);
	for (i=0;i<3*nprocs;i++) {
		fnames[i] = talloc_asprintf(fnames, "%s\\file%d.dat", BASEDIR, i);
	}

	for (i=0;i<nprocs;i++) {
		/* all connections start with the same file */
		state[i].next_file_num = 0;
		state[i].open_fnum = -1;
		state[i].close_fnum = -1;
		next_open(&state[i]);
	}

	tv = timeval_current();	

	if (progress) {
		report_te = event_add_timed(torture->ev, state, timeval_current_ofs(1, 0), 
					    report_rate, state);
	}

	printf("Running for %d seconds\n", timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		event_loop_once(torture->ev);

		if (open_failed) {
			DEBUG(0,("open failed\n"));
			goto failed;
		}
		if (close_failed) {
			DEBUG(0,("open failed\n"));
			goto failed;
		}
	}

	talloc_free(report_te);
	if (progress) {
		for (i=0;i<nprocs;i++) {
			printf("      ");
		}
		printf("\r");
	}

	minops = state[0].count;
	for (i=0;i<nprocs;i++) {
		total += state[i].count;
		total_retries += state[i].open_retries;
		printf("[%d] %u ops (%u retries)\n",
		       i, state[i].count, state[i].open_retries);
		if (state[i].count < minops) minops = state[i].count;
	}
	printf("%.2f ops/second (%d retries)\n",
	       total/timeval_elapsed(&tv), total_retries);
	if (minops < 0.5*total/nprocs) {
		printf("Failed: unbalanced open\n");
		goto failed;
	}

	for (i=0;i<nprocs;i++) {
		talloc_free(state[i].req_open);
		talloc_free(state[i].req_close);
		smb_raw_exit(state[i].tree->session);
	}

	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	return ret;

failed:
	talloc_free(mem_ctx);
	return false;
}
Example #14
0
/*
  test seek ops
*/
static BOOL test_seek(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_seek io;
	union smb_fileinfo finfo;
	union smb_setfileinfo sfinfo;
	NTSTATUS status;
	BOOL ret = True;
	int fnum, fnum2;
	const char *fname = BASEDIR "\\test.txt";
	uint8_t c[2];

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
	if (fnum == -1) {
		printf("Failed to open test.txt - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	
	printf("Trying bad handle\n");
	io.lseek.in.file.fnum = fnum+1;
	io.lseek.in.mode = SEEK_MODE_START;
	io.lseek.in.offset = 0;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("Trying simple seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_START;
	io.lseek.in.offset = 17;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 17);
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);
	
	printf("Trying relative seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_CURRENT;
	io.lseek.in.offset = -3;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 14);

	printf("Trying end seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_END;
	io.lseek.in.offset = 0;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	finfo.generic.level = RAW_FILEINFO_ALL_INFO;
	finfo.all_info.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, finfo.all_info.out.size);

	printf("Trying max seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_START;
	io.lseek.in.offset = -1;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 0xffffffff);

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);

	printf("Trying max overflow\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_CURRENT;
	io.lseek.in.offset = 1000;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 999);

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);

	printf("trying write to update offset\n");
	ZERO_STRUCT(c);
	if (smbcli_write(cli->tree, fnum, 0, c, 0, 2) != 2) {
		printf("Write failed - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;		
	}

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);

	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_CURRENT;
	io.lseek.in.offset = 0;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 2);
	
	if (smbcli_read(cli->tree, fnum, c, 0, 1) != 1) {
		printf("Read failed - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;		
	}

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 1);

	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 1);

	printf("Testing position information\n");
	fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
	if (fnum2 == -1) {
		printf("2nd open failed - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}
	sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
	sfinfo.position_information.in.file.fnum = fnum2;
	sfinfo.position_information.in.position = 25;
	status = smb_raw_setfileinfo(cli->tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum2;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 25);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 1);

	printf("position_information via paths\n");

	sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
	sfinfo.position_information.in.file.path = fname;
	sfinfo.position_information.in.position = 32;
	status = smb_raw_setpathinfo(cli->tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum2;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 25);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);
	

done:
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Example #15
0
/*
  test SMBmv ops
*/
static bool test_mv(struct torture_context *tctx,
                    struct smbcli_state *cli)
{
    union smb_rename io;
    NTSTATUS status;
    bool ret = true;
    int fnum = -1;
    const char *fname1 = BASEDIR "\\test1.txt";
    const char *fname2 = BASEDIR "\\test2.txt";
    const char *Fname1 = BASEDIR "\\Test1.txt";
    union smb_fileinfo finfo;
    union smb_open op;

    torture_comment(tctx, "Testing SMBmv\n");

    if (!torture_setup_dir(cli, BASEDIR)) {
        return false;
    }

    torture_comment(tctx, "Trying simple rename\n");

    op.generic.level = RAW_OPEN_NTCREATEX;
    op.ntcreatex.in.root_fid.fnum = 0;
    op.ntcreatex.in.flags = 0;
    op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    op.ntcreatex.in.create_options = 0;
    op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    op.ntcreatex.in.share_access =
        NTCREATEX_SHARE_ACCESS_READ |
        NTCREATEX_SHARE_ACCESS_WRITE;
    op.ntcreatex.in.alloc_size = 0;
    op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    op.ntcreatex.in.security_flags = 0;
    op.ntcreatex.in.fname = fname1;

    status = smb_raw_open(cli->tree, tctx, &op);
    CHECK_STATUS(status, NT_STATUS_OK);
    fnum = op.ntcreatex.out.file.fnum;

    io.generic.level = RAW_RENAME_RENAME;
    io.rename.in.pattern1 = fname1;
    io.rename.in.pattern2 = fname2;
    io.rename.in.attrib = 0;

    torture_comment(tctx, "trying rename while first file open\n");
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);

    smbcli_close(cli->tree, fnum);

    op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
    op.ntcreatex.in.share_access =
        NTCREATEX_SHARE_ACCESS_DELETE |
        NTCREATEX_SHARE_ACCESS_READ |
        NTCREATEX_SHARE_ACCESS_WRITE;
    status = smb_raw_open(cli->tree, tctx, &op);
    CHECK_STATUS(status, NT_STATUS_OK);
    fnum = op.ntcreatex.out.file.fnum;

    torture_comment(tctx, "trying rename while first file open with SHARE_ACCESS_DELETE\n");
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    io.rename.in.pattern1 = fname2;
    io.rename.in.pattern2 = fname1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Trying case-changing rename\n");
    io.rename.in.pattern1 = fname1;
    io.rename.in.pattern2 = Fname1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.all_info.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    if (strcmp(finfo.all_info.out.fname.s, Fname1) != 0) {
        torture_warning(tctx, "(%s) Incorrect filename [%s] after case-changing "
                        "rename, should be [%s]\n", __location__,
                        finfo.all_info.out.fname.s, Fname1);
    }

    io.rename.in.pattern1 = fname1;
    io.rename.in.pattern2 = fname2;

    torture_comment(tctx, "trying rename while not open\n");
    smb_raw_exit(cli->session);
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Trying self rename\n");
    io.rename.in.pattern1 = fname2;
    io.rename.in.pattern2 = fname2;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    io.rename.in.pattern1 = fname1;
    io.rename.in.pattern2 = fname1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);


    torture_comment(tctx, "trying wildcard rename\n");
    io.rename.in.pattern1 = BASEDIR "\\*.txt";
    io.rename.in.pattern2 = fname1;

    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "and again\n");
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Trying extension change\n");
    io.rename.in.pattern1 = BASEDIR "\\*.txt";
    io.rename.in.pattern2 = BASEDIR "\\*.bak";
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);

    torture_comment(tctx, "Checking attrib handling\n");
    torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN);
    io.rename.in.pattern1 = BASEDIR "\\test1.bak";
    io.rename.in.pattern2 = BASEDIR "\\*.txt";
    io.rename.in.attrib = 0;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);

    io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

done:
    smbcli_close(cli->tree, fnum);
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Example #16
0
static bool test_osxrename(struct torture_context *tctx,
                           struct smbcli_state *cli)
{
    union smb_rename io;
    union smb_unlink io_un;
    NTSTATUS status;
    bool ret = true;
    int fnum = -1;
    const char *fname1 = BASEDIR "\\test1";
    const char *FNAME1 = BASEDIR "\\TEST1";
    union smb_fileinfo finfo;
    union smb_open op;

    torture_comment(tctx, "\nTesting OSX Rename\n");
    if (!torture_setup_dir(cli, BASEDIR)) {
        return false;
    }
    op.generic.level = RAW_OPEN_NTCREATEX;
    op.ntcreatex.in.root_fid.fnum = 0;
    op.ntcreatex.in.flags = 0;
    op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    op.ntcreatex.in.create_options = 0;
    op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    op.ntcreatex.in.share_access =
        NTCREATEX_SHARE_ACCESS_READ |
        NTCREATEX_SHARE_ACCESS_WRITE;
    op.ntcreatex.in.alloc_size = 0;
    op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    op.ntcreatex.in.security_flags = 0;
    op.ntcreatex.in.fname = fname1;

    status = smb_raw_open(cli->tree, tctx, &op);
    CHECK_STATUS(status, NT_STATUS_OK);
    fnum = op.ntcreatex.out.file.fnum;

    io.generic.level = RAW_RENAME_RENAME;
    io.rename.in.attrib = 0;

    smbcli_close(cli->tree, fnum);

    /* Rename by changing case. First check for the
     * existence of the file with the "newname".
     * If we find one and both the output and input are same case,
     * delete it. */

    torture_comment(tctx, "Checking os X rename (case changing)\n");

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.all_info.in.file.path = FNAME1;
    torture_comment(tctx, "Looking for file %s \n",FNAME1);
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);

    if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
        torture_comment(tctx, "Name of the file found %s \n", finfo.all_info.out.fname.s);
        if (strcmp(finfo.all_info.out.fname.s, finfo.all_info.in.file.path) == 0) {
            /* If file is found with the same case delete it */
            torture_comment(tctx, "Deleting File %s \n", finfo.all_info.out.fname.s);
            io_un.unlink.in.pattern = finfo.all_info.out.fname.s;
            io_un.unlink.in.attrib = 0;
            status = smb_raw_unlink(cli->tree, &io_un);
            CHECK_STATUS(status, NT_STATUS_OK);
        }
    }

    io.rename.in.pattern1 = fname1;
    io.rename.in.pattern2 = FNAME1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.all_info.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    torture_comment(tctx, "File name after rename %s \n",finfo.all_info.out.fname.s);

done:
    smbcli_close(cli->tree, fnum);
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Example #17
0
/*
  test read ops
*/
static BOOL test_read(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_read io;
	NTSTATUS status;
	BOOL ret = True;
	int fnum;
	uint8_t *buf;
	const int maxsize = 90000;
	const char *fname = BASEDIR "\\test.txt";
	const char *test_data = "TEST DATA";
	uint_t seed = time(NULL);

	buf = talloc_zero_size(mem_ctx, maxsize);

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	printf("Testing RAW_READ_READ\n");
	io.generic.level = RAW_READ_READ;
	
	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
	if (fnum == -1) {
		printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}

	printf("Trying empty file read\n");
	io.read.in.file.fnum = fnum;
	io.read.in.count = 1;
	io.read.in.offset = 0;
	io.read.in.remaining = 0;
	io.read.out.data = buf;
	status = smb_raw_read(cli->tree, &io);

	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, 0);

	printf("Trying zero file read\n");
	io.read.in.count = 0;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, 0);

	printf("Trying bad fnum\n");
	io.read.in.file.fnum = fnum+1;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
	io.read.in.file.fnum = fnum;

	smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));

	printf("Trying small read\n");
	io.read.in.file.fnum = fnum;
	io.read.in.offset = 0;
	io.read.in.remaining = 0;
	io.read.in.count = strlen(test_data);
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, strlen(test_data));
	if (memcmp(buf, test_data, strlen(test_data)) != 0) {
		ret = False;
		printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
		goto done;
	}

	printf("Trying short read\n");
	io.read.in.offset = 1;
	io.read.in.count = strlen(test_data);
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
	if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
		ret = False;
		printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
		goto done;
	}

	if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
		printf("Trying max offset\n");
		io.read.in.offset = ~0;
		io.read.in.count = strlen(test_data);
		status = smb_raw_read(cli->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OK);
		CHECK_VALUE(io.read.out.nread, 0);
	}

	setup_buffer(buf, seed, maxsize);
	smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
	memset(buf, 0, maxsize);

	printf("Trying large read\n");
	io.read.in.offset = 0;
	io.read.in.count = ~0;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_BUFFER(buf, seed, io.read.out.nread);


	printf("Trying locked region\n");
	cli->session->pid++;
	if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
		printf("Failed to lock file at %d\n", __LINE__);
		ret = False;
		goto done;
	}
	cli->session->pid--;
	memset(buf, 0, maxsize);
	io.read.in.offset = 0;
	io.read.in.count = ~0;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
	

done:
	smbcli_close(cli->tree, fnum);
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Example #18
0
/* 
   test offline file handling
*/
bool torture_test_offline(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	int i;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	struct timeval tv;
	struct offline_state *state;
	struct smbcli_state *cli;
	bool progress;
	progress = torture_setting_bool(torture, "progress", true);

	nconnections = torture_setting_int(torture, "nprocs", 4);
	numstates = nconnections * torture_entries;

	state = talloc_zero_array(mem_ctx, struct offline_state, numstates);

	printf("Opening %d connections with %d simultaneous operations and %u files\n", nconnections, numstates, torture_numops);
	for (i=0;i<nconnections;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].ev = torture->ev;
		if (!torture_open_connection_ev(&cli, i, torture, torture->ev)) {
			return false;
		}
		state[i].tree = cli->tree;
		state[i].client = i;
		/* allow more time for offline files */
		state[i].tree->session->transport->options.request_timeout = 200;
	}

	/* the others are repeats on the earlier connections */
	for (i=nconnections;i<numstates;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].ev = torture->ev;
		state[i].tree = state[i % nconnections].tree;
		state[i].client = i;
	}

	num_connected = i;

	if (!torture_setup_dir(cli, BASEDIR)) {
		goto failed;
	}

	/* pre-create files */
	printf("Pre-creating %u files ....\n", torture_numops);
	for (i=0;i<torture_numops;i++) {
		int fnum;
		char *fname = filename(mem_ctx, i);
		char buf[FILE_SIZE];
		NTSTATUS status;

		memset(buf, 1+(i % 255), sizeof(buf));

		fnum = smbcli_open(state[0].tree, fname, O_RDWR|O_CREAT, DENY_NONE);
		if (fnum == -1) {
			printf("Failed to open %s on connection %d\n", fname, i);
			goto failed;
		}

		if (smbcli_write(state[0].tree, fnum, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
			printf("Failed to write file of size %u\n", FILE_SIZE);
			goto failed;
		}

		status = smbcli_close(state[0].tree, fnum);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Close failed - %s\n", nt_errstr(status));
			goto failed;
		}

		talloc_free(fname);
	}

	/* start the async ops */
	for (i=0;i<numstates;i++) {
		state[i].tv_start = timeval_current();
		test_offline(&state[i]);
	}

	tv = timeval_current();	

	if (progress) {
		event_add_timed(torture->ev, state, timeval_current_ofs(1, 0), report_rate, state);
	}

	printf("Running for %d seconds\n", timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		event_loop_once(torture->ev);

		if (test_failed) {
			DEBUG(0,("test failed\n"));
			goto failed;
		}
	}

	printf("\nWaiting for completion\n");
	test_finished = true;
	for (i=0;i<numstates;i++) {
		while (state[i].loadfile || 
		       state[i].savefile ||
		       state[i].req) {
			event_loop_once(torture->ev);
		}
	}	

	printf("worst latencies: set_lat=%.1f get_lat=%.1f save_lat=%.1f load_lat=%.1f\n",
	       worst_latencies[OP_SETOFFLINE],
	       worst_latencies[OP_GETOFFLINE],
	       worst_latencies[OP_SAVEFILE],
	       worst_latencies[OP_LOADFILE]);

	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	printf("\n");
	return ret;

failed:
	talloc_free(mem_ctx);
	return false;
}
Example #19
0
File: misc.c Project: endisd/samba
/*
test how many open files this server supports on the one socket
*/
bool run_maxfidtest(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
{
#define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
	char *fname;
	int fnums[0x11000], i;
	int retries=4, maxfid;
	bool correct = true;

	if (retries <= 0) {
		torture_comment(tctx, "failed to connect\n");
		return false;
	}

	if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
		torture_comment(tctx, "Failed to deltree \\maxfid - %s\n",
		       smbcli_errstr(cli->tree));
		return false;
	}
	if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
		torture_comment(tctx, "Failed to mkdir \\maxfid, error=%s\n", 
		       smbcli_errstr(cli->tree));
		return false;
	}

	torture_comment(tctx, "Testing maximum number of open files\n");

	for (i=0; i<0x11000; i++) {
		if (i % 1000 == 0) {
			asprintf(&fname, "\\maxfid\\fid%d", i/1000);
			if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
				torture_comment(tctx, "Failed to mkdir %s, error=%s\n", 
				       fname, smbcli_errstr(cli->tree));
				return false;
			}
			free(fname);
		}
		asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
		if ((fnums[i] = smbcli_open(cli->tree, fname, 
					O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
		    -1) {
			torture_comment(tctx, "open of %s failed (%s)\n", 
			       fname, smbcli_errstr(cli->tree));
			torture_comment(tctx, "maximum fnum is %d\n", i);
			break;
		}
		free(fname);
		if (torture_setting_bool(tctx, "progress", true)) {
			torture_comment(tctx, "%6d\r", i);
			fflush(stdout);
		}
	}
	torture_comment(tctx, "%6d\n", i);
	i--;

	maxfid = i;

	torture_comment(tctx, "cleaning up\n");
	for (i=0;i<maxfid/2;i++) {
		asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
		if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
			torture_comment(tctx, "Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
		}
		if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
			torture_comment(tctx, "unlink of %s failed (%s)\n", 
			       fname, smbcli_errstr(cli->tree));
			correct = false;
		}
		free(fname);

		asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
		if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
			torture_comment(tctx, "Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
		}
		if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
			torture_comment(tctx, "unlink of %s failed (%s)\n", 
			       fname, smbcli_errstr(cli->tree));
			correct = false;
		}
		free(fname);

		if (torture_setting_bool(tctx, "progress", true)) {
			torture_comment(tctx, "%6d %6d\r", i, maxfid-i);
			fflush(stdout);
		}
	}
	torture_comment(tctx, "%6d\n", 0);

	if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
		torture_comment(tctx, "Failed to deltree \\maxfid - %s\n",
		       smbcli_errstr(cli->tree));
		return false;
	}

	torture_comment(tctx, "maxfid test finished\n");
	if (!torture_close_connection(cli)) {
		correct = false;
	}
	return correct;
#undef MAXFID_TEMPLATE
}
Example #20
0
bool torture_samba3_closeerr(struct torture_context *tctx)
{
	struct smbcli_state *cli = NULL;
	bool result = false;
	NTSTATUS status;
	const char *dname = "closeerr.dir";
	const char *fname = "closeerr.dir\\closerr.txt";
	int fnum;

	if (!torture_open_connection(&cli, tctx, 0)) {
		goto fail;
	}

	smbcli_deltree(cli->tree, dname);

	torture_assert_ntstatus_ok(
		tctx, smbcli_mkdir(cli->tree, dname),
		talloc_asprintf(tctx, "smbcli_mdir failed: (%s)\n",
				smbcli_errstr(cli->tree)));

	fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR,
			    DENY_NONE);
	torture_assert(tctx, fnum != -1, 
		       talloc_asprintf(tctx, "smbcli_open failed: %s\n",
				       smbcli_errstr(cli->tree)));
	smbcli_close(cli->tree, fnum);

	fnum = smbcli_nt_create_full(cli->tree, fname, 0, 
				      SEC_RIGHTS_FILE_ALL,
				      FILE_ATTRIBUTE_NORMAL,
				      NTCREATEX_SHARE_ACCESS_DELETE,
				      NTCREATEX_DISP_OPEN, 0, 0);

	torture_assert(tctx, fnum != -1, 
		       talloc_asprintf(tctx, "smbcli_open failed: %s\n",
				       smbcli_errstr(cli->tree)));

	status = smbcli_nt_delete_on_close(cli->tree, fnum, true);

	torture_assert_ntstatus_ok(tctx, status, 
				   "setting delete_on_close on file failed !");

	status = smbcli_chmod(cli->tree, dname, 0);

	torture_assert_ntstatus_ok(tctx, status, 
				   "smbcli_chmod on file failed !");

	status = smbcli_close(cli->tree, fnum);

	smbcli_chmod(cli->tree, dname, UNIX_R_USR|UNIX_W_USR|UNIX_X_USR);
	smbcli_deltree(cli->tree, dname);

	torture_assert_ntstatus_equal(tctx, status, NT_STATUS_ACCESS_DENIED,
				      "smbcli_close");

	result = true;
	
 fail:
	if (cli) {
		torture_close_connection(cli);
	}
	return result;
}
Example #21
0
File: dir.c Project: AllardJ/Tomato
bool torture_dirtest2(struct torture_context *tctx, 
		      struct smbcli_state *cli)
{
	int i;
	int fnum, num_seen;
	bool correct = true;
	extern int torture_entries;

	if (!torture_setup_dir(cli, "\\LISTDIR")) {
		return false;
	}

	torture_comment(tctx, "Creating %d files\n", torture_entries);

	/* Create torture_entries files and torture_entries directories. */
	for (i=0;i<torture_entries;i++) {
		char *fname;
		asprintf(&fname, "\\LISTDIR\\f%d", i);
		fnum = smbcli_nt_create_full(cli->tree, fname, 0, 
					     SEC_RIGHTS_FILE_ALL,
					     FILE_ATTRIBUTE_ARCHIVE,
					     NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, 
					     NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
		if (fnum == -1) {
			fprintf(stderr,"(%s) Failed to open %s, error=%s\n", 
				__location__, fname, smbcli_errstr(cli->tree));
			return false;
		}
		free(fname);
		smbcli_close(cli->tree, fnum);
	}
	for (i=0;i<torture_entries;i++) {
		char *fname;
		asprintf(&fname, "\\LISTDIR\\d%d", i);
		if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
			fprintf(stderr,"(%s) Failed to open %s, error=%s\n", 
				__location__, fname, smbcli_errstr(cli->tree));
			return false;
		}
		free(fname);
	}

	/* Now ensure that doing an old list sees both files and directories. */
	num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
	torture_comment(tctx, "num_seen = %d\n", num_seen );
	/* We should see (torture_entries) each of files & directories + . and .. */
	if (num_seen != (2*torture_entries)+2) {
		correct = false;
		fprintf(stderr,"(%s) entry count mismatch, should be %d, was %d\n",
			__location__, (2*torture_entries)+2, num_seen);
	}
		

	/* Ensure if we have the "must have" bits we only see the
	 * relevant entries.
	 */
	num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
	torture_comment(tctx, "num_seen = %d\n", num_seen );
	if (num_seen != torture_entries+2) {
		correct = false;
		fprintf(stderr,"(%s) entry count mismatch, should be %d, was %d\n",
			__location__, torture_entries+2, num_seen);
	}

	num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
	torture_comment(tctx, "num_seen = %d\n", num_seen );
	if (num_seen != torture_entries) {
		correct = false;
		fprintf(stderr,"(%s) entry count mismatch, should be %d, was %d\n",
			__location__, torture_entries, num_seen);
	}

	/* Delete everything. */
	if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
		fprintf(stderr,"(%s) Failed to deltree %s, error=%s\n", "\\LISTDIR", 
			__location__, smbcli_errstr(cli->tree));
		return false;
	}

#if 0
	torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
	torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
	torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
#endif

	return correct;
}
Example #22
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 #23
0
bool torture_samba3_posixtimedlock(struct torture_context *tctx, struct smbcli_state *cli)
{
	NTSTATUS status;
	bool ret = true;
	const char *dirname = "posixlock";
	const char *fname = "locked";
	const char *fpath;
	const char *localdir;
	const char *localname;
	int fnum = -1;

	int fd = -1;
	struct flock posix_lock;

	union smb_lock io;
	struct smb_lock_entry lock_entry;
	struct smbcli_request *req;
	struct lock_result_state lock_result;

	struct tevent_timer *te;

	torture_assert(tctx, torture_setup_dir(cli, dirname), "creating test directory");

	if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
		torture_warning(tctx, "talloc failed\n");
		ret = false;
		goto done;
	}
	fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		torture_warning(tctx, "Could not create file %s: %s\n", fpath,
				smbcli_errstr(cli->tree));
		ret = false;
		goto done;
	}

	if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
		torture_warning(tctx, "Need 'localdir' setting\n");
		ret = false;
		goto done;
	}

	if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
					  fname))) {
		torture_warning(tctx, "talloc failed\n");
		ret = false;
		goto done;
	}

	/*
	 * Lock a byte range from posix
	 */

	fd = open(localname, O_RDWR);
	if (fd == -1) {
		torture_warning(tctx, "open(%s) failed: %s\n",
				localname, strerror(errno));
		goto done;
	}

	posix_lock.l_type = F_WRLCK;
	posix_lock.l_whence = SEEK_SET;
	posix_lock.l_start = 0;
	posix_lock.l_len = 1;

	if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
		torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
		ret = false;
		goto done;
	}

	/*
	 * Try a cifs brlock without timeout to see if posix locking = yes
	 */

	io.lockx.in.ulock_cnt = 0;
	io.lockx.in.lock_cnt = 1;

	lock_entry.count = 1;
	lock_entry.offset = 0;
	lock_entry.pid = cli->tree->session->pid;

	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
	io.lockx.in.timeout = 0;
	io.lockx.in.locks = &lock_entry;
	io.lockx.in.file.fnum = fnum;

	status = smb_raw_lock(cli->tree, &io);

	ret = true;
	CHECK_STATUS(tctx, status, NT_STATUS_FILE_LOCK_CONFLICT);

	if (!ret) {
		goto done;
	}

	/*
	 * Now fire off a timed brlock, unlock the posix lock and see if the
	 * timed lock gets through.
	 */

	io.lockx.in.timeout = 5000;

	req = smb_raw_lock_send(cli->tree, &io);
	if (req == NULL) {
		torture_warning(tctx, "smb_raw_lock_send failed\n");
		ret = false;
		goto done;
	}

	lock_result.done = false;
	req->async.fn = receive_lock_result;
	req->async.private_data = &lock_result;

	te = tevent_add_timer(tctx->ev,
			      tctx, timeval_current_ofs(1, 0),
			      close_locked_file, &fd);
	if (te == NULL) {
		torture_warning(tctx, "tevent_add_timer failed\n");
		ret = false;
		goto done;
	}

	while ((fd != -1) || (!lock_result.done)) {
		if (tevent_loop_once(tctx->ev) == -1) {
			torture_warning(tctx, "tevent_loop_once failed: %s\n",
					strerror(errno));
			ret = false;
			goto done;
		}
	}

	CHECK_STATUS(tctx, lock_result.status, NT_STATUS_OK);

 done:
	if (fnum != -1) {
		smbcli_close(cli->tree, fnum);
	}
	if (fd != -1) {
		close(fd);
	}
	smbcli_deltree(cli->tree, dirname);
	return ret;
}
Example #24
0
/**
 * Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
 * pass-through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
 * trans2setpathinfo.
 */
static bool
torture_raw_sfileinfo_eof(struct torture_context *tctx,
                          struct smbcli_state *cli1, struct smbcli_state *cli2)
{
    const char *fname = BASEDIR "\\test_sfileinfo_end_of_file.dat";
    NTSTATUS status;
    bool ret = true;
    union smb_open io;
    union smb_setfileinfo sfi;
    union smb_fileinfo qfi;
    uint16_t fnum = 0;

    if (!torture_setup_dir(cli1, BASEDIR)) {
        return false;
    }

    /* cleanup */
    smbcli_unlink(cli1->tree, fname);

    io.generic.level = RAW_OPEN_NTCREATEX;
    io.ntcreatex.in.root_fid.fnum = 0;
    io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    io.ntcreatex.in.alloc_size = 0;
    io.ntcreatex.in.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.security_flags = 0;
    io.ntcreatex.in.fname = fname;
    io.ntcreatex.in.flags = 0;

    /* Open the file sharing none. */
    status = smb_raw_open(cli1->tree, tctx, &io);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");
    fnum = io.ntcreatex.out.file.fnum;

    /* Try to sfileinfo to extend the file. */
    ZERO_STRUCT(sfi);
    sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
    sfi.generic.in.file.path = fname;
    sfi.end_of_file_info.in.size = 100;
    status = smb_raw_setpathinfo(cli2->tree, &sfi);

    /* There should be share mode contention in this case. */
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
                                       "SHARING_VIOLATION");

    /* Make sure the size is still 0. */
    ZERO_STRUCT(qfi);
    qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
    qfi.generic.in.file.path = fname;
    status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");

    torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 0,
                             "alloc_size should be 0 since the setpathinfo failed.");

    /* Try again with the pass through instead of documented version. */
    ZERO_STRUCT(sfi);
    sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    sfi.generic.in.file.path = fname;
    sfi.end_of_file_info.in.size = 100;
    status = smb_raw_setpathinfo(cli2->tree, &sfi);

    /*
     * Looks like a windows bug:
     * http://lists.samba.org/archive/cifs-protocol/2009-November/001130.html
     */
    if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
        /* It succeeds! This is just weird! */
        torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                           ret, done, "Status should be OK");

        /* Verify that the file was actually extended to 100. */
        ZERO_STRUCT(qfi);
        qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
        qfi.generic.in.file.path = fname;
        status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
        torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                           ret, done, "Status should be OK");

        torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 100,
                                 "alloc_size should be 100 since the setpathinfo "
                                 "succeeded.");
    } else {
        torture_assert_ntstatus_equal_goto(tctx, status,
                                           NT_STATUS_SHARING_VIOLATION, ret, done, "Status should be "
                                           "SHARING_VIOLATION");
    }

    /* close the first file. */
    smbcli_close(cli1->tree, fnum);
    fnum = 0;

    /* Try to sfileinfo to extend the file again (non-pass-through). */
    ZERO_STRUCT(sfi);
    sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
    sfi.generic.in.file.path = fname;
    sfi.end_of_file_info.in.size = 200;
    status = smb_raw_setpathinfo(cli2->tree, &sfi);

    /* This should cause the client to retun invalid level. */
    if (TARGET_IS_W2K8(tctx) || TARGET_IS_WIN7(tctx)) {
        /*
         * Windows sends back an invalid packet that smbclient sees
         * and returns INTERNAL_ERROR.
         */
        torture_assert_ntstatus_equal_goto(tctx, status,
                                           NT_STATUS_INTERNAL_ERROR, ret, done, "Status should be "
                                           "INTERNAL_ERROR");
    } else {
        torture_assert_ntstatus_equal_goto(tctx, status,
                                           NT_STATUS_INVALID_LEVEL, ret, done, "Status should be "
                                           "INVALID_LEVEL");
    }

    /* Try to extend the file now with the passthrough level. */
    sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    status = smb_raw_setpathinfo(cli2->tree, &sfi);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");

    /* Verify that the file was actually extended to 200. */
    ZERO_STRUCT(qfi);
    qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
    qfi.generic.in.file.path = fname;
    status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);

    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");
    torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 200,
                             "alloc_size should be 200 since the setpathinfo succeeded.");

    /* Open the file so end of file can be set by handle. */
    io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE;
    status = smb_raw_open(cli1->tree, tctx, &io);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");
    fnum = io.ntcreatex.out.file.fnum;

    /* Try sfileinfo to extend the file by handle (non-pass-through). */
    ZERO_STRUCT(sfi);
    sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
    sfi.generic.in.file.fnum = fnum;
    sfi.end_of_file_info.in.size = 300;
    status = smb_raw_setfileinfo(cli1->tree, &sfi);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");

    /* Verify that the file was actually extended to 300. */
    ZERO_STRUCT(qfi);
    qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
    qfi.generic.in.file.path = fname;
    status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");
    torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 300,
                             "alloc_size should be 300 since the setpathinfo succeeded.");

    /* Try sfileinfo to extend the file by handle (pass-through). */
    ZERO_STRUCT(sfi);
    sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
    sfi.generic.in.file.fnum = fnum;
    sfi.end_of_file_info.in.size = 400;
    status = smb_raw_setfileinfo(cli1->tree, &sfi);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");

    /* Verify that the file was actually extended to 300. */
    ZERO_STRUCT(qfi);
    qfi.generic.level = RAW_FILEINFO_STANDARD_INFO;
    qfi.generic.in.file.path = fname;
    status = smb_raw_pathinfo(cli1->tree, tctx, &qfi);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK, ret,
                                       done, "Status should be OK");
    torture_assert_u64_equal(tctx, qfi.standard_info.out.size, 400,
                             "alloc_size should be 400 since the setpathinfo succeeded.");
done:
    if (fnum > 0) {
        smbcli_close(cli1->tree, fnum);
        fnum = 0;
    }

    smb_raw_exit(cli1->session);
    smb_raw_exit(cli2->session);
    smbcli_deltree(cli1->tree, BASEDIR);
    return ret;
}
Example #25
0
/*
  test SMBntrename ops
*/
static bool test_ntrename(struct torture_context *tctx,
                          struct smbcli_state *cli)
{
    union smb_rename io;
    NTSTATUS status;
    bool ret = true;
    int fnum, i;
    const char *fname1 = BASEDIR "\\test1.txt";
    const char *fname2 = BASEDIR "\\test2.txt";
    union smb_fileinfo finfo;

    torture_comment(tctx, "Testing SMBntrename\n");

    if (!torture_setup_dir(cli, BASEDIR)) {
        return false;
    }

    torture_comment(tctx, "Trying simple rename\n");

    fnum = create_complex_file(cli, tctx, fname1);

    io.generic.level = RAW_RENAME_NTRENAME;
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.cluster_size = 0;
    io.ntrename.in.flags = RENAME_FLAG_RENAME;

    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);

    smbcli_close(cli->tree, fnum);
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Trying self rename\n");
    io.ntrename.in.old_name = fname2;
    io.ntrename.in.new_name = fname2;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

    torture_comment(tctx, "trying wildcard rename\n");
    io.ntrename.in.old_name = BASEDIR "\\*.txt";
    io.ntrename.in.new_name = fname1;

    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);

    torture_comment(tctx, "Checking attrib handling\n");
    torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
    io.ntrename.in.old_name = fname2;
    io.ntrename.in.new_name = fname1;
    io.ntrename.in.attrib = 0;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);

    io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);

    torture_comment(tctx, "Checking hard link\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname2;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 2);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 2);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);

    smbcli_unlink(cli->tree, fname2);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    torture_comment(tctx, "Checking copy\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_COPY;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname2;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname2;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);

    smbcli_unlink(cli->tree, fname2);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);

    torture_comment(tctx, "Checking invalid flags\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = 0;
    status = smb_raw_rename(cli->tree, &io);
    if (TARGET_IS_WIN7(tctx)) {
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    io.ntrename.in.flags = 300;
    status = smb_raw_rename(cli->tree, &io);
    if (TARGET_IS_WIN7(tctx)) {
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    io.ntrename.in.flags = 0x106;
    status = smb_raw_rename(cli->tree, &io);
    if (TARGET_IS_WIN7(tctx)) {
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    torture_comment(tctx, "Checking unknown field\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_RENAME;
    io.ntrename.in.cluster_size = 0xff;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");

    io.ntrename.in.old_name = fname2;
    io.ntrename.in.new_name = fname1;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
    io.ntrename.in.cluster_size = 1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    io.ntrename.in.flags = RENAME_FLAG_COPY;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

#if 0
    {
        char buf[16384];
        fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
        memset(buf, 1, sizeof(buf));
        smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
        smbcli_close(cli->tree, fnum);

        fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
        memset(buf, 1, sizeof(buf));
        smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
        smbcli_close(cli->tree, fnum);

        torture_all_info(cli->tree, fname1);
        torture_all_info(cli->tree, fname2);
    }


    io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    for (i=0; i<20000; i++) {
        io.ntrename.in.cluster_size = i;
        status = smb_raw_rename(cli->tree, &io);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
            torture_warning(tctx, "i=%d status=%s\n", i, nt_errstr(status));
        }
    }
#endif

    torture_comment(tctx, "Checking other flags\n");

    for (i=0; i<0xFFF; i++) {
        if (i == RENAME_FLAG_RENAME ||
                i == RENAME_FLAG_HARD_LINK ||
                i == RENAME_FLAG_COPY) {
            continue;
        }

        io.ntrename.in.old_name = fname2;
        io.ntrename.in.new_name = fname1;
        io.ntrename.in.flags = i;
        io.ntrename.in.attrib = 0;
        io.ntrename.in.cluster_size = 0;
        status = smb_raw_rename(cli->tree, &io);
        if (TARGET_IS_WIN7(tctx)) {
            if (!NT_STATUS_EQUAL(status,
                                 NT_STATUS_INVALID_PARAMETER)) {
                torture_warning(tctx, "flags=0x%x status=%s\n",
                                i, nt_errstr(status));
            }
        } else {
            if (!NT_STATUS_EQUAL(status,
                                 NT_STATUS_ACCESS_DENIED)) {
                torture_warning(tctx, "flags=0x%x status=%s\n",
                                i, nt_errstr(status));
            }
        }
    }

done:
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Example #26
0
static bool
torture_raw_sfileinfo_eof_access(struct torture_context *tctx,
                                 struct smbcli_state *cli1, struct smbcli_state *cli2)
{
    const char *fname = BASEDIR "\\test_exclusive3.dat";
    NTSTATUS status, expected_status;
    bool ret = true;
    union smb_open io;
    union smb_setfileinfo sfi;
    uint16_t fnum=0;
    uint32_t access_mask = 0;

    if (!torture_setup_dir(cli1, BASEDIR)) {
        return false;
    }

    /* cleanup */
    smbcli_unlink(cli1->tree, fname);

    /*
     * base ntcreatex parms
     */
    io.generic.level = RAW_OPEN_NTCREATEX;
    io.ntcreatex.in.root_fid.fnum = 0;
    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_OVERWRITE_IF;
    io.ntcreatex.in.create_options = 0;
    io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    io.ntcreatex.in.security_flags = 0;
    io.ntcreatex.in.fname = fname;
    io.ntcreatex.in.flags = 0;


    for (access_mask = 1; access_mask <= 0x00001FF; access_mask++) {
        io.ntcreatex.in.access_mask = access_mask;

        status = smb_raw_open(cli1->tree, tctx, &io);
        if (!NT_STATUS_IS_OK(status)) {
            continue;
        }

        fnum = io.ntcreatex.out.file.fnum;

        ZERO_STRUCT(sfi);
        sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
        sfi.generic.in.file.fnum = fnum;
        sfi.end_of_file_info.in.size = 100;

        status = smb_raw_setfileinfo(cli1->tree, &sfi);

        expected_status = (access_mask & SEC_FILE_WRITE_DATA) ?
                          NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;

        if (!NT_STATUS_EQUAL(expected_status, status)) {
            torture_comment(tctx, "0x%x wrong\n", access_mask);
        }

        torture_assert_ntstatus_equal_goto(tctx, status,
                                           expected_status, ret, done, "Status Wrong");

        smbcli_close(cli1->tree, fnum);
    }

done:
    smb_raw_exit(cli1->session);
    smb_raw_exit(cli2->session);
    smbcli_deltree(cli1->tree, BASEDIR);
    return ret;
}
Example #27
0
/*
  test dir rename.
*/
static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli)
{
    union smb_open io;
    union smb_rename ren_io;
    NTSTATUS status;
    const char *dname1 = BASEDIR "\\dir_for_rename";
    const char *dname2 = BASEDIR "\\renamed_dir";
    const char *dname1_long = BASEDIR "\\dir_for_rename_long";
    const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
    const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA";
    bool ret = true;
    int fnum = -1;

    torture_comment(tctx, "Checking rename on a directory containing an open file.\n");

    if (!torture_setup_dir(cli, BASEDIR)) {
        return false;
    }

    /* create a directory */
    smbcli_rmdir(cli->tree, dname1);
    smbcli_rmdir(cli->tree, dname2);
    smbcli_rmdir(cli->tree, dname1_long);
    smbcli_unlink(cli->tree, dname1);
    smbcli_unlink(cli->tree, dname2);
    smbcli_unlink(cli->tree, dname1_long);

    ZERO_STRUCT(io);
    io.generic.level = RAW_OPEN_NTCREATEX;
    io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    io.ntcreatex.in.alloc_size = 0;
    io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    io.ntcreatex.in.fname = dname1;
    status = smb_raw_open(cli->tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    fnum = io.ntcreatex.out.file.fnum;
    smbcli_close(cli->tree, fnum);

    /* create the longname directory */
    io.ntcreatex.in.fname = dname1_long;
    status = smb_raw_open(cli->tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    fnum = io.ntcreatex.out.file.fnum;
    smbcli_close(cli->tree, fnum);

    /* Now create and hold open a file. */
    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.alloc_size = 0;
    io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    io.ntcreatex.in.create_options = 0;
    io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    io.ntcreatex.in.security_flags = 0;
    io.ntcreatex.in.fname = fname;

    /* Create the file. */

    status = smb_raw_open(cli->tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    fnum = io.ntcreatex.out.file.fnum;

    /* Now try and rename the directory. */

    ZERO_STRUCT(ren_io);
    ren_io.generic.level = RAW_RENAME_RENAME;
    ren_io.rename.in.pattern1 = dname1;
    ren_io.rename.in.pattern2 = dname2;
    ren_io.rename.in.attrib = 0;

    status = smb_raw_rename(cli->tree, &ren_io);
    CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

    /* Close the file and try the rename. */
    smbcli_close(cli->tree, fnum);

    status = smb_raw_rename(cli->tree, &ren_io);
    CHECK_STATUS(status, NT_STATUS_OK);

    /*
     * Now try just holding a second handle on the directory and holding
     * it open across a rename.  This should be allowed.
     */
    io.ntcreatex.in.fname = dname2;
    io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;

    io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
                                  SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;

    status = smb_raw_open(cli->tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    fnum = io.ntcreatex.out.file.fnum;

    ren_io.generic.level = RAW_RENAME_RENAME;
    ren_io.rename.in.pattern1 = dname2;
    ren_io.rename.in.pattern2 = dname1;
    ren_io.rename.in.attrib = 0;

    status = smb_raw_rename(cli->tree, &ren_io);
    CHECK_STATUS(status, NT_STATUS_OK);

    /* close our handle to the directory. */
    smbcli_close(cli->tree, fnum);

    /* Open a handle on the long name, and then
     * try a rename. This would catch a regression
     * in bug #6781.
     */
    io.ntcreatex.in.fname = dname1_long;
    io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;

    io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
                                  SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;

    status = smb_raw_open(cli->tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    fnum = io.ntcreatex.out.file.fnum;

    ren_io.generic.level = RAW_RENAME_RENAME;
    ren_io.rename.in.pattern1 = dname1;
    ren_io.rename.in.pattern2 = dname2;
    ren_io.rename.in.attrib = 0;

    status = smb_raw_rename(cli->tree, &ren_io);
    CHECK_STATUS(status, NT_STATUS_OK);

    /* close our handle to the longname directory. */
    smbcli_close(cli->tree, fnum);

    /*
     * Now try opening a stream on the directory and holding it open
     * across a rename.  This should be allowed.
     */
    io.ntcreatex.in.fname = sname;

    status = smb_raw_open(cli->tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    fnum = io.ntcreatex.out.file.fnum;

    ren_io.generic.level = RAW_RENAME_RENAME;
    ren_io.rename.in.pattern1 = dname2;
    ren_io.rename.in.pattern2 = dname1;
    ren_io.rename.in.attrib = 0;

    status = smb_raw_rename(cli->tree, &ren_io);
    CHECK_STATUS(status, NT_STATUS_OK);

done:

    if (fnum != -1) {
        smbcli_close(cli->tree, fnum);
    }
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Example #28
0
static bool
torture_raw_sfileinfo_archive(struct torture_context *tctx,
                              struct smbcli_state *cli)
{
    const char *fname = BASEDIR "\\test_archive.dat";
    NTSTATUS status;
    bool ret = true;
    union smb_open io;
    union smb_setfileinfo sfinfo;
    union smb_fileinfo finfo;
    uint16_t fnum=0;

    if (!torture_setup_dir(cli, BASEDIR)) {
        return false;
    }

    /* cleanup */
    smbcli_unlink(cli->tree, fname);

    /*
     * create a normal file, verify archive bit
     */
    io.generic.level = RAW_OPEN_NTCREATEX;
    io.ntcreatex.in.root_fid.fnum = 0;
    io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    io.ntcreatex.in.alloc_size = 0;
    io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    io.ntcreatex.in.create_options = 0;
    io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    io.ntcreatex.in.security_flags = 0;
    io.ntcreatex.in.fname = fname;
    io.ntcreatex.in.flags = 0;
    status = smb_raw_open(cli->tree, tctx, &io);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "open failed");
    fnum = io.ntcreatex.out.file.fnum;

    torture_assert_int_equal(tctx,
                             io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
                             FILE_ATTRIBUTE_ARCHIVE,
                             "archive bit not set");

    /*
     * try to turn off archive bit
     */
    ZERO_STRUCT(sfinfo);
    sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
    sfinfo.generic.in.file.fnum = fnum;
    sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
    status = smb_raw_setfileinfo(cli->tree, &sfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "setfileinfo failed");

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.fnum = fnum;
    status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "fileinfo failed");

    torture_assert_int_equal(tctx,
                             finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
                             FILE_ATTRIBUTE_NORMAL,
                             "archive bit set");

    status = smbcli_close(cli->tree, fnum);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "close failed");

    status = smbcli_unlink(cli->tree, fname);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "unlink failed");

    /*
     * create a directory, verify no archive bit
     */
    io.generic.level = RAW_OPEN_NTCREATEX;
    io.ntcreatex.in.root_fid.fnum = 0;
    io.ntcreatex.in.access_mask = SEC_RIGHTS_DIR_ALL;
    io.ntcreatex.in.alloc_size = 0;
    io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    io.ntcreatex.in.security_flags = 0;
    io.ntcreatex.in.fname = fname;
    io.ntcreatex.in.flags = 0;
    status = smb_raw_open(cli->tree, tctx, &io);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "directory open failed");
    fnum = io.ntcreatex.out.file.fnum;

    torture_assert_int_equal(tctx,
                             io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
                             FILE_ATTRIBUTE_DIRECTORY,
                             "archive bit set");

    /*
     * verify you can turn on archive bit
     */
    sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
    sfinfo.generic.in.file.fnum = fnum;
    sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE;
    status = smb_raw_setfileinfo(cli->tree, &sfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "setfileinfo failed");

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.fnum = fnum;
    status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "fileinfo failed");

    torture_assert_int_equal(tctx,
                             finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
                             FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE,
                             "archive bit not set");

    /*
     * and try to turn it back off
     */
    sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFO;
    sfinfo.generic.in.file.fnum = fnum;
    sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
    status = smb_raw_setfileinfo(cli->tree, &sfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "setfileinfo failed");

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.fnum = fnum;
    status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "fileinfo failed");

    torture_assert_int_equal(tctx,
                             finfo.all_info.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED,
                             FILE_ATTRIBUTE_DIRECTORY,
                             "archive bit set");

    status = smbcli_close(cli->tree, fnum);
    torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OK,
                                       ret, done, "close failed");

done:
    smbcli_close(cli->tree, fnum);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Example #29
0
/*
 * basic testing of all RAW_SFILEINFO_RENAME call
 */
static bool
torture_raw_sfileinfo_rename(struct torture_context *torture,
                             struct smbcli_state *cli)
{
    bool ret = true;
    int fnum_saved, d_fnum, fnum2, fnum = -1;
    char *fnum_fname;
    char *fnum_fname_new;
    char *path_fname;
    char *path_fname_new;
    char *path_dname;
    char *path_dname_new;
    char *saved_name;
    char *saved_name_new;
    union smb_fileinfo finfo1, finfo2;
    union smb_setfileinfo sfinfo;
    NTSTATUS status, status2;
    const char *call_name;
    bool check_fnum;
    int n = time(NULL) % 100;

    asprintf(&path_fname, BASEDIR "\\fname_test_%d.txt", n);
    asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
    asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
    asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
    asprintf(&path_dname, BASEDIR "\\dname_test_%d", n);
    asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n);

    if (!torture_setup_dir(cli, BASEDIR)) {
        return false;
    }

    RECREATE_BOTH;

    ZERO_STRUCT(sfinfo);

    smbcli_close(cli->tree, create_complex_file(cli, torture, fnum_fname_new));
    smbcli_close(cli->tree, create_complex_file(cli, torture, path_fname_new));

    sfinfo.rename_information.in.overwrite = 0;
    sfinfo.rename_information.in.root_fid  = 0;
    sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);

    sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
    CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OBJECT_NAME_COLLISION);

    sfinfo.rename_information.in.new_name  = fnum_fname_new;
    sfinfo.rename_information.in.overwrite = 1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_NOT_SUPPORTED);

    sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);

    printf("Trying rename with dest file open\n");
    fnum2 = create_complex_file(cli, torture, fnum_fname);
    sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);

    fnum_saved = fnum;
    fnum = fnum2;
    sfinfo.disposition_info.in.delete_on_close = 1;
    CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
    fnum = fnum_saved;

    printf("Trying rename with dest file open and delete_on_close\n");
    sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_ACCESS_DENIED);

    smbcli_close(cli->tree, fnum2);
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);

    printf("Trying rename with source file open twice\n");
    sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);

    fnum2 = create_complex_file(cli, torture, fnum_fname);
    sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 0;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname_new);
    smbcli_close(cli->tree, fnum2);

    sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 0;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);

    sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 1;
    CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);

    sfinfo.rename_information.in.new_name  = fnum_fname+strlen(BASEDIR)+1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);

    sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
    CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);

    printf("Trying rename with a root fid\n");
    status = create_directory_handle(cli->tree, BASEDIR, &d_fnum);
    CHECK_STATUS(status, NT_STATUS_OK);
    sfinfo.rename_information.in.new_name  = fnum_fname_new+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.root_fid = d_fnum;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
    CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
    smbcli_close(cli->tree, d_fnum);

    printf("Trying rename directory\n");
    if (!torture_setup_dir(cli, path_dname)) {
        ret = false;
        goto done;
    }
    saved_name = path_fname;
    saved_name_new = path_fname_new;
    path_fname = path_dname;
    path_fname_new = path_dname_new;
    sfinfo.rename_information.in.new_name  = path_dname_new+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 0;
    sfinfo.rename_information.in.root_fid  = 0;
    CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
    path_fname = saved_name;
    path_fname_new = saved_name_new;

    if (torture_setting_bool(torture, "samba3", false)) {
        printf("SKIP: Trying rename directory with a handle\n");
        printf("SKIP: Trying rename by path while a handle is open\n");
        printf("SKIP: Trying rename directory by path while a handle is open\n");
        goto done;
    }

    printf("Trying rename directory with a handle\n");
    status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
    fnum_saved = fnum;
    fnum = d_fnum;
    saved_name = fnum_fname;
    saved_name_new = fnum_fname_new;
    fnum_fname = path_dname;
    fnum_fname_new = path_dname_new;
    sfinfo.rename_information.in.new_name  = path_dname+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 0;
    sfinfo.rename_information.in.root_fid  = 0;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
    smbcli_close(cli->tree, d_fnum);
    fnum = fnum_saved;
    fnum_fname = saved_name;
    fnum_fname_new = saved_name_new;

    printf("Trying rename by path while a handle is open\n");
    fnum_saved = fnum;
    fnum = create_complex_file(cli, torture, path_fname);
    sfinfo.rename_information.in.new_name  = path_fname_new+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 0;
    sfinfo.rename_information.in.root_fid  = 0;
    CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
    /* check that the handle returns the same name */
    check_fnum = true;
    CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
    /* rename it back on the handle */
    sfinfo.rename_information.in.new_name  = path_fname+strlen(BASEDIR)+1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
    check_fnum = false;
    CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
    smbcli_close(cli->tree, fnum);
    fnum = fnum_saved;

    printf("Trying rename directory by path while a handle is open\n");
    status = create_directory_handle(cli->tree, path_dname, &d_fnum);
    fnum_saved = fnum;
    fnum = d_fnum;
    saved_name = path_fname;
    saved_name_new = path_fname_new;
    path_fname = path_dname;
    path_fname_new = path_dname_new;
    sfinfo.rename_information.in.new_name  = path_dname_new+strlen(BASEDIR)+1;
    sfinfo.rename_information.in.overwrite = 0;
    sfinfo.rename_information.in.root_fid  = 0;
    CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
    path_fname = saved_name;
    path_fname_new = saved_name_new;
    saved_name = fnum_fname;
    saved_name_new = fnum_fname_new;
    fnum_fname = path_dname;
    fnum_fname_new = path_dname_new;
    /* check that the handle returns the same name */
    check_fnum = true;
    CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
    /* rename it back on the handle */
    sfinfo.rename_information.in.new_name  = path_dname+strlen(BASEDIR)+1;
    CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
    CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
    fnum_fname = saved_name;
    fnum_fname_new = saved_name_new;
    saved_name = path_fname;
    saved_name_new = path_fname_new;
    path_fname = path_dname;
    path_fname_new = path_dname_new;
    check_fnum = false;
    CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
    smbcli_close(cli->tree, d_fnum);
    fnum = fnum_saved;
    path_fname = saved_name;
    path_fname_new = saved_name_new;

done:
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Example #30
0
/*
  test dir rename.
*/
static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli)
{
        union smb_open io;
	union smb_rename ren_io;
	NTSTATUS status;
        const char *dname1 = BASEDIR "\\dir_for_rename";
        const char *dname2 = BASEDIR "\\renamed_dir";
        const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
	bool ret = true;
	int fnum = -1;

        printf("Checking rename on a directory containing an open file.\n");

	if (!torture_setup_dir(cli, BASEDIR)) {
		return false;
	}

        /* create a directory */
        smbcli_rmdir(cli->tree, dname1);
        smbcli_rmdir(cli->tree, dname2);
        smbcli_unlink(cli->tree, dname1);
        smbcli_unlink(cli->tree, dname2);

        ZERO_STRUCT(io);
        io.generic.level = RAW_OPEN_NTCREATEX;
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        io.ntcreatex.in.alloc_size = 0;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
        io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
        io.ntcreatex.in.fname = dname1;
        status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);

        fnum = io.ntcreatex.out.file.fnum;
	smbcli_close(cli->tree, fnum);

        /* Now create and hold open a file. */
        ZERO_STRUCT(io);

        io.generic.level = RAW_OPEN_NTCREATEX;
        io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
        io.ntcreatex.in.root_fid = 0;
        io.ntcreatex.in.alloc_size = 0;
        io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
        io.ntcreatex.in.create_options = 0;
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
        io.ntcreatex.in.security_flags = 0;
        io.ntcreatex.in.fname = fname;

        /* Create the file. */

        status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.file.fnum;

        /* Now try and rename the directory. */

        ZERO_STRUCT(ren_io);
	ren_io.generic.level = RAW_RENAME_RENAME;
	ren_io.rename.in.pattern1 = dname1;
	ren_io.rename.in.pattern2 = dname2;
	ren_io.rename.in.attrib = 0;
	
	status = smb_raw_rename(cli->tree, &ren_io);
	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);

done:
	
	if (fnum != -1) {
		smbcli_close(cli->tree, fnum);
	}
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}