Пример #1
0
/*
  set info on a open file
*/
static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, 
				 struct ntvfs_request *req, 
				 union smb_setfileinfo *io)
{
	struct cvfs_private *p = ntvfs->private_data;
	struct smbcli_request *c_req;

	SETUP_PID_AND_FILE;

	if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) {
		return smb_raw_setfileinfo(p->tree, io);
	}
	c_req = smb_raw_setfileinfo_send(p->tree, io);

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

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

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

	if (strchr(fname, ':') == NULL) {
		/* setup some EAs */
		setfile.generic.level = RAW_SFILEINFO_EA_SET;
		setfile.generic.in.file.fnum = fnum;
		setfile.ea_set.in.num_eas = 2;	
		setfile.ea_set.in.eas = talloc_array(mem_ctx, struct ea_struct, 2);
		setfile.ea_set.in.eas[0].flags = 0;
		setfile.ea_set.in.eas[0].name.s = "EAONE";
		setfile.ea_set.in.eas[0].value = data_blob_talloc(mem_ctx, "VALUE1", 6);
		setfile.ea_set.in.eas[1].flags = 0;
		setfile.ea_set.in.eas[1].name.s = "SECONDEA";
		setfile.ea_set.in.eas[1].value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
		status = smb_raw_setfileinfo(cli->tree, &setfile);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to setup EAs\n");
		}
	}
Пример #3
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;
}
Пример #4
0
static bool
torture_raw_sfileinfo_archive(struct torture_context *tctx,
                              struct smbcli_state *cli)
{
    const char *fname = BASEDIR "\\test_archive.dat";
    NTSTATUS status;
    bool ret = true;
    union smb_open io;
    union smb_setfileinfo sfinfo;
    union smb_fileinfo finfo;
    uint16_t fnum=0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

done:
    smbcli_close(cli->tree, fnum);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
0
static bool test_eas(struct smbcli_state *cli, struct torture_context *tctx)
{
	NTSTATUS status;
	union smb_setfileinfo setfile;
	union smb_open io;
	const char *fname = BASEDIR "\\ea.txt";
	bool ret = true;
	int fnum = -1;

	torture_comment(tctx, "TESTING SETFILEINFO EA_SET\n");

	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid.fnum = 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, tctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	ret &= check_ea(cli, fname, "EAONE", NULL);

	torture_comment(tctx, "Adding first two EAs\n");
	setfile.generic.level = RAW_SFILEINFO_EA_SET;
	setfile.generic.in.file.fnum = fnum;
	setfile.ea_set.in.num_eas = 2;
	setfile.ea_set.in.eas = talloc_array(tctx, struct ea_struct, 2);
	setfile.ea_set.in.eas[0].flags = 0;
	setfile.ea_set.in.eas[0].name.s = "EAONE";
	setfile.ea_set.in.eas[0].value = data_blob_string_const("VALUE1");
	setfile.ea_set.in.eas[1].flags = 0;
	setfile.ea_set.in.eas[1].name.s = "SECONDEA";
	setfile.ea_set.in.eas[1].value = data_blob_string_const("ValueTwo");

	status = smb_raw_setfileinfo(cli->tree, &setfile);
	CHECK_STATUS(status, NT_STATUS_OK);

	ret &= check_ea(cli, fname, "EAONE", "VALUE1");
	ret &= check_ea(cli, fname, "SECONDEA", "ValueTwo");

	torture_comment(tctx, "Modifying 2nd EA\n");
	setfile.ea_set.in.num_eas = 1;
	setfile.ea_set.in.eas[0].name.s = "SECONDEA";
	setfile.ea_set.in.eas[0].value = data_blob_string_const(" Changed Value");
	status = smb_raw_setfileinfo(cli->tree, &setfile);
	CHECK_STATUS(status, NT_STATUS_OK);

	ret &= check_ea(cli, fname, "EAONE", "VALUE1");
	ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");

	torture_comment(tctx, "Setting a NULL EA\n");
	setfile.ea_set.in.eas[0].value = data_blob(NULL, 0);
	setfile.ea_set.in.eas[0].name.s = "NULLEA";
	status = smb_raw_setfileinfo(cli->tree, &setfile);
	CHECK_STATUS(status, NT_STATUS_OK);

	ret &= check_ea(cli, fname, "EAONE", "VALUE1");
	ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
	ret &= check_ea(cli, fname, "NULLEA", NULL);

	torture_comment(tctx, "Deleting first EA\n");
	setfile.ea_set.in.eas[0].flags = 0;
	setfile.ea_set.in.eas[0].name.s = "EAONE";
	setfile.ea_set.in.eas[0].value = data_blob(NULL, 0);
	status = smb_raw_setfileinfo(cli->tree, &setfile);
	CHECK_STATUS(status, NT_STATUS_OK);

	ret &= check_ea(cli, fname, "EAONE", NULL);
	ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");

	torture_comment(tctx, "Deleting second EA\n");
	setfile.ea_set.in.eas[0].flags = 0;
	setfile.ea_set.in.eas[0].name.s = "SECONDEA";
	setfile.ea_set.in.eas[0].value = data_blob(NULL, 0);
	status = smb_raw_setfileinfo(cli->tree, &setfile);
	CHECK_STATUS(status, NT_STATUS_OK);

	ret &= check_ea(cli, fname, "EAONE", NULL);
	ret &= check_ea(cli, fname, "SECONDEA", NULL);

done:
	smbcli_close(cli->tree, fnum);
	return ret;
}
Пример #8
0
/*
 * Helper function to retrieve the max. ea size for one ea name
 */
static int test_one_eamax(struct torture_context *tctx,
			  struct smbcli_state *cli, const int fnum,
			  const char *eaname, DATA_BLOB eablob,
			  const int eastart, const int eadebug)
{
	NTSTATUS status;
	struct ea_struct eastruct;
	union smb_setfileinfo setfile;
	int i, high, low, maxeasize;

	setfile.generic.level = RAW_SFILEINFO_EA_SET;
	setfile.generic.in.file.fnum = fnum;
	setfile.ea_set.in.num_eas = 1;
	setfile.ea_set.in.eas = &eastruct;
	setfile.ea_set.in.eas->flags = 0;
	setfile.ea_set.in.eas->name.s = eaname;
	setfile.ea_set.in.eas->value = eablob;

	maxeasize = eablob.length;
	i = eastart;
	low = 0;
	high = maxeasize;

	do {
		if (eadebug) {
			torture_comment(tctx, "Testing EA size: %d\n", i);
		}
		setfile.ea_set.in.eas->value.length = i;

		status = smb_raw_setfileinfo(cli->tree, &setfile);

		if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
			if (eadebug) {
				torture_comment(tctx, "[%s] EA size %d succeeded! "
					"(high=%d low=%d)\n",
					eaname, i, high, low);
			}
			low = i;
			if (low == maxeasize) {
				torture_comment(tctx, "Max. EA size for \"%s\"=%d "
					"[but could be possibly larger]\n",
					eaname, low);
				break;
			}
			if (high - low == 1 && high != maxeasize) {
				torture_comment(tctx, "Max. EA size for \"%s\"=%d\n",
					eaname, low);
				break;
			}
			i += (high - low + 1) / 2;
		} else {
			if (eadebug) {
				torture_comment(tctx, "[%s] EA size %d failed!    "
					"(high=%d low=%d) [%s]\n",
					eaname, i, high, low,
					nt_errstr(status));
			}
			high = i;
			if (high - low <= 1) {
				torture_comment(tctx, "Max. EA size for \"%s\"=%d\n",
					eaname, low);
				break;
			}
			i -= (high - low + 1) / 2;
		}
	} while (true);

