Пример #1
0
/*
  tries the unusual lockingX locktype bits
*/
static bool torture_locktest6(struct torture_context *tctx, 
			      struct smbcli_state *cli)
{
	const char *fname[1] = { "\\lock6.txt" };
	int i;
	int fnum;
	NTSTATUS status;

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

	for (i=0;i<1;i++) {
		torture_comment(tctx, "Testing %s\n", fname[i]);

		smbcli_unlink(cli->tree, fname[i]);

		fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
		status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
		smbcli_close(cli->tree, fnum);
		torture_comment(tctx, "CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));

		fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
		status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
		smbcli_close(cli->tree, fnum);
		torture_comment(tctx, "CANCEL_LOCK gave %s\n", nt_errstr(status));

		smbcli_unlink(cli->tree, fname[i]);
	}

	return true;
}
Пример #2
0
bool torture_samba3_rootdirfid(struct torture_context *tctx, struct smbcli_state *cli)
{
	uint16_t dnum;
	union smb_open io;
	const char *fname = "testfile";
	bool ret = false;

	smbcli_unlink(cli->tree, fname);

	ZERO_STRUCT(io);
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
	io.ntcreatex.in.root_fid.fnum = 0;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.access_mask =
		SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
	io.ntcreatex.in.share_access =
		NTCREATEX_SHARE_ACCESS_READ
		| NTCREATEX_SHARE_ACCESS_READ;
	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 = "\\";
	torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io), 
					   NT_STATUS_OK,
					   ret, done, "smb_open on the directory failed: %s\n");

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

	io.ntcreatex.in.flags =
		NTCREATEX_FLAGS_REQUEST_OPLOCK
		| NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
	io.ntcreatex.in.root_fid.fnum = dnum;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
	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.create_options = 0;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.fname = fname;

	torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
					   NT_STATUS_OK,
					   ret, done, "smb_open on the file failed");

	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
	smbcli_close(cli->tree, dnum);
	smbcli_unlink(cli->tree, fname);

	ret = true;
 done:
	return ret;
}
Пример #3
0
/*
  This test checks that 

  1) the server does not allow an unlink on a file that is open
*/
BOOL torture_unlinktest(struct torture_context *tctx, struct smbcli_state *cli)
{
	const char *fname = BASEDIR "\\unlink.tst";
	int fnum;
	BOOL correct = True;
	union smb_open io;
	NTSTATUS status;

	torture_assert(tctx, torture_setup_dir(cli, BASEDIR), 
				   talloc_asprintf(tctx, "Failed setting up %s", BASEDIR));

	cli->session->pid = 1;

	torture_comment(tctx, "Opening a file\n");

	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
	torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open of %s failed (%s)", fname, smbcli_errstr(cli->tree)));

	torture_comment(tctx, "Unlinking a open file\n");

	torture_assert(tctx, !NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname)),
		"server allowed unlink on an open file");
	
	correct = check_error(__location__, cli, ERRDOS, ERRbadshare, 
				      NT_STATUS_SHARING_VIOLATION);

	smbcli_close(cli->tree, fnum);
	smbcli_unlink(cli->tree, fname);

	torture_comment(tctx, "testing unlink after ntcreatex with DELETE access\n");

	io.ntcreatex.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
	io.ntcreatex.in.file_attr = 0;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE;
	io.ntcreatex.in.access_mask  = SEC_RIGHTS_FILE_ALL;

	status = smb_raw_open(cli->tree, cli, &io);
	torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "failed to open %s", fname));

	torture_assert(tctx, !NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname)),
		"server allowed unlink on an open file");

	correct = check_error(__location__, cli, ERRDOS, ERRbadshare, 
				      NT_STATUS_SHARING_VIOLATION);

	return correct;
}
Пример #4
0
/* 
   recursively descend a tree deleting all files
   returns the number of files deleted, or -1 on error
*/
int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
{
	char *mask;
	struct delete_state dstate;
	NTSTATUS status;

	dstate.tree = tree;
	dstate.total_deleted = 0;
	dstate.failed = false;

	/* it might be a file */
	status = smbcli_unlink(tree, dname);
	if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) {
		return 1;
	}
	if (NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
	    NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
	    NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE) ||
	    NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_DOS(ERRDOS, ERRbadfile))) {
		return 0;
	}
	if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
		/* it could be read-only */
		status = smbcli_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL, 0);
		if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) {
			return 1;
		}
	}

	asprintf(&mask, "%s\\*", dname);
	smbcli_unlink(dstate.tree, mask);
	smbcli_list(dstate.tree, mask, 
		 FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, 
		 delete_fn, &dstate);
	free(mask);

	status = smbcli_rmdir(dstate.tree, dname);
	if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
		/* it could be read-only */
		status = smbcli_setatr(dstate.tree, dname, FILE_ATTRIBUTE_NORMAL, 0);
		status = smbcli_rmdir(dstate.tree, dname);
	}
	if (NT_STATUS_IS_ERR(status)) {
		DEBUG(2,("Failed to delete %s - %s\n", 
			 dname, smbcli_errstr(dstate.tree)));
		return -1;
	}
	dstate.total_deleted++;

	if (dstate.failed) {
		return -1;
	}

	return dstate.total_deleted;
}
Пример #5
0
/* basic testing of all RAW_FILEINFO_* calls 
   for each call we test that it succeeds, and where possible test 
   for consistency between the calls. 
*/
BOOL torture_raw_qfileinfo(struct torture_context *torture)
{
	struct smbcli_state *cli;
	BOOL ret = True;
	TALLOC_CTX *mem_ctx;
	int fnum;
	const char *fname = "\\torture_qfileinfo.txt";

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

	mem_ctx = talloc_init("torture_qfileinfo");

	fnum = create_complex_file(cli, mem_ctx, fname);
	if (fnum == -1) {
		printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}

	ret = torture_raw_qfileinfo_internals(torture, mem_ctx, cli->tree, fnum, fname, False /* is_ipc */);
	
	smbcli_close(cli->tree, fnum);
	smbcli_unlink(cli->tree, fname);

done:
	torture_close_connection(cli);
	talloc_free(mem_ctx);
	return ret;
}
Пример #6
0
NTSTATUS svc_UploadService(const char *hostname,
			   struct cli_credentials * credentials, int force)
{
	struct smb_composite_savefile *io;
	struct smbcli_state *cli;
	NTSTATUS status;

