Exemplo n.º 1
0
static bool test_session_reauth1(struct torture_context *tctx,
				 struct smbcli_state *cli)
{
	NTSTATUS status;
	struct smb_composite_sesssetup io;
	int fnum, num;
	const int dlen = 255;
	char *data;
	char fname[256];
	char buf[dlen+1];
	bool ok = true;
	uint16_t vuid1 = cli->session->vuid;

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

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

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

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

	buf[dlen] = '\0';

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

done:
	talloc_free(data);

	if (fnum > 0) {
		status = smbcli_close(cli->tree, fnum);
		torture_assert_ntstatus_ok(tctx, status, "close");
	}
	return ok;
}
Exemplo n.º 2
0
NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx,
		       struct smbcli_state *cli,
		       const char *nt_path,
		       const char *unix_path)
{
	NTSTATUS result;
	int fnum;
	int fd = 0;
	char *data = NULL;
	static int io_bufsize = 64512;
	int read_size = io_bufsize;
	off_t nread = 0;

	if ((fnum = smbcli_open(cli->tree, nt_path, O_RDONLY, DENY_NONE)) == -1) {
		result = NT_STATUS_NO_SUCH_FILE;
		goto out;
	}

	if ((fd = open(unix_path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) {
		result = map_nt_error_from_unix(errno);
		goto out;
	}

	if ((data = talloc_size(mem_ctx, read_size)) == NULL) {
		result = NT_STATUS_NO_MEMORY;
		goto out;
	}

	while (1) {

		int n = smbcli_read(cli->tree, fnum, data, nread, read_size);

		if (n <= 0)
			break;

		if (write(fd, data, n) != n) {
			break;
		}

		nread += n;
	}

	result = NT_STATUS_OK;

 out:
	SAFE_FREE(data);
	if (fnum) {
		smbcli_close(cli->tree, fnum);
	}
	if (fd) {
		close(fd);
	}

	return result;
}
Exemplo n.º 3
0
/*
  check that a stream has the right contents
*/
static BOOL check_stream(struct smbcli_state *cli, TALLOC_CTX *mem_ctx,
			 const char *fname, const char *sname, 
			 const char *value)
{
	int fnum;
	const char *full_name;
	uint8_t *buf;
	ssize_t ret;

	full_name = talloc_asprintf(mem_ctx, "%s:%s", fname, sname);

	fnum = smbcli_open(cli->tree, full_name, O_RDONLY, DENY_NONE);

	if (value == NULL) {
		if (fnum != -1) {
			printf("should have failed stream open of %s\n", full_name);
			return False;
		}
		return True;
	}
	    
	if (fnum == -1) {
		printf("Failed to open stream '%s' - %s\n", 
		       full_name, smbcli_errstr(cli->tree));
		return False;
	}

	buf = talloc_size(mem_ctx, strlen(value)+11);
	
	ret = smbcli_read(cli->tree, fnum, buf, 0, strlen(value)+11);
	if (ret != strlen(value)) {
		printf("Failed to read %lu bytes from stream '%s' - got %d\n",
		       (long)strlen(value), full_name, (int)ret);
		return False;
	}

	if (memcmp(buf, value, strlen(value)) != 0) {
		printf("Bad data in stream\n");
		return False;
	}

	smbcli_close(cli->tree, fnum);
	return True;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
bool torture_casetable(struct torture_context *tctx, 
					   struct smbcli_state *cli)
{
	char *fname;
	int fnum;
	int c, i;
#define MAX_EQUIVALENCE 8
	codepoint_t equiv[0x10000][MAX_EQUIVALENCE];

	torture_comment(tctx, "Determining upper/lower case table\n");

	memset(equiv, 0, sizeof(equiv));

	torture_assert(tctx, torture_setup_dir(cli, "\\utable"),
				   "Error setting up dir \\utable");

	for (c=1; c < 0x10000; c++) {
		size_t size;

		if (c == '.' || c == '\\') continue;

		torture_comment(tctx, "%04x (%c)\n", c, isprint(c)?c:'.');

		fname = form_name(lp_iconv_convenience(tctx->lp_ctx), c);
		fnum = smbcli_nt_create_full(cli->tree, fname, 0,
#if 0
					     SEC_RIGHT_MAXIMUM_ALLOWED, 
#else
					     SEC_RIGHTS_FILE_ALL,
#endif
					     FILE_ATTRIBUTE_NORMAL,
					     NTCREATEX_SHARE_ACCESS_NONE,
					     NTCREATEX_DISP_OPEN_IF, 0, 0);

		torture_assert(tctx, fnum != -1, 
					   talloc_asprintf(tctx, 
			"Failed to create file with char %04x\n", c));

		size = 0;

		if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, 
						   NULL, NULL, NULL, NULL, NULL))) continue;

		if (size > 0) {
			/* found a character equivalence! */
			int c2[MAX_EQUIVALENCE];

			if (size/sizeof(int) >= MAX_EQUIVALENCE) {
				torture_comment(tctx, "too many chars match?? size=%d c=0x%04x\n",
				       (int)size, c);
				smbcli_close(cli->tree, fnum);
				return false;
			}

			smbcli_read(cli->tree, fnum, c2, 0, size);
			torture_comment(tctx, "%04x: ", c);
			equiv[c][0] = c;
			for (i=0; i<size/sizeof(int); i++) {
				torture_comment(tctx, "%04x ", c2[i]);
				equiv[c][i+1] = c2[i];
			}
			torture_comment(tctx, "\n");
		}

		smbcli_write(cli->tree, fnum, 0, &c, size, sizeof(c));
		smbcli_close(cli->tree, fnum);
	}

	smbcli_unlink(cli->tree, "\\utable\\*");
	smbcli_rmdir(cli->tree, "\\utable");

	return true;
}
Exemplo n.º 7
0
Arquivo: misc.c Projeto: endisd/samba
static bool rw_torture(struct torture_context *tctx, struct smbcli_state *c)
{
	const char *lockfname = "\\torture.lck";
	char *fname;
	int fnum;
	int fnum2;
	pid_t pid2, pid = getpid();
	int i, j;
	uint8_t buf[1024];
	bool correct = true;

	fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL, 
			 DENY_NONE);
	if (fnum2 == -1)
		fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
	if (fnum2 == -1) {
		torture_comment(tctx, "open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
		return false;
	}

	generate_random_buffer(buf, sizeof(buf));

	for (i=0;i<torture_numops;i++) {
		uint_t n = (uint_t)random()%10;
		if (i % 10 == 0) {
			if (torture_setting_bool(tctx, "progress", true)) {
				torture_comment(tctx, "%d\r", i);
				fflush(stdout);
			}
		}
		asprintf(&fname, "\\torture.%u", n);

		if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
			return false;
		}

		fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
		if (fnum == -1) {
			torture_comment(tctx, "open failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
			break;
		}

		if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
			torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		for (j=0;j<50;j++) {
			if (smbcli_write(c->tree, fnum, 0, buf, 
				      sizeof(pid)+(j*sizeof(buf)), 
				      sizeof(buf)) != sizeof(buf)) {
				torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));
				correct = false;
			}
		}

		pid2 = 0;

		if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
			torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		if (pid2 != pid) {
			torture_comment(tctx, "data corruption!\n");
			correct = false;
		}

		if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
			torture_comment(tctx, "close failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
			torture_comment(tctx, "unlink failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
			torture_comment(tctx, "unlock failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}
		free(fname);
	}

	smbcli_close(c->tree, fnum2);
	smbcli_unlink(c->tree, lockfname);

	torture_comment(tctx, "%d\n", i);

	return correct;
}
Exemplo n.º 8
0
static bool torture_locktest7(struct torture_context *tctx, 
			      struct smbcli_state *cli1)
{
	const char *fname = BASEDIR "\\lockt7.lck";
	int fnum1;
	int fnum2 = -1;
	size_t size;
	uint8_t buf[200];
	bool correct = false;

	torture_assert(tctx, torture_setup_dir(cli1, BASEDIR),
				   talloc_asprintf(tctx, "Unable to set up %s", BASEDIR));

	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);

	memset(buf, 0, sizeof(buf));

	torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) == sizeof(buf),
		"Failed to create file");

	cli1->session->pid = 1;

	torture_assert_ntstatus_ok(tctx, smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK),
		talloc_asprintf(tctx, "Unable to apply read lock on range 130:4, error was %s", 
		       smbcli_errstr(cli1->tree)));

	torture_comment(tctx, "pid1 successfully locked range 130:4 for READ\n");

	torture_assert(tctx, smbcli_read(cli1->tree, fnum1, buf, 130, 4) == 4, 
		 	talloc_asprintf(tctx, "pid1 unable to read the range 130:4, error was %s)", 
		       smbcli_errstr(cli1->tree)));

	torture_comment(tctx, "pid1 successfully read the range 130:4\n");

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
		torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT,
			"Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
	} else {
		torture_fail(tctx, "pid1 successfully wrote to the range 130:4 (should be denied)");
	}

	cli1->session->pid = 2;

	if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
	} else {
		torture_comment(tctx, "pid2 successfully read the range 130:4\n");
	}

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
		torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT, 
			"Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
	} else {
		torture_fail(tctx, "pid2 successfully wrote to the range 130:4 (should be denied)"); 
	}

	cli1->session->pid = 1;
	smbcli_unlock(cli1->tree, fnum1, 130, 4);

	torture_assert_ntstatus_ok(tctx, smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK),
		talloc_asprintf(tctx, "Unable to apply write lock on range 130:4, error was %s", 
		       smbcli_errstr(cli1->tree)));
	torture_comment(tctx, "pid1 successfully locked range 130:4 for WRITE\n");

	torture_assert(tctx, smbcli_read(cli1->tree, fnum1, buf, 130, 4) == 4, 
		talloc_asprintf(tctx, "pid1 unable to read the range 130:4, error was %s", 
		       smbcli_errstr(cli1->tree)));
	torture_comment(tctx, "pid1 successfully read the range 130:4\n");

	torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) == 4, 
		talloc_asprintf(tctx, "pid1 unable to write to the range 130:4, error was %s",
		       smbcli_errstr(cli1->tree)));
	torture_comment(tctx, "pid1 successfully wrote to the range 130:4\n");

	cli1->session->pid = 2;

	if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to read the range 130:4, error was %s\n", 
		       smbcli_errstr(cli1->tree));
		torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT, 
			"Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
	} else {
		torture_fail(tctx, "pid2 successfully read the range 130:4 (should be denied)");
	}

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to write to the range 130:4, error was %s\n", 
		       smbcli_errstr(cli1->tree));
		if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT)) {
			torture_comment(tctx, "Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT) (%s)\n",
			       __location__);
			goto fail;
		}
	} else {
		torture_comment(tctx, "pid2 successfully wrote to the range 130:4 (should be denied) (%s)\n", 
		       __location__);
		goto fail;
	}

	torture_comment(tctx, "Testing truncate of locked file.\n");

	fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);

	torture_assert(tctx, fnum2 != -1, "Unable to truncate locked file");

	torture_comment(tctx, "Truncated locked file.\n");

	torture_assert_ntstatus_ok(tctx, smbcli_getatr(cli1->tree, fname, NULL, &size, NULL), 
		talloc_asprintf(tctx, "getatr failed (%s)", smbcli_errstr(cli1->tree)));

	torture_assert(tctx, size == 0, talloc_asprintf(tctx, "Unable to truncate locked file. Size was %u", (unsigned)size));

	cli1->session->pid = 1;

	smbcli_unlock(cli1->tree, fnum1, 130, 4);
	correct = true;

