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

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

	mem_ctx = talloc_init("torture_raw_context");

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

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

	torture_close_connection(cli);
	talloc_free(mem_ctx);

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

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

	mem_ctx = talloc_init("torture_raw_streams");

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

	ret &= test_stream_io(cli, mem_ctx);

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

	torture_close_connection(cli);
	talloc_free(mem_ctx);
	return ret;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
/* 
   basic testing of multiplexing notify
*/
bool torture_raw_mux(struct torture_context *torture, struct smbcli_state *cli)
{
	bool ret = true;
		
	torture_assert(torture, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);

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

	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemplo n.º 5
0
/*
  exit - closing files open by the pid
*/
static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, 
			  struct ntvfs_request *req)
{
	struct cvfs_private *p = ntvfs->private_data;
	struct smbcli_request *c_req;

	SETUP_PID;

	if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
		return smb_raw_exit(p->tree->session);
	}

	c_req = smb_raw_exit_send(p->tree->session);

	SIMPLE_ASYNC_TAIL;
}
Exemplo n.º 6
0
/* 
   basic testing of session/tree context calls
*/
static bool torture_raw_context_int(struct torture_context *tctx, 
									struct smbcli_state *cli)
{
	bool ret = true;

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

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

	return ret;
}
Exemplo n.º 7
0
/* 
   basic testing of disconnects
*/
bool torture_disconnect(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx;
	int i;
	extern int torture_numops;
	struct smbcli_state *cli;

	mem_ctx = talloc_init("torture_raw_mux");

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

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

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

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

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

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

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

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

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

	return ret;
}
Exemplo n.º 9
0
/* 
   benchmark locking calls
*/
bool torture_bench_lock(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	int i, j;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	struct timeval tv;
	struct benchlock_state *state;
	int total = 0, minops=0;
	struct smbcli_state *cli;
	bool progress;
	off_t offset;
	int initial_locks = torture_setting_int(torture, "initial_locks", 0);

	progress = torture_setting_bool(torture, "progress", true);

	nprocs = torture_setting_int(torture, "nprocs", 4);

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

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

	num_connected = i;

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

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

		/* Optionally, lock initial_locks for each proc beforehand. */
		if (i == 0 && initial_locks > 0) {
			printf("Initializing %d locks on each proc.\n",
			    initial_locks);
		}

		for (j = 0; j < initial_locks; j++) {
			offset = (0xFFFFFED8LLU * (i+2)) + j;
			if (!NT_STATUS_IS_OK(smbcli_lock64(state[i].tree,
			    state[i].fnum, offset, 1, 0, WRITE_LOCK))) {
				printf("Failed initializing, lock=%d\n", j);
				goto failed;
			}
		}

		state[i].stage = LOCK_INITIAL;
		lock_send(&state[i]);
	}

	tv = timeval_current();	

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

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

		if (lock_failed) {
			DEBUG(0,("locking failed\n"));
			goto failed;
		}
	}

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

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

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

failed:
	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	return false;
}
Exemplo n.º 10
0
static bool test_osxrename(struct torture_context *tctx,
                           struct smbcli_state *cli)
{
    union smb_rename io;
    union smb_unlink io_un;
    NTSTATUS status;
    bool ret = true;
    int fnum = -1;
    const char *fname1 = BASEDIR "\\test1";
    const char *FNAME1 = BASEDIR "\\TEST1";
    union smb_fileinfo finfo;
    union smb_open op;

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

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

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