	status =
	    smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL,
				   credentials, NULL);
	NT_ERR(status, 1, "Failed to open ADMIN$ share");
	if (!force) {
		int fd = smbcli_open(cli->tree, "winexesvc.exe", O_RDONLY, DENY_NONE);
		if (fd >= 0) {
			smbcli_close(cli->tree, fd);
			return status;
		}
	} else {
		smbcli_unlink(cli->tree, "winexesvc.exe");
	}
	io = talloc_zero(cli->tree, struct smb_composite_savefile);
	io->in.fname = "winexesvc.exe";
	io->in.data = winexesvc_exe;
	io->in.size = winexesvc_exe_len;
	status = smb_composite_savefile(cli->tree, io);
	NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname);
	talloc_free(io);
	smbcli_tdis(cli);
	return status;
}
Пример #7
0
static int ejs_unlink(MprVarHandle eid, int argc, MprVar **argv)
{
	struct smbcli_tree *tree;
	NTSTATUS result;

	if (argc != 2) {
		ejsSetErrorMsg(eid, "unlink(): 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_unlink(tree, argv[1]->string);

	mpr_Return(eid, mprNTSTATUS(result));

	return 0;
}
Пример #8
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);
}
Пример #9
0
bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_state *cli)
{
	union smb_open io;
	const char *fname = "testfile";
	bool ret = false;
	struct smbcli_request *req;
	struct smb_echo echo_req;

	smbcli_unlink(cli->tree, fname);

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

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

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

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

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

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

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

	ret = true;
 done:
	return ret;
}
Пример #10
0
/*
  open a file N times on the server and just hold them open
  used for testing performance when there are N file handles
  alopenn
 */
bool torture_holdopen(struct torture_context *tctx,
		      struct smbcli_state *cli)
{
	int i, fnum;
	const char *fname = "\\holdopen.dat";
	NTSTATUS status;

	smbcli_unlink(cli->tree, fname);

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

	smbcli_close(cli->tree, fnum);

	for (i=0;i<torture_numops;i++) {
		union smb_open op;

		op.generic.level = RAW_OPEN_NTCREATEX;
		op.ntcreatex.in.root_fid.fnum = 0;
		op.ntcreatex.in.flags = 0;
		op.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
		op.ntcreatex.in.create_options = 0;
		op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
		op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
		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, tctx, &op);
		if (!NT_STATUS_IS_OK(status)) {
			torture_warning(tctx, "open %d failed\n", i);
			continue;
		}

		if (torture_setting_bool(tctx, "progress", true)) {
			torture_comment(tctx, "opened %d file\r", i);
			fflush(stdout);
		}
	}

	torture_comment(tctx, "\nStarting pings\n");

	while (1) {
		struct smb_echo ec;

		status = smb_raw_echo(cli->transport, &ec);
		torture_comment(tctx, ".");
		fflush(stdout);
		sleep(15);
	}

	return true;
}
Пример #11
0
/* 
   callback function for torture_deltree() 
*/
static void delete_fn(struct clilist_file_info *finfo, const char *name, void *state)
{
	struct delete_state *dstate = (struct delete_state *)state;
	char *s, *n;
	if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
		return;
	}

	n = strdup(name);
	n[strlen(n)-1] = 0;
	asprintf(&s, "%s%s", n, finfo->name);

	if (finfo->attrib & FILE_ATTRIBUTE_READONLY) {
		if (NT_STATUS_IS_ERR(smbcli_setatr(dstate->tree, s, 0, 0))) {
			DEBUG(2,("Failed to remove READONLY on %s - %s\n",
				 s, smbcli_errstr(dstate->tree)));			
		}
	}

	if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) {
		char *s2;
		asprintf(&s2, "%s\\*", s);
		smbcli_unlink(dstate->tree, s2);
		smbcli_list(dstate->tree, s2, 
			 FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, 
			 delete_fn, state);
		free(s2);
		if (NT_STATUS_IS_ERR(smbcli_rmdir(dstate->tree, s))) {
			DEBUG(2,("Failed to delete %s - %s\n", 
				 s, smbcli_errstr(dstate->tree)));
			dstate->failed = true;
		}
		dstate->total_deleted++;
	} else {
		if (NT_STATUS_IS_ERR(smbcli_unlink(dstate->tree, s))) {
			DEBUG(2,("Failed to delete %s - %s\n", 
				 s, smbcli_errstr(dstate->tree)));
			dstate->failed = true;
		}
		dstate->total_deleted++;
	}
	free(s);
	free(n);
}
Пример #12
0
NTSTATUS svc_uninstall(const char *hostname,
		       struct cli_credentials * credentials)
{
	NTSTATUS status;
	struct dcerpc_pipe *svc_pipe;
	struct policy_handle scm_handle;
	struct policy_handle svc_handle;
	struct SERVICE_STATUS svc_status;