fail:
	smbcli_close(cli1->tree, fnum1);
	smbcli_close(cli1->tree, fnum2);
	smbcli_unlink(cli1->tree, fname);

	return correct;
}
Exemplo n.º 9
0
/*
  looks at overlapping locks
*/
static bool torture_locktest4(struct torture_context *tctx, 
			      struct smbcli_state *cli1,
			      struct smbcli_state *cli2)
{
	const char *fname = BASEDIR "\\lockt4.lck";
	int fnum1, fnum2, f;
	bool ret;
	uint8_t buf[1000];
	bool correct = true;

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

	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
	fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);

	memset(buf, 0, sizeof(buf));

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
		torture_comment(tctx, "Failed to create file\n");
		correct = false;
		goto fail;
	}

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s set overlapping write locks\n", ret?"can":"cannot");
	    
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s set overlapping read locks\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "a different connection %s set overlapping write locks\n", ret?"can":"cannot");
	    
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
		NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "a different connection %s set overlapping read locks\n", ret?"can":"cannot");
	
	ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
	      NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
	EXPECTED(ret, false);
	torture_comment(tctx, "a different pid %s set overlapping write locks\n", ret?"can":"cannot");
	    
	ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
	      NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
	EXPECTED(ret, true);
	torture_comment(tctx, "a different pid %s set overlapping read locks\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s set the same read lock twice\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s set the same write lock twice\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
	      NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
	EXPECTED(ret, false);
	torture_comment(tctx, "a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s coalesce read locks\n", ret?"can":"cannot");


	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
	      (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
	EXPECTED(ret, false);
	torture_comment(tctx, "this server %s strict write locking\n", ret?"doesn't do":"does");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
	      (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
	EXPECTED(ret, false);
	torture_comment(tctx, "this server %s strict read locking\n", ret?"doesn't do":"does");


	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
	EXPECTED(ret, true);
	torture_comment(tctx, "this server %s do recursive read locking\n", ret?"does":"doesn't");


	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
	      (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
	      !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
	EXPECTED(ret, true);
	torture_comment(tctx, "this server %s do recursive lock overlays\n", ret?"does":"doesn't");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
	      (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&		
	      (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);		
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s remove a read lock using write locking\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
	      (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&		
	      (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);		
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s remove a write lock using read locking\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
	      !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&		
	      (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);		
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s remove the first lock first\n", ret?"does":"doesn't");

	smbcli_close(cli1->tree, fnum1);
	smbcli_close(cli2->tree, fnum2);
	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
	f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
	      ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
        smbcli_close(cli1->tree, f);
	smbcli_close(cli1->tree, fnum1);
	EXPECTED(ret, true);
	torture_comment(tctx, "the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");

 fail:
	smbcli_close(cli1->tree, fnum1);
	smbcli_close(cli2->tree, fnum2);
	smbcli_unlink(cli1->tree, fname);

	return correct;
}
Exemplo n.º 10
0
/*
  test write ops
*/
static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_write io;
	NTSTATUS status;
	BOOL ret = True;
	int fnum;
	uint8_t *buf;
	const int maxsize = 90000;
	const char *fname = BASEDIR "\\test.txt";
	uint_t seed = time(NULL);
	union smb_fileinfo finfo;

	buf = talloc_zero_size(mem_ctx, maxsize);

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

	printf("Testing RAW_WRITE_WRITE\n");
	io.generic.level = RAW_WRITE_WRITE;
	
	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 zero write\n");
	io.write.in.file.fnum = fnum;
	io.write.in.count = 0;
	io.write.in.offset = 0;
	io.write.in.remaining = 0;
	io.write.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.write.out.nwritten, 0);

	setup_buffer(buf, seed, maxsize);

	printf("Trying small write\n");
	io.write.in.count = 9;
	io.write.in.offset = 4;
	io.write.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.write.out.nwritten, io.write.in.count);

	memset(buf, 0, maxsize);
	if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
		printf("read failed at %s\n", __location__);
		ret = False;
		goto done;
	}
	CHECK_BUFFER(buf+4, seed, 9);
	CHECK_VALUE(IVAL(buf,0), 0);

	setup_buffer(buf, seed, maxsize);

	printf("Trying large write\n");
	io.write.in.count = 4000;
	io.write.in.offset = 0;
	io.write.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.write.out.nwritten, 4000);

	memset(buf, 0, maxsize);
	if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
		printf("read failed at %s\n", __location__);
		ret = False;
		goto done;
	}
	CHECK_BUFFER(buf, seed, 4000);

	printf("Trying bad fnum\n");
	io.write.in.file.fnum = fnum+1;
	io.write.in.count = 4000;
	io.write.in.offset = 0;
	io.write.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("Setting file as sparse\n");
	status = torture_set_sparse(cli->tree, fnum);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
		printf("skipping large file tests - CAP_LARGE_FILES not set\n");
		goto done;
	}
	
	if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
		printf("skipping large file tests - CAP_LARGE_FILES not set\n");
		goto done;
	}

	printf("Trying 2^32 offset\n");
	setup_buffer(buf, seed, maxsize);
	io.write.in.file.fnum = fnum;
	io.write.in.count = 4000;
	io.write.in.offset = 0xFFFFFFFF - 2000;
	io.write.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.write.out.nwritten, 4000);
	CHECK_ALL_INFO(io.write.in.count + (uint64_t)io.write.in.offset, size);
	
	memset(buf, 0, maxsize);
	if (smbcli_read(cli->tree, fnum, buf, io.write.in.offset, 4000) != 4000) {
		printf("read failed at %s\n", __location__);
		ret = False;
		goto done;
	}
	CHECK_BUFFER(buf, seed, 4000);