    smbcli_close(cli->tree, fnum);

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

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

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

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

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

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

done:
    smbcli_close(cli->tree, fnum);
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Exemplo n.º 11
0
/*
  test pid ops with 2 tcons
*/
static BOOL test_pid_2tcon(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	NTSTATUS status;
	BOOL ret = True;
	const char *share, *host;
	struct smbcli_tree *tree;
	union smb_tcon tcon;
	union smb_open io;
	union smb_write wr;
	union smb_close cl;
	int fnum1, fnum2;
	const char *fname1 = BASEDIR "\\test1.txt";
	const char *fname2 = BASEDIR "\\test2.txt";
	uint8_t c = 1;
	uint16_t tid1, tid2;

	printf("TESTING PID HANDLING WITH 2 TCONS\n");

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

	share = lp_parm_string(-1, "torture", "share");
	host  = lp_parm_string(-1, "torture", "host");
	
	printf("create a second tree context on the same session\n");
	tree = smbcli_tree_init(cli->session, mem_ctx, False);

	tcon.generic.level = RAW_TCON_TCONX;
	tcon.tconx.in.flags = 0;
	tcon.tconx.in.password = data_blob(NULL, 0);
	tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
	tcon.tconx.in.device = "A:";	
	status = smb_raw_tcon(tree, mem_ctx, &tcon);
	CHECK_STATUS(status, NT_STATUS_OK);	

	tree->tid = tcon.tconx.out.tid;

	tid1 = cli->tree->tid;
	tid2 = tree->tid;
	printf("tid1=%d tid2=%d\n", tid1, tid2);

	printf("create a file using the tid1\n");
	cli->tree->tid = tid1;
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 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.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname1;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum1 = io.ntcreatex.out.file.fnum;

	printf("write using the tid1\n");
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum1;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;

	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("create a file using the tid2\n");
	cli->tree->tid = tid2;
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 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.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname2;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum2 = io.ntcreatex.out.file.fnum;

	printf("write using the tid2\n");
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum2;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;

	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("exit the pid\n");
	status = smb_raw_exit(cli->session);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the fnum1 on tid1 should not be accessible\n");
	cli->tree->tid = tid1;
	wr.writex.in.file.fnum = fnum1;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("the fnum1 on tid1 should have been auto-closed\n");
	cl.close.level = RAW_CLOSE_CLOSE;
	cl.close.in.file.fnum = fnum1;
	cl.close.in.write_time = 0;
	status = smb_raw_close(cli->tree, &cl);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("the fnum2 on tid2 should not be accessible\n");
	cli->tree->tid = tid2;
	wr.writex.in.file.fnum = fnum2;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("the fnum2 on tid2 should have been auto-closed\n");
	cl.close.level = RAW_CLOSE_CLOSE;
	cl.close.in.file.fnum = fnum2;
	cl.close.in.write_time = 0;
	status = smb_raw_close(cli->tree, &cl);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

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

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

	buf = talloc_zero_size(mem_ctx, maxsize);

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

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

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

	setup_buffer(buf, seed, maxsize);

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

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

	setup_buffer(buf, seed, maxsize);

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

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

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

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

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


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

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

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

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

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

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

	setup_buffer(buf, seed, maxsize);

done:
	smbcli_close(cli->tree, fnum);
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemplo n.º 13
0
/*
  test pid ops
  this test demonstrates that exit() only sees the PID
  used for the open() calls
*/
static BOOL test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	NTSTATUS status;
	BOOL ret = True;
	union smb_open io;
	union smb_write wr;
	union smb_close cl;
	int fnum;
	const char *fname = BASEDIR "\\test.txt";
	uint8_t c = 1;
	uint16_t pid1, pid2;

	printf("TESTING PID HANDLING exit() only cares about open() PID\n");

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

	pid1 = cli->session->pid;
	pid2 = pid1 + 1;

	printf("pid1=%d pid2=%d\n", pid1, pid2);

	printf("create a file using pid1\n");
	cli->session->pid = pid1;
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 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.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	printf("write using pid2\n");
	cli->session->pid = pid2;
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("exit pid2\n");
	cli->session->pid = pid2;
	status = smb_raw_exit(cli->session);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the fnum should still be accessible via pid2\n");
	cli->session->pid = pid2;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("exit pid2\n");
	cli->session->pid = pid2;
	status = smb_raw_exit(cli->session);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the fnum should still be accessible via pid1 and pid2\n");
	cli->session->pid = pid1;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);
	cli->session->pid = pid2;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("exit pid1\n");
	cli->session->pid = pid1;
	status = smb_raw_exit(cli->session);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the fnum should not now be accessible via pid1 or pid2\n");
	cli->session->pid = pid1;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
	cli->session->pid = pid2;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("the fnum should have been auto-closed\n");
	cli->session->pid = pid1;
	cl.close.level = RAW_CLOSE_CLOSE;
	cl.close.in.file.fnum = fnum;
	cl.close.in.write_time = 0;
	status = smb_raw_close(cli->tree, &cl);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

done:
	return ret;
}
Exemplo n.º 14
0
/*
  test pid ops with 2 sessions
*/
static BOOL test_pid_2sess(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	NTSTATUS status;
	BOOL ret = True;
	struct smbcli_session *session;
	struct smb_composite_sesssetup setup;
	union smb_open io;
	union smb_write wr;
	union smb_close cl;
	int fnum;
	const char *fname = BASEDIR "\\test.txt";
	uint8_t c = 1;
	uint16_t vuid1, vuid2;

	printf("TESTING PID HANDLING WITH 2 SESSIONS\n");

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

	printf("create a second security context on the same transport\n");
	session = smbcli_session_init(cli->transport, mem_ctx, False);

	setup.in.sesskey = cli->transport->negotiate.sesskey;
	setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
	setup.in.workgroup = lp_workgroup();

	setup.in.credentials = cmdline_credentials;

	status = smb_composite_sesssetup(session, &setup);
	CHECK_STATUS(status, NT_STATUS_OK);	
	session->vuid = setup.out.vuid;

	vuid1 = cli->session->vuid;
	vuid2 = session->vuid;

	printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);

	printf("create a file using the vuid1\n");
	cli->session->vuid = vuid1;
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 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.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	printf("write using the vuid1 (fnum=%d)\n", fnum);
	cli->session->vuid = vuid1;
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;

	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("exit the pid with vuid2\n");
	cli->session->vuid = vuid2;
	status = smb_raw_exit(cli->session);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the fnum should still be accessible\n");
	cli->session->vuid = vuid1;
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("exit the pid with vuid1\n");
	cli->session->vuid = vuid1;
	status = smb_raw_exit(cli->session);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the fnum should not now be accessible\n");
	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("the fnum should have been auto-closed\n");
	cl.close.level = RAW_CLOSE_CLOSE;
	cl.close.in.file.fnum = fnum;
	cl.close.in.write_time = 0;
	status = smb_raw_close(cli->tree, &cl);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