	status = svc_pipe_connect(&svc_pipe, hostname, credentials);
	NT_ERR(status, 1, "Cannot connect to svcctl pipe");
	status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle);
	NT_ERR(status, 1, "OpenSCManager failed");
	status =
	    svc_OpenService(svc_pipe, &scm_handle, "winexesvc",
			    &svc_handle);
	NT_ERR(status, 1, "OpenService failed");
	DEBUG(1, ("OpenService - %s\n", nt_errstr(status)));
	if (NT_STATUS_IS_OK(status)) {
		status =
		    svc_ControlService(svc_pipe, &svc_handle,
				       SERVICE_CONTROL_STOP, &svc_status);
		{
			struct SERVICE_STATUS s;
			do {
				msleep(100);
				status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s);
				NT_ERR(status, 1, "QueryServiceStatus failed");
			} while (s.state == SERVICE_STOP_PENDING);
			if (s.state != SERVICE_STOPPED) {
				DEBUG(0, ("Service cannot stop, status=0x%08X\n", s.state));
				return NT_STATUS_UNSUCCESSFUL;
			}
		}
		DEBUG(1, ("StopService - %s\n", nt_errstr(status)));
		status = svc_DeleteService(svc_pipe, &svc_handle);
		DEBUG(1, ("DeleteService - %s\n", nt_errstr(status)));
		status = svc_CloseServiceHandle(svc_pipe, &svc_handle);
		DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status)));
	}
	svc_CloseServiceHandle(svc_pipe, &scm_handle);
	DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status)));

	struct smbcli_state *cli;
	status =
	    smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL,
				   credentials, NULL);
	NT_ERR(status, 1, "Failed to open ADMIN$ share");
	/* Give winexesvc some time to exit */
	msleep(300);
	status = smbcli_unlink(cli->tree, "winexesvc.exe");
	DEBUG(1, ("Delete winexesvc.exe - %s\n", nt_errstr(status)));
	status = smbcli_tdis(cli);
	DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status)));
	return status;
}
Пример #13
0
static NTSTATUS svc_UploadService(struct tevent_context *ev_ctx, 
                           const char *hostname,
			   const char *service_filename,
			   unsigned char *svc32_exe, unsigned int svc32_exe_len,
			   unsigned char *svc64_exe, unsigned int svc64_exe_len,
			   struct cli_credentials *credentials,
			   struct loadparm_context *cllp_ctx,
		           int flags)
{
	struct smb_composite_savefile *io;
	struct smbcli_state *cli;
	NTSTATUS status;
	struct smbcli_options options;
	struct smbcli_session_options session_options;

	lpcfg_smbcli_options(cllp_ctx, &options);
	lpcfg_smbcli_session_options(cllp_ctx, &session_options);

	status =
	    smbcli_full_connection(NULL, &cli, hostname, lpcfg_smb_ports(cllp_ctx), "ADMIN$", NULL,
				   lpcfg_socket_options(cllp_ctx), credentials, lpcfg_resolve_context(cllp_ctx), ev_ctx, &options, &session_options, lpcfg_gensec_settings(NULL, cllp_ctx));
	NT_ERR(status, 1, "Failed to open ADMIN$ share");
	if (flags & SVC_FORCE_UPLOAD) {
		smbcli_unlink(cli->tree, service_filename);
	} else {
		int fd = smbcli_open(cli->tree, service_filename, O_RDONLY, DENY_NONE);
		if (fd >= 0) {
			smbcli_close(cli->tree, fd);
			return status;
		}
	}
	io = talloc_zero(cli->tree, struct smb_composite_savefile);
	io->in.fname = service_filename;
	if (flags & SVC_OSCHOOSE) {
	    status = smbcli_chkpath(cli->tree, "SysWoW64");
	}
	if (((flags & SVC_OSCHOOSE) && NT_STATUS_IS_OK(status)) || (flags & SVC_OS64BIT)) {
		DEBUG(1, ("svc_UploadService: Installing 64bit %s\n", service_filename));
		io->in.data = svc64_exe;
		io->in.size = svc64_exe_len;
	} else {
		DEBUG(1, ("svc_UploadService: Installing 32bit %s\n", service_filename));
		io->in.data = svc32_exe;
		io->in.size = svc32_exe_len;
	}
	status = smb_composite_savefile(cli->tree, io);
	NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname);
	talloc_free(io);
	smbcli_tdis(cli);
	return status;
}
Пример #14
0
static void testpair(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, char *mask,
		char *file)
{
	int fnum;
	char res1[256];
	char *res2;
	static int count;
	char *short_name = NULL;
	char *long_name = NULL;
	struct masktest_state state;

	count++;

	safe_strcpy(res1, "---", sizeof(res1));

	state.mem_ctx = mem_ctx;

	fnum = smbcli_open(cli->tree, file, O_CREAT|O_TRUNC|O_RDWR, 0);
	if (fnum == -1) {
		DEBUG(0,("Can't create %s\n", file));
		return;
	}
	smbcli_close(cli->tree, fnum);

	resultp = res1;
	short_name = talloc_strdup(mem_ctx, "");
	get_real_name(mem_ctx, cli, &long_name, &short_name);
	safe_strcpy(res1, "---", sizeof(res1));
	smbcli_list_new(cli->tree, mask,
			FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY,
			RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
			listfn, &state);

	res2 = reg_test(cli, mem_ctx, mask, long_name, short_name);

	if (showall || strcmp(res1, res2)) {
		d_printf("%s %s %d mask=[%s] file=[%s] rfile=[%s/%s]\n",
			 res1, res2, count, mask, file, long_name, short_name);
		if (die_on_error) exit(1);
	}

	smbcli_unlink(cli->tree, file);

	if (count % 100 == 0) DEBUG(0,("%d\n", count));

	resultp = NULL;
}
Пример #15
0
static void close_files(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
			int fnum[NSERVERS][NCONNECTIONS][NFILES])
{
	int server, conn, f; 

	for (server=0;server<NSERVERS;server++)
	for (conn=0;conn<NCONNECTIONS;conn++)
	for (f=0;f<NFILES;f++) {
		if (fnum[server][conn][f] != -1) {
			smbcli_close(cli[server][conn]->tree, fnum[server][conn][f]);
			fnum[server][conn][f] = -1;
		}
	}
	for (server=0;server<NSERVERS;server++) {
		smbcli_unlink(cli[server][0]->tree, FILENAME);
	}
}
Пример #16
0
BOOL torture_mangle(struct torture_context *torture, 
					struct smbcli_state *cli)
{
	extern int torture_numops;
	int i;