done:
	smbcli_close(cli->tree, fnum);
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemplo n.º 11
0
/*
  test writex ops
*/
static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_write io;
	NTSTATUS status;
	BOOL ret = True;
	int fnum, i;
	uint8_t *buf;
	const int maxsize = 90000;
	const char *fname = BASEDIR "\\test.txt";
	uint_t seed = time(NULL);
	union smb_fileinfo finfo;
	int max_bits=63;

	if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
		max_bits=33;
		printf("dangerous not set - limiting range of test to 2^%d\n", max_bits);
	}

	buf = talloc_zero_size(mem_ctx, maxsize);

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

	printf("Testing RAW_WRITE_WRITEX\n");
	io.generic.level = RAW_WRITE_WRITEX;
	
	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 zero write\n");
	io.writex.in.file.fnum = fnum;
	io.writex.in.offset = 0;
	io.writex.in.wmode = 0;
	io.writex.in.remaining = 0;
	io.writex.in.count = 0;
	io.writex.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.writex.out.nwritten, 0);

	setup_buffer(buf, seed, maxsize);

	printf("Trying small write\n");
	io.writex.in.count = 9;
	io.writex.in.offset = 4;
	io.writex.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);

	memset(buf, 0, maxsize);
	if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
		printf("read failed at %s\n", __location__);
		ret = False;
		goto done;
	}
	CHECK_BUFFER(buf+4, seed, 9);
	CHECK_VALUE(IVAL(buf,0), 0);

	setup_buffer(buf, seed, maxsize);

	printf("Trying large write\n");
	io.writex.in.count = 4000;
	io.writex.in.offset = 0;
	io.writex.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.writex.out.nwritten, 4000);

	memset(buf, 0, maxsize);
	if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
		printf("read failed at %s\n", __location__);
		ret = False;
		goto done;
	}
	CHECK_BUFFER(buf, seed, 4000);

	printf("Trying bad fnum\n");
	io.writex.in.file.fnum = fnum+1;
	io.writex.in.count = 4000;
	io.writex.in.offset = 0;
	io.writex.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("Testing wmode\n");
	io.writex.in.file.fnum = fnum;
	io.writex.in.count = 1;
	io.writex.in.offset = 0;
	io.writex.in.wmode = 1;
	io.writex.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);

	io.writex.in.wmode = 2;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);


	printf("Trying locked region\n");
	cli->session->pid++;
	if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 3, 1, 0, WRITE_LOCK))) {
		printf("Failed to lock file at %s\n", __location__);
		ret = False;
		goto done;
	}
	cli->session->pid--;
	io.writex.in.wmode = 0;
	io.writex.in.count = 4;
	io.writex.in.offset = 0;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);

	printf("Setting file as sparse\n");
	status = torture_set_sparse(cli->tree, fnum);
	CHECK_STATUS(status, NT_STATUS_OK);
	
	if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
		printf("skipping large file tests - CAP_LARGE_FILES not set\n");
		goto done;
	}

	printf("Trying 2^32 offset\n");
	setup_buffer(buf, seed, maxsize);
	io.writex.in.file.fnum = fnum;
	io.writex.in.count = 4000;
	io.writex.in.offset = 0xFFFFFFFF - 2000;
	io.writex.in.data = buf;
	status = smb_raw_write(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.writex.out.nwritten, 4000);
	CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);

	memset(buf, 0, maxsize);
	if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
		printf("read failed at %s\n", __location__);
		ret = False;
		goto done;
	}
	CHECK_BUFFER(buf, seed, 4000);

	for (i=33;i<max_bits;i++) {
		printf("Trying 2^%d offset\n", i);
		setup_buffer(buf, seed+1, maxsize);
		io.writex.in.file.fnum = fnum;
		io.writex.in.count = 4000;
		io.writex.in.offset = ((uint64_t)1) << i;
		io.writex.in.data = buf;
		status = smb_raw_write(cli->tree, &io);
		if (i>33 &&
		    NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
			break;
		}
		CHECK_STATUS(status, NT_STATUS_OK);
		CHECK_VALUE(io.writex.out.nwritten, 4000);
		CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);

		memset(buf, 0, maxsize);
		if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
			printf("read failed at %s\n", __location__);
			ret = False;
			goto done;
		}
		CHECK_BUFFER(buf, seed+1, 4000);
	}
	printf("limit is 2^%d\n", i);

	setup_buffer(buf, seed, maxsize);