done:
	return ret;
}
Exemplo n.º 15
0
/*
  test a lock that conflicts with an existing lock
*/
static bool test_mux_lock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_lock io;
	NTSTATUS status;
	int fnum;
	bool ret = true;
	struct smbcli_request *req;
	struct smb_lock_entry lock[1];
	struct timeval t;

	printf("TESTING MULTIPLEXED LOCK/LOCK/UNLOCK\n");

	fnum = smbcli_open(cli->tree, BASEDIR "\\write.dat", O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		printf("open failed in mux_write - %s\n", smbcli_errstr(cli->tree));
		ret = false;
		goto done;
	}

	printf("establishing a lock\n");
	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.file.fnum = fnum;
	io.lockx.in.mode = 0;
	io.lockx.in.timeout = 0;
	io.lockx.in.lock_cnt = 1;
	io.lockx.in.ulock_cnt = 0;
	lock[0].pid = 1;
	lock[0].offset = 0;
	lock[0].count = 4;
	io.lockx.in.locks = &lock[0];

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

	printf("the second lock will conflict with the first\n");
	lock[0].pid = 2;
	io.lockx.in.timeout = 1000;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);

	printf("this will too, but we'll unlock while waiting\n");
	t = timeval_current();
	req = smb_raw_lock_send(cli->tree, &io);

	printf("unlock the first range\n");
	lock[0].pid = 1;
	io.lockx.in.ulock_cnt = 1;
	io.lockx.in.lock_cnt = 0;
	io.lockx.in.timeout = 0;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("recv the async reply\n");
	status = smbcli_request_simple_recv(req);
	CHECK_STATUS(status, NT_STATUS_OK);	

	printf("async lock took %.2f msec\n", timeval_elapsed(&t) * 1000);
	if (timeval_elapsed(&t) > 0.1) {
		printf("failed to trigger early lock retry\n");
		return false;		
	}

	printf("reopening with an exit\n");
	smb_raw_exit(cli->session);
	fnum = smbcli_open(cli->tree, BASEDIR "\\write.dat", O_RDWR | O_CREAT, DENY_NONE);

	printf("Now trying with a cancel\n");

	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.file.fnum = fnum;
	io.lockx.in.mode = 0;
	io.lockx.in.timeout = 0;
	io.lockx.in.lock_cnt = 1;
	io.lockx.in.ulock_cnt = 0;
	lock[0].pid = 1;
	lock[0].offset = 0;
	lock[0].count = 4;
	io.lockx.in.locks = &lock[0];

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

	lock[0].pid = 2;
	io.lockx.in.timeout = 1000;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);

	req = smb_raw_lock_send(cli->tree, &io);

	/* cancel the blocking lock */
	smb_raw_ntcancel(req);

	printf("sending 2nd cancel\n");
	/* the 2nd cancel is totally harmless, but tests the server trying to 
	   cancel an already cancelled request */
	smb_raw_ntcancel(req);

	printf("sent 2nd cancel\n");

	lock[0].pid = 1;
	io.lockx.in.ulock_cnt = 1;
	io.lockx.in.lock_cnt = 0;
	io.lockx.in.timeout = 0;
	status = smb_raw_lock(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	status = smbcli_request_simple_recv(req);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);	

	printf("cancel a lock using exit to close file\n");
	lock[0].pid = 1;
	io.lockx.in.ulock_cnt = 0;
	io.lockx.in.lock_cnt = 1;
	io.lockx.in.timeout = 1000;

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

	t = timeval_current();
	lock[0].pid = 2;
	req = smb_raw_lock_send(cli->tree, &io);

	smb_raw_exit(cli->session);
	smb_raw_exit(cli->session);
	smb_raw_exit(cli->session);
	smb_raw_exit(cli->session);

	printf("recv the async reply\n");
	status = smbcli_request_simple_recv(req);
	CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
	printf("async lock exit took %.2f msec\n", timeval_elapsed(&t) * 1000);
	if (timeval_elapsed(&t) > 0.1) {
		printf("failed to trigger early lock failure\n");
		return false;		
	}

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

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

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

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

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

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

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

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

        /* Create the file. */

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

        /* Now try and rename the directory. */

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

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

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

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

    RECREATE_BOTH;

    ZERO_STRUCT(sfinfo);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