	return low;
}
Пример #9
0
		}
	}

	/* make sure all the timestamps aren't the same */
	ZERO_STRUCT(setfile);
	setfile.generic.level = RAW_SFILEINFO_BASIC_INFO;
	setfile.generic.in.file.fnum = fnum;

	unix_to_nt_time(&setfile.basic_info.in.create_time,
	    t + 9*30*24*60*60);
	unix_to_nt_time(&setfile.basic_info.in.access_time,
	    t + 6*30*24*60*60);
	unix_to_nt_time(&setfile.basic_info.in.write_time,
	    t + 3*30*24*60*60);

	status = smb_raw_setfileinfo(cli->tree, &setfile);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to setup file times - %s\n", nt_errstr(status));
	}

	/* make sure all the timestamps aren't the same */
	fileinfo.generic.level = RAW_FILEINFO_BASIC_INFO;
	fileinfo.generic.in.file.fnum = fnum;

	status = smb_raw_fileinfo(cli->tree, mem_ctx, &fileinfo);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to query file times - %s\n", nt_errstr(status));
	}

	if (setfile.basic_info.in.create_time != fileinfo.basic_info.out.create_time) {
		printf("create_time not setup correctly\n");
Пример #10
0
NTSTATUS gp_set_gpt_security_descriptor(struct gp_context *gp_ctx,
                                        struct gp_object *gpo,
                                        struct security_descriptor *sd)
{
	TALLOC_CTX *mem_ctx;
	NTSTATUS status;
	union smb_setfileinfo fileinfo;
	union smb_open io;
	union smb_close io_close;

	/* Create a connection to sysvol if it is not already there */
	if (gp_ctx->cli == NULL) {
		status = gp_cli_connect(gp_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Failed to create cli connection to DC\n"));
			return status;
		}
	}

	/* Create a forked memory context which can be freed easily */
	mem_ctx = talloc_new(gp_ctx);
	NT_STATUS_HAVE_NO_MEMORY(mem_ctx);

	/* Open the directory with NTCreate AndX call */
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid.fnum = 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_OPEN;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = gp_get_share_path(mem_ctx, gpo->file_sys_path);
	status = smb_raw_open(gp_ctx->cli->tree, mem_ctx, &io);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Can't open GPT directory\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Set the security descriptor on the directory */
	fileinfo.generic.level = RAW_FILEINFO_SEC_DESC;
	fileinfo.set_secdesc.in.file.fnum = io.ntcreatex.out.file.fnum;
	fileinfo.set_secdesc.in.secinfo_flags = SECINFO_PROTECTED_DACL |
	                                        SECINFO_OWNER |
	                                        SECINFO_GROUP |
	                                        SECINFO_DACL;
	fileinfo.set_secdesc.in.sd = sd;
	status = smb_raw_setfileinfo(gp_ctx->cli->tree, &fileinfo);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to set security descriptor on the GPT\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Close the directory */
	io_close.close.level = RAW_CLOSE_CLOSE;
	io_close.close.in.file.fnum = io.ntcreatex.out.file.fnum;
	io_close.close.in.write_time = 0;
	status = smb_raw_close(gp_ctx->cli->tree, &io_close);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to close directory\n"));
		talloc_free(mem_ctx);
		return status;
	}

	talloc_free(mem_ctx);
	return NT_STATUS_OK;
}