	/* we will use an internal tdb to store the names we have used */
	tdb = tdb_open(NULL, 100000, TDB_INTERNAL, 0, 0);
	if (!tdb) {
		printf("ERROR: Failed to open tdb\n");
		return False;
	}

	if (!torture_setup_dir(cli, "\\mangle_test")) {
		return False;
	}

	for (i=0;i<torture_numops;i++) {
		fstring name;

		ZERO_STRUCT(name);

		gen_name(name);

		if (!test_one(cli, name)) {
			break;
		}
		if (total && total % 100 == 0) {
			printf("collisions %u/%u  - %.2f%%   (%u failures)\r",
			       collisions, total, (100.0*collisions) / total, failures);
		}
	}

	smbcli_unlink(cli->tree, "\\mangle_test\\*");
	if (NT_STATUS_IS_ERR(smbcli_rmdir(cli->tree, "\\mangle_test"))) {
		printf("ERROR: Failed to remove directory\n");
		return False;
	}

	printf("\nTotal collisions %u/%u  - %.2f%%   (%u failures)\n",
	       collisions, total, (100.0*collisions) / total, failures);

	return (failures == 0);
}
Пример #17
0
static void close_files(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], 
			char *nfs[NSERVERS],
			int fnum[NSERVERS][NUMFSTYPES][NCONNECTIONS][NFILES])
{
	int server, conn, f, fstype; 

	for (server=0;server<NSERVERS;server++)
	for (fstype=0;fstype<NUMFSTYPES;fstype++)
	for (conn=0;conn<NCONNECTIONS;conn++)
	for (f=0;f<NFILES;f++) {
		if (fnum[server][fstype][conn][f] != -1) {
			try_close(cli[server][conn], fstype, fnum[server][fstype][conn][f]);
			fnum[server][fstype][conn][f] = -1;
		}
	}
	for (server=0;server<NSERVERS;server++) {
		smbcli_unlink(cli[server][0], FILENAME);
	}
}
Пример #18
0
/*
  test directory listing speed
 */
bool torture_dirtest1(struct torture_context *tctx, 
		      struct smbcli_state *cli)
{
	int i;
	int fnum;
	bool correct = true;
	extern int torture_numops;
	struct timeval tv;

	torture_comment(tctx, "Creating %d random filenames\n", torture_numops);

	srandom(0);
	tv = timeval_current();
	for (i=0;i<torture_numops;i++) {
		char *fname;
		asprintf(&fname, "\\%x", (int)random());
		fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
		if (fnum == -1) {
			fprintf(stderr,"(%s) Failed to open %s\n", 
				__location__, fname);
			return false;
		}
		smbcli_close(cli->tree, fnum);
		free(fname);
	}

	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));

	torture_comment(tctx, "dirtest core %g seconds\n", timeval_elapsed(&tv));

	srandom(0);
	for (i=0;i<torture_numops;i++) {
		char *fname;
		asprintf(&fname, "\\%x", (int)random());
		smbcli_unlink(cli->tree, fname);
		free(fname);
	}

	return correct;
}
Пример #19
0
/* basic testing of all RAW_FILEINFO_* calls 
   for each call we test that it succeeds, and where possible test 
   for consistency between the calls. 
*/
bool torture_raw_qfileinfo(struct torture_context *torture, 
						   struct smbcli_state *cli)
{
	int fnum;
	bool ret;
	const char *fname = "\\torture_qfileinfo.txt";