done:
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
/*
  test read ops
*/
static BOOL test_read(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_read io;
	NTSTATUS status;
	BOOL ret = True;
	int fnum;
	uint8_t *buf;
	const int maxsize = 90000;
	const char *fname = BASEDIR "\\test.txt";
	const char *test_data = "TEST DATA";
	uint_t seed = time(NULL);

	buf = talloc_zero_size(mem_ctx, maxsize);

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

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

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

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

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

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

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

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

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

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

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

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


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

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

	buf = talloc_zero_size(mem_ctx, maxsize);

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

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

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

	setup_buffer(buf, seed, maxsize);

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

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

	setup_buffer(buf, seed, maxsize);

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

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

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

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

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

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

done:
	smbcli_close(cli->tree, fnum);
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
0
/* 
   basic testing of all RAW_SEARCH_* calls using a single file
*/
static bool test_one_file(struct torture_context *tctx, 
			  struct smbcli_state *cli)
{
	bool ret = true;
	int fnum;
	const char *fname = "\\torture_search.txt";
	const char *fname2 = "\\torture_search-NOTEXIST.txt";
	NTSTATUS status;
	int i;
	union smb_fileinfo all_info, alt_info, name_info, internal_info;
	union smb_search_data *s;

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

	/* call all the levels */
	for (i=0;i<ARRAY_SIZE(levels);i++) {
		NTSTATUS expected_status;
		uint32_t cap = cli->transport->negotiate.capabilities;

		torture_comment(tctx, "testing %s\n", levels[i].name);

		levels[i].status = torture_single_search(cli, tctx, fname, 
							 levels[i].level,
							 levels[i].data_level,
							 0,
							 &levels[i].data);

		/* see if this server claims to support this level */
		if ((cap & levels[i].capability_mask) != levels[i].capability_mask) {
			printf("search level %s(%d) not supported by server\n",
			       levels[i].name, (int)levels[i].level);
			continue;
		}

		if (!NT_STATUS_IS_OK(levels[i].status)) {
			printf("search level %s(%d) failed - %s\n",
			       levels[i].name, (int)levels[i].level, 
			       nt_errstr(levels[i].status));
			ret = false;
			continue;
		}

		status = torture_single_search(cli, tctx, fname2, 
					       levels[i].level,
					       levels[i].data_level,
					       0,
					       &levels[i].data);
		
		expected_status = NT_STATUS_NO_SUCH_FILE;
		if (levels[i].level == RAW_SEARCH_SEARCH ||
		    levels[i].level == RAW_SEARCH_FFIRST ||
		    levels[i].level == RAW_SEARCH_FUNIQUE) {
			expected_status = STATUS_NO_MORE_FILES;
		}
		if (!NT_STATUS_EQUAL(status, expected_status)) {
			printf("search level %s(%d) should fail with %s - %s\n",
			       levels[i].name, (int)levels[i].level, 
			       nt_errstr(expected_status),
			       nt_errstr(status));
			ret = false;
		}
	}

	/* get the all_info file into to check against */
	all_info.generic.level = RAW_FILEINFO_ALL_INFO;
	all_info.generic.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, tctx, &all_info);
	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_ALL_INFO failed");

	alt_info.generic.level = RAW_FILEINFO_ALT_NAME_INFO;
	alt_info.generic.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, tctx, &alt_info);
	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_ALT_NAME_INFO failed");

	internal_info.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;
	internal_info.generic.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, tctx, &internal_info);
	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_INTERNAL_INFORMATION failed");

	name_info.generic.level = RAW_FILEINFO_NAME_INFO;
	name_info.generic.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, tctx, &name_info);
	torture_assert_ntstatus_ok(tctx, status, "RAW_FILEINFO_NAME_INFO failed");