done:
	smbcli_close(cli->tree, fnum);
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemplo n.º 12
0
static NTSTATUS gp_get_file (struct smbcli_tree *tree, const char *remote_src,
                             const char *local_dst)
{
	int fh_remote, fh_local;
	uint8_t *buf;
	size_t nread = 0;
	size_t buf_size = 1024;
	size_t file_size;
	uint16_t attr;

	/* Open the remote file */
	fh_remote = smbcli_open(tree, remote_src, O_RDONLY, DENY_NONE);
	if (fh_remote == -1) {
		DEBUG(0, ("Failed to open remote file: %s\n", remote_src));
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* Open the local file */
	fh_local = open(local_dst, O_WRONLY | O_CREAT | O_TRUNC, 0644);
	if (fh_local == -1) {
		DEBUG(0, ("Failed to open local file: %s\n", local_dst));
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* Get the remote file size for error checking */
	if (NT_STATUS_IS_ERR(smbcli_qfileinfo(tree, fh_remote,
				&attr, &file_size, NULL, NULL, NULL, NULL, NULL)) &&
			NT_STATUS_IS_ERR(smbcli_getattrE(tree, fh_remote,
				&attr, &file_size, NULL, NULL, NULL))) {
		DEBUG(0, ("Failed to get remote file size: %s\n", smbcli_errstr(tree)));
		return NT_STATUS_UNSUCCESSFUL;
	}

	buf = talloc_zero_array(tree, uint8_t, buf_size);
	NT_STATUS_HAVE_NO_MEMORY(buf);

	/* Copy the contents of the file */
	while (1) {
		int n = smbcli_read(tree, fh_remote, buf, nread, buf_size);

		if (n <= 0) {
			break;
		}

		if (write(fh_local, buf, n) != n) {
			DEBUG(0, ("Short write while copying file.\n"));
			talloc_free(buf);
			return NT_STATUS_UNSUCCESSFUL;
		}
		nread += n;
	}

	/* Bytes read should match the file size, or the copy was incomplete */
	if (nread != file_size) {
		DEBUG(0, ("Remote/local file size mismatch after copying file: "
		          "%s (remote %zu, local %zu).\n",
		          remote_src, file_size, nread));
		talloc_free(buf);
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* Close the files */
	smbcli_close(tree, fh_remote);
	close(fh_local);

	talloc_free(buf);
	return NT_STATUS_OK;
}