	fnum = create_complex_file(cli, torture, fname);
	if (fnum == -1) {
		printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
		return false;
	}

	ret = torture_raw_qfileinfo_internals(torture, torture, cli->tree, fnum, fname, false /* is_ipc */);
	
	smbcli_close(cli->tree, fnum);
	smbcli_unlink(cli->tree, fname);

	return ret;
}
Пример #20
0
/*
  sees what IOCTLs are supported
 */
bool torture_ioctl_test(struct torture_context *tctx, 
						struct smbcli_state *cli)
{
	uint16_t device, function;
	int fnum;
	const char *fname = "\\ioctl.dat";
	NTSTATUS status;
	union smb_ioctl parms;
	TALLOC_CTX *mem_ctx;

	mem_ctx = talloc_named_const(tctx, 0, "ioctl_test");

	smbcli_unlink(cli->tree, fname);

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

	parms.ioctl.level = RAW_IOCTL_IOCTL;
	parms.ioctl.in.file.fnum = fnum;
	parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
	status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
	torture_comment(tctx, "ioctl job info: %s\n", smbcli_errstr(cli->tree));

	for (device=0;device<0x100;device++) {
		torture_comment(tctx, "testing device=0x%x\n", device);
		for (function=0;function<0x100;function++) {
			parms.ioctl.in.request = (device << 16) | function;
			status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);

			if (NT_STATUS_IS_OK(status)) {
				torture_comment(tctx, "ioctl device=0x%x function=0x%x OK : %d bytes\n", 
					device, function, (int)parms.ioctl.out.blob.length);
			}
		}
	}

	return true;
}
Пример #21
0
/**
  sometimes we need a fairly complex file to work with, so we can test
  all possible attributes. 
*/
_PUBLIC_ int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *fname)
{
	int fnum;
	char buf[7] = "abc";
	union smb_setfileinfo setfile;
	union smb_fileinfo fileinfo;
	time_t t = (time(NULL) & ~1);
	NTSTATUS status;

	smbcli_unlink(cli->tree, fname);
	fnum = smbcli_nt_create_full(cli->tree, fname, 0, 
				     SEC_RIGHTS_FILE_ALL,
				     FILE_ATTRIBUTE_NORMAL,
				     NTCREATEX_SHARE_ACCESS_DELETE|
				     NTCREATEX_SHARE_ACCESS_READ|
				     NTCREATEX_SHARE_ACCESS_WRITE, 
				     NTCREATEX_DISP_OVERWRITE_IF,
				     0, 0);
	if (fnum == -1) return -1;

	smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));

	if (strchr(fname, ':') == NULL) {
		/* setup some EAs */
		setfile.generic.level = RAW_SFILEINFO_EA_SET;
		setfile.generic.in.file.fnum = fnum;
		setfile.ea_set.in.num_eas = 2;	
		setfile.ea_set.in.eas = talloc_array(mem_ctx, struct ea_struct, 2);
		setfile.ea_set.in.eas[0].flags = 0;
		setfile.ea_set.in.eas[0].name.s = "EAONE";
		setfile.ea_set.in.eas[0].value = data_blob_talloc(mem_ctx, "VALUE1", 6);
		setfile.ea_set.in.eas[1].flags = 0;
		setfile.ea_set.in.eas[1].name.s = "SECONDEA";
		setfile.ea_set.in.eas[1].value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
		status = smb_raw_setfileinfo(cli->tree, &setfile);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to setup EAs\n");
		}
	}
Пример #22
0
/*
  Test rename on files open with share delete and no share delete.
 */
bool torture_test_rename(struct torture_context *tctx, 
			 struct smbcli_state *cli1)
{
	const char *fname = "\\test.txt";
	const char *fname1 = "\\test1.txt";
	int fnum1;