#define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if ((s->sname1.field1) != (v.sname2.out.field2)) { \
			printf("(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \
			       __location__, \
				#sname1, #field1, (int)s->sname1.field1, \
				#sname2, #field2, (int)v.sname2.out.field2); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if (s->sname1.field1 != (~1 & nt_time_to_unix(v.sname2.out.field2))) { \
			printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
			       __location__, \
				#sname1, #field1, timestring(tctx, s->sname1.field1), \
				#sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if (s->sname1.field1 != v.sname2.out.field2) { \
			printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
			       __location__, \
				#sname1, #field1, nt_time_string(tctx, s->sname1.field1), \
				#sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1 || strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \
			printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
			       __location__, \
				#sname1, #field1, s->sname1.field1, \
				#sname2, #field2, v.sname2.out.field2.s); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1.s || \
		    strcmp(s->sname1.field1.s, v.sname2.out.field2.s) || \
		    wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \
			printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
			       __location__, \
				#sname1, #field1, s->sname1.field1.s, \
				#sname2, #field2, v.sname2.out.field2.s); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_NAME(name, sname1, field1, fname, flags) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1.s || \
		    strcmp(s->sname1.field1.s, fname) || \
		    wire_bad_flags(&s->sname1.field1, flags, cli->transport)) { \
			printf("(%s) %s/%s [%s] != %s\n", \
			       __location__, \
				#sname1, #field1, s->sname1.field1.s, \
				fname); \
			ret = false; \
		} \
	}} while (0)

