Пример #1
0
static int ejs_mkdir(MprVarHandle eid, int argc, MprVar **argv)
{
	struct smbcli_tree *tree;
	NTSTATUS result;

	if (argc != 2) {
		ejsSetErrorMsg(eid, "mkdir(): invalid number of args");
		return -1;
	}

	if (!IS_TREE_HANDLE(argv[0])) {
		ejsSetErrorMsg(eid, "first arg is not a tree handle");
		return -1;
	}

	tree = argv[0]->ptr;

	if (!mprVarIsString(argv[1]->type)) {
		ejsSetErrorMsg(eid, "arg 2 must be a string");
		return -1;
	}

	result = smbcli_mkdir(tree, argv[1]->string);

	mpr_Return(eid, mprNTSTATUS(result));

	return 0;
}
Пример #2
0
static void test_mask(int argc, char *argv[],
					  TALLOC_CTX *mem_ctx,
		      struct smbcli_state *cli)
{
	char *mask, *file;
	int l1, l2, i, l;
	int mc_len = strlen(maskchars);
	int fc_len = strlen(filechars);

	smbcli_mkdir(cli->tree, "\\masktest");

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

	if (argc >= 2) {
		while (argc >= 2) {
			mask = talloc_strdup(mem_ctx, "\\masktest\\");
			file = talloc_strdup(mem_ctx, "\\masktest\\");
			mask = talloc_strdup_append(mask, argv[0]);
			file = talloc_strdup_append(file, argv[1]);
			testpair(mem_ctx, cli, mask, file);
			argv += 2;
			argc -= 2;
		}
		goto finished;
	}

	while (1) {
		l1 = 1 + random() % max_length;
		l2 = 1 + random() % max_length;
		mask = talloc_strdup(mem_ctx, "\\masktest\\");
		file = talloc_strdup(mem_ctx, "\\masktest\\");
		mask = talloc_realloc_size(mem_ctx, mask, strlen(mask)+l1+1);
		file = talloc_realloc_size(mem_ctx, file, strlen(file)+l2+1);
		l = strlen(mask);
		for (i=0;i<l1;i++) {
			mask[i+l] = maskchars[random() % mc_len];
		}
		mask[l+l1] = 0;

		for (i=0;i<l2;i++) {
			file[i+l] = filechars[random() % fc_len];
		}
		file[l+l2] = 0;

		if (ISDOT(file+l) || ISDOTDOT(file+l) || ISDOTDOT(mask+l)) {
			continue;
		}

		if (strspn(file+l, ".") == strlen(file+l)) continue;

		testpair(mem_ctx, cli, mask, file);
		if (NumLoops && (--NumLoops == 0))
			break;
	}