	smbcli_unlink(cli1->tree, fname);
	smbcli_unlink(cli1->tree, fname1);
	fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
				      SEC_RIGHTS_FILE_READ, 
				      FILE_ATTRIBUTE_NORMAL,
				      NTCREATEX_SHARE_ACCESS_READ, 
				      NTCREATEX_DISP_OVERWRITE_IF, 0, 0);

	torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "First open failed - %s", 
		       smbcli_errstr(cli1->tree)));

	torture_assert(tctx, NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1)), 
					"First rename succeeded - this should have failed !");

	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
		talloc_asprintf(tctx, "close - 1 failed (%s)", smbcli_errstr(cli1->tree)));

	smbcli_unlink(cli1->tree, fname);
	smbcli_unlink(cli1->tree, fname1);
	fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
				      SEC_RIGHTS_FILE_READ, 
				      FILE_ATTRIBUTE_NORMAL,
				      NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, 
				      NTCREATEX_DISP_OVERWRITE_IF, 0, 0);

	torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, 
				   "Second open failed - %s", smbcli_errstr(cli1->tree)));

	torture_assert_ntstatus_ok(tctx, smbcli_rename(cli1->tree, fname, fname1),
		talloc_asprintf(tctx, 
				"Second rename failed - this should have succeeded - %s", 
		       smbcli_errstr(cli1->tree)));

	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
		talloc_asprintf(tctx, 
		"close - 2 failed (%s)", smbcli_errstr(cli1->tree)));

	smbcli_unlink(cli1->tree, fname);
	smbcli_unlink(cli1->tree, fname1);

	fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
				      SEC_STD_READ_CONTROL, 
				      FILE_ATTRIBUTE_NORMAL,
				      NTCREATEX_SHARE_ACCESS_NONE, 
				      NTCREATEX_DISP_OVERWRITE_IF, 0, 0);

	torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "Third open failed - %s", 
			smbcli_errstr(cli1->tree)));

	torture_assert_ntstatus_ok(tctx, smbcli_rename(cli1->tree, fname, fname1),
		talloc_asprintf(tctx, "Third rename failed - this should have succeeded - %s", 
		       smbcli_errstr(cli1->tree)));

	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1), 
		talloc_asprintf(tctx, "close - 3 failed (%s)", smbcli_errstr(cli1->tree)));

	smbcli_unlink(cli1->tree, fname);
	smbcli_unlink(cli1->tree, fname1);

	return true;
}
Пример #23
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;
}
Пример #24
0
bool unix_torture_unix_info2(struct torture_context *torture)
{
	void *mem_ctx;
	struct smbcli_state *cli;
	int fnum;

	struct unix_info2 pinfo, finfo;

	mem_ctx = talloc_init("smb_query_unix_info2");
	torture_assert(torture, mem_ctx != NULL, "out of memory");

	if (!(cli = connect_to_server(torture))) {
		talloc_free(mem_ctx);
		return false;
	}

	smbcli_unlink(cli->tree, FILENAME);

	fnum = create_file(cli, FILENAME);
	torture_assert(torture, fnum != -1, smbcli_errstr(cli->tree));

	printf("checking SMB_QFILEINFO_UNIX_INFO2 for QueryFileInfo\n");
	if (!query_file_info2(mem_ctx, torture, cli, fnum, &finfo)) {
		goto fail;
	}

	printf("checking SMB_QFILEINFO_UNIX_INFO2 for QueryPathInfo\n");
	if (!query_path_info2(mem_ctx, torture, cli, FILENAME, &pinfo)) {
		goto fail;
	}

	if (!match_info2(torture, &pinfo, &finfo)) {
		goto fail;
	}

	printf("checking SMB_FIND_UNIX_INFO2 for FindFirst\n");
	if (!find_single_info2(mem_ctx, torture, cli, FILENAME, &pinfo)) {
		goto fail;
	}

	if (!match_info2(torture, &pinfo, &finfo)) {
		goto fail;
	}

	/* XXX: should repeat this test with SetFileInfo. */
	printf("checking SMB_SFILEINFO_UNIX_INFO2 for SetPathInfo\n");
	if (!verify_setinfo_flags(mem_ctx, torture, cli, FILENAME)) {
		goto fail;
	}

	smbcli_close(cli->tree, fnum);
	smbcli_unlink(cli->tree, FILENAME);
	torture_close_connection(cli);
	talloc_free(mem_ctx);
	return true;

fail:

	smbcli_close(cli->tree, fnum);
	smbcli_unlink(cli->tree, FILENAME);
	torture_close_connection(cli);
	talloc_free(mem_ctx);
	return false;

}
Пример #25
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;
}
Пример #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;
}
Пример #27
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;
}
Пример #28
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;
}
Пример #29
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;
}
Пример #30
0
/* basic testing of all RAW_SFILEINFO_* calls
   for each call we test that it succeeds, and where possible test
   for consistency between the calls.
*/
static bool
torture_raw_sfileinfo_base(struct torture_context *torture, struct smbcli_state *cli)
{
    bool ret = true;
    int fnum = -1;
    char *fnum_fname;
    char *fnum_fname_new;
    char *path_fname;
    char *path_fname_new;
    union smb_fileinfo finfo1, finfo2;
    union smb_setfileinfo sfinfo;
    NTSTATUS status, status2;
    const char *call_name;
    time_t basetime = (time(NULL) - 86400) & ~1;
    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);

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

#define RECREATE_FILE(fname) do { \
	if (fnum != -1) smbcli_close(cli->tree, fnum); \
	fnum = create_complex_file(cli, torture, fname); \
	if (fnum == -1) { \
		printf("(%s) ERROR: open of %s failed (%s)\n", \
		       __location__, fname, smbcli_errstr(cli->tree)); \
		ret = false; \
		goto done; \
	}} while (0)

#define RECREATE_BOTH do { \
		RECREATE_FILE(path_fname); \
		smbcli_close(cli->tree, fnum); \
		RECREATE_FILE(fnum_fname); \
	} while (0)

    RECREATE_BOTH;

#define CHECK_CALL_FNUM(call, rightstatus) do { \
	check_fnum = true; \
	call_name = #call; \
	sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
	sfinfo.generic.in.file.fnum = fnum; \
	status = smb_raw_setfileinfo(cli->tree, &sfinfo); \
	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
                torture_warning(torture, \
			"(%s) %s - %s", __location__, #call, \
                        nt_errstr(status)); \
        } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
		printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
			nt_errstr(status), nt_errstr(rightstatus)); \
		ret = false; \
	} \
	finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
	finfo1.generic.in.file.fnum = fnum; \
	status2 = smb_raw_fileinfo(cli->tree, torture, &finfo1); \
	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
                torture_warning(torture, \
			"(%s) %s - %s", __location__, #call, \
                        nt_errstr(status)); \
        } else if (!NT_STATUS_IS_OK(status2)) { \
		printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status)); \
		ret = false; \
	}} while (0)