#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \
	s = find(name); \
	if (s) { \
		if (!s->sname1.field1 || \
		    strcmp(s->sname1.field1, fname)) { \
			printf("(%s) %s/%s [%s] != %s\n", \
			       __location__, \
				#sname1, #field1, s->sname1.field1, \
				fname); \
			ret = false; \
		} \
	}} while (0)
	
	/* check that all the results are as expected */
	CHECK_VAL("SEARCH",              search,              attrib, all_info, all_info, attrib&0xFFF);
	CHECK_VAL("STANDARD",            standard,            attrib, all_info, all_info, attrib&0xFFF);
	CHECK_VAL("EA_SIZE",             ea_size,             attrib, all_info, all_info, attrib&0xFFF);
	CHECK_VAL("DIRECTORY_INFO",      directory_info,      attrib, all_info, all_info, attrib);
	CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, attrib, all_info, all_info, attrib);
	CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, attrib, all_info, all_info, attrib);
	CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           attrib, all_info, all_info, attrib);
	CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           attrib, all_info, all_info, attrib);

	CHECK_TIME("SEARCH",             search,              write_time, all_info, all_info, write_time);
	CHECK_TIME("STANDARD",           standard,            write_time, all_info, all_info, write_time);
	CHECK_TIME("EA_SIZE",            ea_size,             write_time, all_info, all_info, write_time);
	CHECK_TIME("STANDARD",           standard,            create_time, all_info, all_info, create_time);
	CHECK_TIME("EA_SIZE",            ea_size,             create_time, all_info, all_info, create_time);
	CHECK_TIME("STANDARD",           standard,            access_time, all_info, all_info, access_time);
	CHECK_TIME("EA_SIZE",            ea_size,             access_time, all_info, all_info, access_time);

	CHECK_NTTIME("DIRECTORY_INFO",      directory_info,      write_time, all_info, all_info, write_time);
	CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, write_time, all_info, all_info, write_time);
	CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, write_time, all_info, all_info, write_time);
	CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           write_time, all_info, all_info, write_time);
	CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           write_time, all_info, all_info, write_time);

	CHECK_NTTIME("DIRECTORY_INFO",      directory_info,      create_time, all_info, all_info, create_time);
	CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, create_time, all_info, all_info, create_time);
	CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, create_time, all_info, all_info, create_time);
	CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           create_time, all_info, all_info, create_time);
	CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           create_time, all_info, all_info, create_time);

	CHECK_NTTIME("DIRECTORY_INFO",      directory_info,      access_time, all_info, all_info, access_time);
	CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, access_time, all_info, all_info, access_time);
	CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, access_time, all_info, all_info, access_time);
	CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           access_time, all_info, all_info, access_time);
	CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           access_time, all_info, all_info, access_time);

	CHECK_NTTIME("DIRECTORY_INFO",      directory_info,      change_time, all_info, all_info, change_time);
	CHECK_NTTIME("FULL_DIRECTORY_INFO", full_directory_info, change_time, all_info, all_info, change_time);
	CHECK_NTTIME("BOTH_DIRECTORY_INFO", both_directory_info, change_time, all_info, all_info, change_time);
	CHECK_NTTIME("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           change_time, all_info, all_info, change_time);
	CHECK_NTTIME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           change_time, all_info, all_info, change_time);

	CHECK_VAL("SEARCH",              search,              size, all_info, all_info, size);
	CHECK_VAL("STANDARD",            standard,            size, all_info, all_info, size);
	CHECK_VAL("EA_SIZE",             ea_size,             size, all_info, all_info, size);
	CHECK_VAL("DIRECTORY_INFO",      directory_info,      size, all_info, all_info, size);
	CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, size, all_info, all_info, size);
	CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, size, all_info, all_info, size);
	CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           size, all_info, all_info, size);
	CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           size, all_info, all_info, size);
	CHECK_VAL("UNIX_INFO",           unix_info,           size, all_info, all_info, size);

	CHECK_VAL("STANDARD",            standard,            alloc_size, all_info, all_info, alloc_size);
	CHECK_VAL("EA_SIZE",             ea_size,             alloc_size, all_info, all_info, alloc_size);
	CHECK_VAL("DIRECTORY_INFO",      directory_info,      alloc_size, all_info, all_info, alloc_size);
	CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, alloc_size, all_info, all_info, alloc_size);
	CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, alloc_size, all_info, all_info, alloc_size);
	CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           alloc_size, all_info, all_info, alloc_size);
	CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           alloc_size, all_info, all_info, alloc_size);
	CHECK_VAL("UNIX_INFO",           unix_info,           alloc_size, all_info, all_info, alloc_size);

	CHECK_VAL("EA_SIZE",             ea_size,             ea_size, all_info, all_info, ea_size);
	CHECK_VAL("FULL_DIRECTORY_INFO", full_directory_info, ea_size, all_info, all_info, ea_size);
	CHECK_VAL("BOTH_DIRECTORY_INFO", both_directory_info, ea_size, all_info, all_info, ea_size);
	CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           ea_size, all_info, all_info, ea_size);
	CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           ea_size, all_info, all_info, ea_size);

	CHECK_STR("SEARCH", search, name, alt_info, alt_name_info, fname);
	CHECK_WSTR("BOTH_DIRECTORY_INFO", both_directory_info, short_name, alt_info, alt_name_info, fname, STR_UNICODE);

	CHECK_NAME("STANDARD",            standard,            name, fname+1, 0);
	CHECK_NAME("EA_SIZE",             ea_size,             name, fname+1, 0);
	CHECK_NAME("DIRECTORY_INFO",      directory_info,      name, fname+1, STR_TERMINATE_ASCII);
	CHECK_NAME("FULL_DIRECTORY_INFO", full_directory_info, name, fname+1, STR_TERMINATE_ASCII);
	CHECK_NAME("NAME_INFO",           name_info,           name, fname+1, STR_TERMINATE_ASCII);
	CHECK_NAME("BOTH_DIRECTORY_INFO", both_directory_info, name, fname+1, STR_TERMINATE_ASCII);
	CHECK_NAME("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           name, fname+1, STR_TERMINATE_ASCII);
	CHECK_NAME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           name, fname+1, STR_TERMINATE_ASCII);
	CHECK_UNIX_NAME("UNIX_INFO",           unix_info,           name, fname+1, STR_TERMINATE_ASCII);

	CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, file_id, internal_info, internal_information, file_id);
	CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, file_id, internal_info, internal_information, file_id);