 finished:
	smbcli_rmdir(cli->tree, "\\masktest");
	talloc_free(mem_ctx);
}
Пример #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;
}
Пример #4
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;
}
Пример #5
0
NTSTATUS gp_push_gpt(struct gp_context *gp_ctx, const char *local_path,
                     const char *file_sys_path)
{
	NTSTATUS status;
	char *share_path;

	if (gp_ctx->cli == NULL) {
		status = gp_cli_connect(gp_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Failed to create cli connection to DC\n"));
			return status;
		}
	}
	share_path = gp_get_share_path(gp_ctx, file_sys_path);

	DEBUG(5, ("Copying %s to %s on sysvol\n", local_path, share_path));

	smbcli_mkdir(gp_ctx->cli->tree, share_path);

	status = push_recursive(gp_ctx, local_path, share_path, 0);

	talloc_free(share_path);
	return status;
}
Пример #6
0
/****************************************************************************
check for existance of a nttrans call
****************************************************************************/
static bool scan_nttrans(struct smbcli_state *cli, int op, int level,
			int fnum, int dnum, const char *fname)
{
	int data_len = 0;
	int param_len = 0;
	int rparam_len, rdata_len;
	uint8_t *param, *data;
	NTSTATUS status;
	TALLOC_CTX *mem_ctx;

	mem_ctx = talloc_init("scan_nttrans");

	param = talloc_array(mem_ctx, uint8_t, PARAM_SIZE);
	data = talloc_array(mem_ctx, uint8_t, PARAM_SIZE);
	memset(data, 0, PARAM_SIZE);
	data_len = 4;

	/* try with a info level only */
	param_len = 2;
	SSVAL(param, 0, level);
	status = try_nttrans_len(cli, "void", op, level, param, data, param_len,
			&data_len, &rparam_len, &rdata_len);
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return true;
	}

	/* try with a file descriptor */
	param_len = 6;
	SSVAL(param, 0, fnum);
	SSVAL(param, 2, level);
	SSVAL(param, 4, 0);
	status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len,
			&data_len, &rparam_len, &rdata_len);
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return true;
	}

	/* try with a notify style */
	param_len = 6;
	SSVAL(param, 0, dnum);
	SSVAL(param, 2, dnum);
	SSVAL(param, 4, level);
	status = try_nttrans_len(cli, "notify", op, level, param, data,
			param_len, &data_len, &rparam_len, &rdata_len);
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return true;
	}

	/* try with a file name */
	param_len = 6;
	SSVAL(param, 0, level);
	SSVAL(param, 2, 0);
	SSVAL(param, 4, 0);
	param_len += push_string(
			&param[6], fname, PARAM_SIZE,
			STR_TERMINATE | STR_UNICODE);

	status = try_nttrans_len(cli, "fname", op, level, param, data,
			param_len, &data_len, &rparam_len, &rdata_len);
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return true;
	}

	/* try with a new file name */
	param_len = 6;
	SSVAL(param, 0, level);
	SSVAL(param, 2, 0);
	SSVAL(param, 4, 0);
	param_len += push_string(
			&param[6], "\\newfile.dat", PARAM_SIZE,
			STR_TERMINATE | STR_UNICODE);

	status = try_nttrans_len(cli, "newfile", op, level, param, data,
			param_len, &data_len, &rparam_len, &rdata_len);
	smbcli_unlink(cli->tree, "\\newfile.dat");
	smbcli_rmdir(cli->tree, "\\newfile.dat");
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return true;
	}

	/* try dfs style  */
	smbcli_mkdir(cli->tree, "\\testdir");
	param_len = 2;
	SSVAL(param, 0, level);
	param_len += push_string(&param[2], "\\testdir", PARAM_SIZE,
			STR_TERMINATE | STR_UNICODE);

	status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len,
			&data_len, &rparam_len, &rdata_len);
	smbcli_rmdir(cli->tree, "\\testdir");
	if (NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return true;
	}

	talloc_free(mem_ctx);
	return false;
}
Пример #7
0
/*
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
}
Пример #8
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;
}
Пример #9
0
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;
}
Пример #10
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;

	if (!torture_open_connection(&cli, tctx, 0)) {
		ret = false;
		goto done;
	}

	smbcli_deltree(cli->tree, dirname);

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

	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(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(req->transport->socket->event.ctx,
			      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(req->transport->socket->event.ctx)
		    == -1) {
			torture_warning(tctx, "tevent_loop_once failed: %s\n",
					strerror(errno));
			ret = false;
			goto done;
		}
	}

	CHECK_STATUS(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;
}
Пример #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;

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

	if (!torture_open_connection_share(
		    torture, &cli, torture, torture_setting_string(torture, "host", NULL),
		    torture_setting_string(torture, "share", NULL), torture->ev)) {
		d_printf("torture_open_connection_share failed\n");
		ret = false;
		goto done;
	}

	smbcli_deltree(cli->tree, dirname);

	status = torture_second_tcon(torture, cli->session,
				     torture_setting_string(torture, "share", NULL),
				     &tree2);
	CHECK_STATUS(status, NT_STATUS_OK);
	if (!NT_STATUS_IS_OK(status))
		goto done;

	/* Try a read on an invalid FID */

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

	/* Try a read on a directory handle */

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

	/* 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)) {
			d_printf("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) {
		d_printf("smbcli_read on a directory succeeded, expected "
			 "failure\n");
		ret = false;
	}

	CHECK_STATUS(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) {
		d_printf("smbcli_read on a directory succeeded, expected "
			 "failure\n");
		ret = false;
	}

	CHECK_STATUS(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) {
		d_printf("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(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);

	smbcli_close(cli->tree, fnum);

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

	return ret;
}
Пример #12
0
bool torture_samba3_badpath(struct torture_context *torture)
{
	struct smbcli_state *cli_nt;
	struct smbcli_state *cli_dos;
	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;

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

	nt_status_support = lp_nt_status_support(torture->lp_ctx);

	if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "yes")) {
		printf("Could not set 'nt status support = yes'\n");
		goto fail;
	}

	if (!torture_open_connection(&cli_nt, torture, 0)) {
		goto fail;
	}

	if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "no")) {
		printf("Could not set 'nt status support = yes'\n");
		goto fail;
	}

	if (!torture_open_connection(&cli_dos, torture, 1)) {
		goto fail;
	}

	if (!lp_set_cmdline(torture->lp_ctx, "nt status support",
			    nt_status_support ? "yes":"no")) {
		printf("Could not reset 'nt status support = yes'");
		goto fail;
	}

	smbcli_deltree(cli_nt->tree, dirname);

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

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

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

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

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

	if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
		goto fail;
	}
	fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		d_printf("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) {
		d_printf("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(status, NT_STATUS_NOT_A_DIRECTORY);
	status = smbcli_chkpath(cli_dos->tree, fpath);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

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

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

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

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

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

	status = smbcli_chkpath(cli_nt->tree, "<\\bla");
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "<\\bla");
	CHECK_STATUS(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(status, NT_STATUS_OK);
	status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OK);

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

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

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

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

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

	status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
	CHECK_STATUS(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(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
	status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));

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

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

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

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

	status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(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(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(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(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(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
	}

	status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
	status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
	CHECK_STATUS(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(status, NT_STATUS_OBJECT_NAME_COLLISION);
		status = smb_raw_rename(cli_dos->tree, &io);
		CHECK_STATUS(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(status, NT_STATUS_OBJECT_NAME_COLLISION);
		status = smb_raw_rename(cli_dos->tree, &io);
		CHECK_STATUS(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;
}
Пример #13
0
static NTSTATUS push_recursive (struct gp_context *gp_ctx, const char *local_path,
                                const char *remote_path, int depth)
{
	DIR *dir;
	struct dirent *dirent;
	char *entry_local_path;
	char *entry_remote_path;
	int local_fd, remote_fd;
	int buf[1024];
	int nread, total_read;
	struct stat s;

	dir = opendir(local_path);
	while ((dirent = readdir(dir)) != NULL) {
		if (strcmp(dirent->d_name, ".") == 0 ||
				strcmp(dirent->d_name, "..") == 0) {
			continue;
		}

		entry_local_path = talloc_asprintf(gp_ctx, "%s/%s", local_path,
		                                   dirent->d_name);
		NT_STATUS_HAVE_NO_MEMORY(entry_local_path);

		entry_remote_path = talloc_asprintf(gp_ctx, "%s\\%s",
		                                    remote_path, dirent->d_name);
		NT_STATUS_HAVE_NO_MEMORY(entry_remote_path);

		if (stat(dirent->d_name, &s) != 0) {
			return NT_STATUS_UNSUCCESSFUL;
		}
		if (s.st_mode & S_IFDIR) {
			DEBUG(6, ("Pushing directory %s to %s on sysvol\n",
			          entry_local_path, entry_remote_path));
			smbcli_mkdir(gp_ctx->cli->tree, entry_remote_path);
			if (depth < GP_MAX_DEPTH) {
				push_recursive(gp_ctx, entry_local_path,
				               entry_remote_path, depth+1);
			}
		} else {
			DEBUG(6, ("Pushing file %s to %s on sysvol\n",
			          entry_local_path, entry_remote_path));
			remote_fd = smbcli_open(gp_ctx->cli->tree,
			                        entry_remote_path,
			                        O_WRONLY | O_CREAT,
			                        0);
			if (remote_fd < 0) {
				talloc_free(entry_local_path);
				talloc_free(entry_remote_path);
				DEBUG(0, ("Failed to create remote file: %s\n",
				          entry_remote_path));
				return NT_STATUS_UNSUCCESSFUL;
			}
			local_fd = open(entry_local_path, O_RDONLY);
			if (local_fd < 0) {
				talloc_free(entry_local_path);
				talloc_free(entry_remote_path);
				DEBUG(0, ("Failed to open local file: %s\n",
				          entry_local_path));
				return NT_STATUS_UNSUCCESSFUL;
			}
			total_read = 0;
			while ((nread = read(local_fd, &buf, sizeof(buf)))) {
				smbcli_write(gp_ctx->cli->tree, remote_fd, 0,
						&buf, total_read, nread);
				total_read += nread;
			}

			close(local_fd);
			smbcli_close(gp_ctx->cli->tree, remote_fd);
		}
		talloc_free(entry_local_path);
		talloc_free(entry_remote_path);
	}
	closedir(dir);

	return NT_STATUS_OK;
}