#define CHECK_CALL_PATH(call, rightstatus) do { \
	check_fnum = false; \
	call_name = #call; \
	sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
	sfinfo.generic.in.file.path = path_fname; \
	status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
		sfinfo.generic.in.file.path = path_fname_new; \
		status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
	} \
	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
                torture_warning(torture, \
			"(%s) %s - %s", __location__, #call, \
                        nt_errstr(status)); \
        } else if (!NT_STATUS_EQUAL(status, rightstatus)) { \
		printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
			nt_errstr(status), nt_errstr(rightstatus)); \
		ret = false; \
	} \
	finfo1.generic.level = RAW_FILEINFO_ALL_INFO; \
	finfo1.generic.in.file.path = path_fname; \
	status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
	if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
		finfo1.generic.in.file.path = path_fname_new; \
		status2 = smb_raw_pathinfo(cli->tree, torture, &finfo1); \
	} \
	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { \
                torture_warning(torture, \
			"(%s) %s - %s", __location__, #call, \
                        nt_errstr(status)); \
        } else if (!NT_STATUS_IS_OK(status2)) { \
		printf("(%s) %s pathinfo - %s\n", __location__, #call, nt_errstr(status2)); \
		ret = false; \
	}} while (0)

#define CHECK1(call) \
	do { if (NT_STATUS_IS_OK(status)) { \
		finfo2.generic.level = RAW_FILEINFO_ ## call; \
		if (check_fnum) { \
			finfo2.generic.in.file.fnum = fnum; \
			status2 = smb_raw_fileinfo(cli->tree, torture, &finfo2); \
		} else { \
			finfo2.generic.in.file.path = path_fname; \
			status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
			if (NT_STATUS_EQUAL(status2, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { \
				finfo2.generic.in.file.path = path_fname_new; \
				status2 = smb_raw_pathinfo(cli->tree, torture, &finfo2); \
			} \
		} \
		if (!NT_STATUS_IS_OK(status2)) { \
			printf("%s - %s\n", #call, nt_errstr(status2)); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_VALUE(call, stype, field, value) do { \
 	CHECK1(call); \
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
		printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
		       call_name, #stype, #field, \
		       (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
		dump_all_info(torture, &finfo1); \
		ret = false; \
	}} while (0)

#define CHECK_TIME(call, stype, field, value) do { \
 	CHECK1(call); \
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
		printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
		        call_name, #stype, #field, \
		        (unsigned int)value, \
			(unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
		printf("\t%s", timestring(torture, value)); \
		printf("\t%s\n", nt_time_string(torture, finfo2.stype.out.field)); \
		dump_all_info(torture, &finfo1); \
		ret = false; \
	}} while (0)

#define CHECK_STR(call, stype, field, value) do { \
 	CHECK1(call); \
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && strcmp(finfo2.stype.out.field, value) != 0) { \
		printf("(%s) %s - %s/%s should be '%s' - '%s'\n", __location__, \
		        call_name, #stype, #field, \
		        value, \
			finfo2.stype.out.field); \
		dump_all_info(torture, &finfo1); \
		ret = false; \
	}} while (0)

#define CHECK_STATUS(status, correct) do { \
	if (!NT_STATUS_EQUAL(status, correct)) { \
		printf("(%s) Incorrect status %s - should be %s\n", \
		       __location__, nt_errstr(status), nt_errstr(correct)); \
		ret = false; \
		goto done; \
	}} while (0)


    printf("Test setattr\n");
    sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_READONLY;
    sfinfo.setattr.in.write_time = basetime;
    CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
    CHECK_VALUE  (ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
    CHECK_TIME   (ALL_INFO, all_info, write_time, basetime);

    printf("setting to NORMAL doesn't do anything\n");
    sfinfo.setattr.in.attrib = FILE_ATTRIBUTE_NORMAL;
    sfinfo.setattr.in.write_time = 0;
    CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);
    CHECK_TIME (ALL_INFO, all_info, write_time, basetime);

    printf("a zero write_time means don't change\n");
    sfinfo.setattr.in.attrib = 0;
    sfinfo.setattr.in.write_time = 0;
    CHECK_CALL_PATH(SETATTR, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);
    CHECK_TIME (ALL_INFO, all_info, write_time, basetime);

    printf("Test setattre\n");
    sfinfo.setattre.in.create_time = basetime + 20;
    sfinfo.setattre.in.access_time = basetime + 30;
    sfinfo.setattre.in.write_time  = basetime + 40;
    CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);

    sfinfo.setattre.in.create_time = 0;
    sfinfo.setattre.in.access_time = 0;
    sfinfo.setattre.in.write_time  = 0;
    CHECK_CALL_FNUM(SETATTRE, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 20);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 30);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 40);

    printf("Test standard level\n");
    sfinfo.standard.in.create_time = basetime + 100;
    sfinfo.standard.in.access_time = basetime + 200;
    sfinfo.standard.in.write_time  = basetime + 300;
    CHECK_CALL_FNUM(STANDARD, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);

    printf("Test basic_info level\n");
    basetime += 86400;
    unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
    unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
    unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
    unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
    sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
    CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
    CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);

    printf("a zero time means don't change\n");
    unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
    unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
    unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
    unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
    sfinfo.basic_info.in.attrib = 0;
    CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
    CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_READONLY);

    printf("Test basic_information level\n");
    basetime += 86400;
    unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
    unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
    unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
    unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
    sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
    CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
    CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);

    CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
    CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);

    torture_comment(torture, "try to change a file to a directory\n");
    sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
    CHECK_CALL_FNUM(BASIC_INFO, NT_STATUS_INVALID_PARAMETER);

    printf("a zero time means don't change\n");
    unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
    unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
    unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
    unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
    sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
    CHECK_CALL_FNUM(BASIC_INFORMATION, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);
    CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);

    CHECK_CALL_PATH(BASIC_INFORMATION, NT_STATUS_OK);
    CHECK_TIME(ALL_INFO, all_info, create_time, basetime + 100);
    CHECK_TIME(ALL_INFO, all_info, access_time, basetime + 200);
    CHECK_TIME(ALL_INFO, all_info, write_time,  basetime + 300);

    /* interesting - w2k3 leaves change_time as current time for 0 change time
       in setpathinfo
      CHECK_TIME(ALL_INFO, all_info, change_time, basetime + 400);
    */
    CHECK_VALUE(ALL_INFO, all_info, attrib,     FILE_ATTRIBUTE_NORMAL);

    printf("Test disposition_info level\n");
    sfinfo.disposition_info.in.delete_on_close = 1;
    CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
    CHECK_VALUE(ALL_INFO, all_info, nlink, 0);

    sfinfo.disposition_info.in.delete_on_close = 0;
    CHECK_CALL_FNUM(DISPOSITION_INFO, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
    CHECK_VALUE(ALL_INFO, all_info, nlink, 1);

    printf("Test disposition_information level\n");
    sfinfo.disposition_info.in.delete_on_close = 1;
    CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
    CHECK_VALUE(ALL_INFO, all_info, nlink, 0);

    /* this would delete the file! */
    /*
      CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
      CHECK_VALUE(ALL_INFO, all_info, delete_pending, 1);
      CHECK_VALUE(ALL_INFO, all_info, nlink, 0);
    */

    sfinfo.disposition_info.in.delete_on_close = 0;
    CHECK_CALL_FNUM(DISPOSITION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
    CHECK_VALUE(ALL_INFO, all_info, nlink, 1);

    CHECK_CALL_PATH(DISPOSITION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, delete_pending, 0);
    CHECK_VALUE(ALL_INFO, all_info, nlink, 1);

    printf("Test allocation_info level\n");
    sfinfo.allocation_info.in.alloc_size = 0;
    CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 0);
    CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);

    sfinfo.allocation_info.in.alloc_size = 4096;
    CHECK_CALL_FNUM(ALLOCATION_INFO, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
    CHECK_VALUE(ALL_INFO, all_info, size, 0);

    RECREATE_BOTH;
    sfinfo.allocation_info.in.alloc_size = 0;
    CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 0);
    CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);

    CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 0);
    CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);

    sfinfo.allocation_info.in.alloc_size = 4096;
    CHECK_CALL_FNUM(ALLOCATION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, alloc_size, 4096);
    CHECK_VALUE(ALL_INFO, all_info, size, 0);

    /* setting the allocation size up via setpathinfo seems
       to be broken in w2k3 */
    CHECK_CALL_PATH(ALLOCATION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, alloc_size, 0);
    CHECK_VALUE(ALL_INFO, all_info, size, 0);

    printf("Test end_of_file_info level\n");
    sfinfo.end_of_file_info.in.size = 37;
    CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 37);

    sfinfo.end_of_file_info.in.size = 7;
    CHECK_CALL_FNUM(END_OF_FILE_INFO, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 7);

    sfinfo.end_of_file_info.in.size = 37;
    CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 37);

    CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 37);

    sfinfo.end_of_file_info.in.size = 7;
    CHECK_CALL_FNUM(END_OF_FILE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 7);

    CHECK_CALL_PATH(END_OF_FILE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(ALL_INFO, all_info, size, 7);

    printf("Test position_information level\n");
    sfinfo.position_information.in.position = 123456;
    CHECK_CALL_FNUM(POSITION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);

    CHECK_CALL_PATH(POSITION_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(POSITION_INFORMATION, position_information, position, 0);

    printf("Test mode_information level\n");
    sfinfo.mode_information.in.mode = 2;
    CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);

    CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);

    sfinfo.mode_information.in.mode = 1;
    CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);
    CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);

    sfinfo.mode_information.in.mode = 0;
    CHECK_CALL_FNUM(MODE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);

    CHECK_CALL_PATH(MODE_INFORMATION, NT_STATUS_OK);
    CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);

#if 0
    printf("Test unix_basic level\n");
    CHECK_CALL_FNUM(UNIX_BASIC, NT_STATUS_OK);
    CHECK_CALL_PATH(UNIX_BASIC, NT_STATUS_OK);

    printf("Test unix_link level\n");
    CHECK_CALL_FNUM(UNIX_LINK, NT_STATUS_OK);
    CHECK_CALL_PATH(UNIX_LINK, NT_STATUS_OK);
#endif

done:
    smb_raw_exit(cli->session);
    smbcli_close(cli->tree, fnum);
    if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
        printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
    }
    if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
        printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
    }

    return ret;
}