done:
	smb_raw_exit(cli->session);
	smbcli_unlink(cli->tree, fname);

	return ret;
}
Exemplo n.º 24
0
/*
  test SMBmv ops
*/
static bool test_mv(struct torture_context *tctx,
                    struct smbcli_state *cli)
{
    union smb_rename io;
    NTSTATUS status;
    bool ret = true;
    int fnum = -1;
    const char *fname1 = BASEDIR "\\test1.txt";
    const char *fname2 = BASEDIR "\\test2.txt";
    const char *Fname1 = BASEDIR "\\Test1.txt";
    union smb_fileinfo finfo;
    union smb_open op;

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

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

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

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

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

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

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

    smbcli_close(cli->tree, fnum);

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

	num_connected = i;

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

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

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

	tv = timeval_current();	

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	printf("position_information via paths\n");

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

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

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

done:
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemplo n.º 27
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;
}
Exemplo n.º 28
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;
}
Exemplo n.º 29
0
/* basic testing of all RAW_CLOSE_* calls 
*/
BOOL torture_raw_close(struct torture_context *torture)
{
	struct smbcli_state *cli;
	BOOL ret = True;
	TALLOC_CTX *mem_ctx;
	union smb_close io;
	union smb_flush io_flush;
	int fnum;
	const char *fname = "\\torture_close.txt";
	time_t basetime = (time(NULL) + 3*86400) & ~1;
	union smb_fileinfo finfo, finfo2;
	NTSTATUS status;

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

	mem_ctx = talloc_init("torture_raw_close");

#define REOPEN do { \
	fnum = create_complex_file(cli, mem_ctx, fname); \
	if (fnum == -1) { \
		printf("(%d) Failed to create %s\n", __LINE__, fname); \
		ret = False; \
		goto done; \
	}} while (0)

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

	REOPEN;

	io.close.level = RAW_CLOSE_CLOSE;
	io.close.in.file.fnum = fnum;
	io.close.in.write_time = basetime;
	status = smb_raw_close(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	status = smb_raw_close(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
	
	printf("testing close.in.write_time\n");

	/* the file should have the write time set */
	finfo.generic.level = RAW_FILEINFO_ALL_INFO;
	finfo.generic.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (basetime != nt_time_to_unix(finfo.all_info.out.write_time)) {
		printf("Incorrect write time on file - %s - %s\n",
		       timestring(mem_ctx, basetime), 
		       nt_time_string(mem_ctx, finfo.all_info.out.write_time));
		dump_all_info(mem_ctx, &finfo);
		ret = False;
	}

	printf("testing other times\n");

	/* none of the other times should be set to that time */
	if (nt_time_equal(&finfo.all_info.out.write_time, 
			  &finfo.all_info.out.access_time) ||
	    nt_time_equal(&finfo.all_info.out.write_time, 
			  &finfo.all_info.out.create_time) ||
	    nt_time_equal(&finfo.all_info.out.write_time, 
			  &finfo.all_info.out.change_time)) {
		printf("Incorrect times after close - only write time should be set\n");
		dump_all_info(mem_ctx, &finfo);
		ret = False;
	}
	    

	smbcli_unlink(cli->tree, fname);
	REOPEN;

	finfo2.generic.level = RAW_FILEINFO_ALL_INFO;
	finfo2.generic.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2);
	CHECK_STATUS(status, NT_STATUS_OK);

	io.close.level = RAW_CLOSE_CLOSE;
	io.close.in.file.fnum = fnum;
	io.close.in.write_time = 0;
	status = smb_raw_close(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* the file should have the write time set equal to access time */
	finfo.generic.level = RAW_FILEINFO_ALL_INFO;
	finfo.generic.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (!nt_time_equal(&finfo.all_info.out.write_time, 
			   &finfo2.all_info.out.write_time)) {
		printf("Incorrect write time on file - 0 time should be ignored\n");
		dump_all_info(mem_ctx, &finfo);
		ret = False;
	}

	printf("testing splclose\n");

	/* check splclose on a file */
	REOPEN;
	io.splclose.level = RAW_CLOSE_SPLCLOSE;
	io.splclose.in.file.fnum = fnum;
	status = smb_raw_close(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRerror));

	printf("testing flush\n");
	smbcli_close(cli->tree, fnum);

	io_flush.flush.level		= RAW_FLUSH_FLUSH;
	io_flush.flush.in.file.fnum	= fnum;
	status = smb_raw_flush(cli->tree, &io_flush);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	io_flush.flush_all.level	= RAW_FLUSH_ALL;
	status = smb_raw_flush(cli->tree, &io_flush);
	CHECK_STATUS(status, NT_STATUS_OK);

	REOPEN;

	io_flush.flush.level		= RAW_FLUSH_FLUSH;
	io_flush.flush.in.file.fnum	= fnum;
	status = smb_raw_flush(cli->tree, &io_flush);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Testing SMBexit\n");
	smb_raw_exit(cli->session);

	io_flush.flush.level		= RAW_FLUSH_FLUSH;
	io_flush.flush.in.file.fnum	= fnum;
	status = smb_raw_flush(cli->tree, &io_flush);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
	

done:
	smbcli_close(cli->tree, fnum);
	smbcli_unlink(cli->tree, fname);
	torture_close_connection(cli);
	talloc_free(mem_ctx);
	return ret;
}