Пример #1
0
bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_state *cli)
{
	union smb_open io;
	const char *fname = "testfile";
	bool ret = false;
	struct smbcli_request *req;
	struct smb_echo echo_req;

	smbcli_unlink(cli->tree, fname);

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

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

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

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

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

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

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

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

	smbcli_unlink(cli->tree, fname);

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

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

	io.ntcreatex.in.flags =
		NTCREATEX_FLAGS_REQUEST_OPLOCK
		| NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
	io.ntcreatex.in.root_fid.fnum = dnum;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.fname = fname;

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

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

	ret = true;
 done:
	return ret;
}
Пример #3
0
/*
   basic testing of change notify on directories
*/
static bool torture_smb2_notify_disabled(struct torture_context *torture,
					 struct smb2_tree *tree1)
{
	bool ret = true;
	NTSTATUS status;
	union smb_notify notify;
	union smb_open io;
	struct smb2_handle h1;
	struct smb2_request *req;

	torture_comment(torture, "TESTING CHANGE NOTIFY DISABLED\n");

	smb2_deltree(tree1, BASEDIR);
	smb2_util_rmdir(tree1, BASEDIR);
	/*
	  get a handle on the directory
	*/
	ZERO_STRUCT(io.smb2);
	io.generic.level = RAW_OPEN_SMB2;
	io.smb2.in.create_flags = 0;
	io.smb2.in.desired_access = SEC_FILE_ALL;
	io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
	io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
				NTCREATEX_SHARE_ACCESS_WRITE;
	io.smb2.in.alloc_size = 0;
	io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
	io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
	io.smb2.in.security_flags = 0;
	io.smb2.in.fname = BASEDIR;

	status = smb2_create(tree1, torture, &(io.smb2));
	torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OK,
					   ret, done, "smb2_create");
	h1 = io.smb2.out.file.handle;

	ZERO_STRUCT(notify.smb2);
	notify.smb2.level = RAW_NOTIFY_SMB2;
	notify.smb2.in.buffer_size = 1000;
	notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
	notify.smb2.in.file.handle = h1;
	notify.smb2.in.recursive = true;

	req = smb2_notify_send(tree1, &(notify.smb2));
	status = smb2_notify_recv(req, torture, &(notify.smb2));
	torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_NOT_IMPLEMENTED,
					   ret, done, "smb2_notify_recv");

	status = smb2_util_close(tree1, h1);
	torture_assert_ntstatus_equal_goto(torture, status, NT_STATUS_OK,
					   ret, done, "smb2_create");

done:
	smb2_deltree(tree1, 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
/**
 * 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;
}
Пример #6
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;
}
Пример #7
0
/**
 * do reauth with wrong credentials,
 * hence triggering the error path in reauth.
 * The invalid reauth deletes the session.
 */
bool test_session_reauth6(struct torture_context *tctx, struct smb2_tree *tree)
{
    NTSTATUS status;
    TALLOC_CTX *mem_ctx = talloc_new(tctx);
    char fname[256];
    struct smb2_handle _h1;
    struct smb2_handle *h1 = NULL;
    struct smb2_create io1;
    bool ret = true;
    char *corrupted_password;
    struct cli_credentials *broken_creds;
    bool ok;
    bool encrypted;
    NTSTATUS expected;
    enum credentials_use_kerberos krb_state;

    krb_state = cli_credentials_get_kerberos_state(cmdline_credentials);
    if (krb_state == CRED_MUST_USE_KERBEROS) {
        torture_skip(tctx,
                     "Can't test failing session setup with kerberos.");
    }

    encrypted = smb2cli_tcon_is_encryption_on(tree->smbXcli);

    /* Add some random component to the file name. */
    snprintf(fname, sizeof(fname), "session_reauth1_%s.dat",
             generate_random_str(tctx, 8));

    smb2_util_unlink(tree, fname);

    smb2_oplock_create_share(&io1, fname,
                             smb2_util_share_access(""),
                             smb2_util_oplock_level("b"));
    io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;

    status = smb2_create(tree, mem_ctx, &io1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");
    _h1 = io1.out.file.handle;
    h1 = &_h1;
    CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");

    /*
     * reauthentication with invalid credentials:
     */

    broken_creds = cli_credentials_shallow_copy(mem_ctx,
                   cmdline_credentials);
    torture_assert(tctx, (broken_creds != NULL), "talloc error");

    corrupted_password = talloc_asprintf(mem_ctx, "%s%s",
                                         cli_credentials_get_password(broken_creds),
                                         "corrupt");
    torture_assert(tctx, (corrupted_password != NULL), "talloc error");

    ok = cli_credentials_set_password(broken_creds, corrupted_password,
                                      CRED_SPECIFIED);
    torture_assert(tctx, ok, "cli_credentials_set_password not ok");

    status = smb2_session_setup_spnego(tree->session,
                                       broken_creds,
                                       0 /* previous_session_id */);
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_LOGON_FAILURE, ret, done,
                                       "smb2_session_setup_spnego "
                                       "returned unexpected status");

    torture_comment(tctx, "did failed reauth\n");
    /*
     * now verify that the invalid session reauth has closed our session
     */

    if (encrypted) {
        expected = NT_STATUS_CONNECTION_DISCONNECTED;
    } else {
        expected = NT_STATUS_USER_SESSION_DELETED;
    }

    smb2_oplock_create_share(&io1, fname,
                             smb2_util_share_access(""),
                             smb2_util_oplock_level("b"));

    status = smb2_create(tree, mem_ctx, &io1);
    torture_assert_ntstatus_equal_goto(tctx, status, expected,
                                       ret, done, "smb2_create "
                                       "returned unexpected status");

done:
    if (h1 != NULL) {
        smb2_util_close(tree, *h1);
    }

    smb2_util_unlink(tree, fname);

    talloc_free(tree);

    talloc_free(mem_ctx);

    return ret;
}
Пример #8
0
/**
 * test renaming after reauth.
 * compare security descriptors before and after rename/reauth
 */
bool test_session_reauth5(struct torture_context *tctx, struct smb2_tree *tree)
{
    NTSTATUS status;
    TALLOC_CTX *mem_ctx = talloc_new(tctx);
    char dname[256];
    char fname[256];
    char fname2[256];
    struct smb2_handle _dh1;
    struct smb2_handle *dh1 = NULL;
    struct smb2_handle _h1;
    struct smb2_handle *h1 = NULL;
    struct smb2_create io1;
    bool ret = true;
    bool ok;
    union smb_fileinfo qfinfo;
    union smb_setfileinfo sfinfo;
    struct cli_credentials *anon_creds = NULL;
    uint32_t secinfo_flags = SECINFO_OWNER
                             | SECINFO_GROUP
                             | SECINFO_DACL
                             | SECINFO_PROTECTED_DACL
                             | SECINFO_UNPROTECTED_DACL;
    struct security_descriptor *f_sd1;
    struct security_descriptor *d_sd1 = NULL;
    struct security_ace ace;
    struct dom_sid *extra_sid;

    /* Add some random component to the file name. */
    snprintf(dname, sizeof(dname), "session_reauth5_%s.d",
             generate_random_str(tctx, 8));
    snprintf(fname, sizeof(fname), "%s\\file.dat", dname);

    ok = smb2_util_setup_dir(tctx, tree, dname);
    torture_assert(tctx, ok, "smb2_util_setup_dir not ok");

    status = torture_smb2_testdir(tree, dname, &_dh1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "torture_smb2_testdir failed");
    dh1 = &_dh1;

    smb2_oplock_create_share(&io1, fname,
                             smb2_util_share_access(""),
                             smb2_util_oplock_level("b"));

    status = smb2_create(tree, mem_ctx, &io1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");
    _h1 = io1.out.file.handle;
    h1 = &_h1;
    CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");

    /* get the security descriptor */

    ZERO_STRUCT(qfinfo);

    qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    qfinfo.query_secdesc.in.file.handle = _h1;
    qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

    status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

    f_sd1 = qfinfo.query_secdesc.out.sd;

    /* re-authenticate as anonymous */

    anon_creds = cli_credentials_init_anon(mem_ctx);
    torture_assert(tctx, (anon_creds != NULL), "talloc error");

    status = smb2_session_setup_spnego(tree->session,
                                       anon_creds,
                                       0 /* previous_session_id */);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_session_setup_spnego failed");

    /* try to rename the file: fails */

    snprintf(fname2, sizeof(fname2), "%s\\file2.dat", dname);

    status = smb2_util_unlink(tree, fname2);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_util_unlink failed");


    ZERO_STRUCT(sfinfo);
    sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    sfinfo.rename_information.in.file.handle = _h1;
    sfinfo.rename_information.in.overwrite = true;
    sfinfo.rename_information.in.new_name = fname2;

    status = smb2_setinfo_file(tree, &sfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_ACCESS_DENIED,
                                       ret, done, "smb2_setinfo_file "
                                       "returned unexpected status");

    /* re-authenticate as original user again */

    status = smb2_session_setup_spnego(tree->session,
                                       cmdline_credentials,
                                       0 /* previous_session_id */);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_session_setup_spnego failed");

    /* give full access on the file to anonymous */

    extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);

    ZERO_STRUCT(ace);
    ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
    ace.flags = 0;
    ace.access_mask = SEC_RIGHTS_FILE_ALL;
    ace.trustee = *extra_sid;

    status = security_descriptor_dacl_add(f_sd1, &ace);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "security_descriptor_dacl_add failed");

    ZERO_STRUCT(sfinfo);
    sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    sfinfo.set_secdesc.in.file.handle = _h1;
    sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
    sfinfo.set_secdesc.in.sd = f_sd1;

    status = smb2_setinfo_file(tree, &sfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_setinfo_file failed");

    /* re-get the security descriptor */

    ZERO_STRUCT(qfinfo);

    qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    qfinfo.query_secdesc.in.file.handle = _h1;
    qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

    status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

    /* re-authenticate as anonymous - again */

    anon_creds = cli_credentials_init_anon(mem_ctx);
    torture_assert(tctx, (anon_creds != NULL), "talloc error");

    status = smb2_session_setup_spnego(tree->session,
                                       anon_creds,
                                       0 /* previous_session_id */);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_session_setup_spnego failed");

    /* try to rename the file: fails */

    ZERO_STRUCT(sfinfo);
    sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    sfinfo.rename_information.in.file.handle = _h1;
    sfinfo.rename_information.in.overwrite = true;
    sfinfo.rename_information.in.new_name = fname2;

    status = smb2_setinfo_file(tree, &sfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_ACCESS_DENIED,
                                       ret, done, "smb2_setinfo_file "
                                       "returned unexpected status");

    /* give full access on the parent dir to anonymous */

    ZERO_STRUCT(qfinfo);

    qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    qfinfo.query_secdesc.in.file.handle = _dh1;
    qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

    status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

    d_sd1 = qfinfo.query_secdesc.out.sd;

    ZERO_STRUCT(ace);
    ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
    ace.flags = 0;
    ace.access_mask = SEC_RIGHTS_FILE_ALL;
    ace.trustee = *extra_sid;

    status = security_descriptor_dacl_add(d_sd1, &ace);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "security_descriptor_dacl_add failed");

    ZERO_STRUCT(sfinfo);
    sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    sfinfo.set_secdesc.in.file.handle = _dh1;
    sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
    sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    sfinfo.set_secdesc.in.sd = d_sd1;

    status = smb2_setinfo_file(tree, &sfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_setinfo_file failed");

    ZERO_STRUCT(qfinfo);

    qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    qfinfo.query_secdesc.in.file.handle = _dh1;
    qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

    status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

    status = smb2_util_close(tree, _dh1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_util_close failed");
    dh1 = NULL;

    /* try to rename the file: still fails */

    ZERO_STRUCT(sfinfo);
    sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    sfinfo.rename_information.in.file.handle = _h1;
    sfinfo.rename_information.in.overwrite = true;
    sfinfo.rename_information.in.new_name = fname2;

    status = smb2_setinfo_file(tree, &sfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_ACCESS_DENIED,
                                       ret, done, "smb2_setinfo_file "
                                       "returned unexpected status");

    /* re-authenticate as original user - again */

    status = smb2_session_setup_spnego(tree->session,
                                       cmdline_credentials,
                                       0 /* previous_session_id */);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_session_setup_spnego failed");

    /* rename the file - for verification that it works */

    ZERO_STRUCT(sfinfo);
    sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
    sfinfo.rename_information.in.file.handle = _h1;
    sfinfo.rename_information.in.overwrite = true;
    sfinfo.rename_information.in.new_name = fname2;

    status = smb2_setinfo_file(tree, &sfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_setinfo_file failed");

    /* closs the file, check it is gone and reopen under the new name */

    status = smb2_util_close(tree, _h1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_util_close failed");
    ZERO_STRUCT(io1);

    smb2_generic_create_share(&io1,
                              NULL /* lease */, false /* dir */,
                              fname,
                              NTCREATEX_DISP_OPEN,
                              smb2_util_share_access(""),
                              smb2_util_oplock_level("b"),
                              0 /* leasekey */, 0 /* leasestate */);

    status = smb2_create(tree, mem_ctx, &io1);
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_OBJECT_NAME_NOT_FOUND,
                                       ret, done, "smb2_create "
                                       "returned unexpected status");

    ZERO_STRUCT(io1);

    smb2_generic_create_share(&io1,
                              NULL /* lease */, false /* dir */,
                              fname2,
                              NTCREATEX_DISP_OPEN,
                              smb2_util_share_access(""),
                              smb2_util_oplock_level("b"),
                              0 /* leasekey */, 0 /* leasestate */);

    status = smb2_create(tree, mem_ctx, &io1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");
    _h1 = io1.out.file.handle;
    h1 = &_h1;
    CHECK_CREATED(tctx, &io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");

    /* try to access the file via the old handle */

    ZERO_STRUCT(qfinfo);

    qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    qfinfo.query_secdesc.in.file.handle = _h1;
    qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;

    status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

done:
    if (dh1 != NULL) {
        smb2_util_close(tree, *dh1);
    }
    if (h1 != NULL) {
        smb2_util_close(tree, *h1);
    }

    smb2_deltree(tree, dname);

    talloc_free(tree);

    talloc_free(mem_ctx);

    return ret;
}
Пример #9
0
/**
 * basic test for doing a session reconnect
 */
bool test_session_reconnect1(struct torture_context *tctx, struct smb2_tree *tree)
{
    NTSTATUS status;
    TALLOC_CTX *mem_ctx = talloc_new(tctx);
    char fname[256];
    struct smb2_handle _h1;
    struct smb2_handle *h1 = NULL;
    struct smb2_handle _h2;
    struct smb2_handle *h2 = NULL;
    struct smb2_create io1, io2;
    uint64_t previous_session_id;
    bool ret = true;
    struct smb2_tree *tree2 = NULL;
    union smb_fileinfo qfinfo;

    /* Add some random component to the file name. */
    snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
             generate_random_str(tctx, 8));

    smb2_util_unlink(tree, fname);

    smb2_oplock_create_share(&io1, fname,
                             smb2_util_share_access(""),
                             smb2_util_oplock_level("b"));

    status = smb2_create(tree, mem_ctx, &io1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");
    _h1 = io1.out.file.handle;
    h1 = &_h1;
    CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");

    /* disconnect, reconnect and then do durable reopen */
    previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);

    torture_assert_goto(tctx, torture_smb2_connection_ext(tctx, previous_session_id,
                        &tree->session->transport->options, &tree2),
                        ret, done,
                        "session reconnect failed\n");

    /* try to access the file via the old handle */

    ZERO_STRUCT(qfinfo);
    qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
    qfinfo.generic.in.file.handle = _h1;
    status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
    torture_assert_ntstatus_equal_goto(tctx, status,
                                       NT_STATUS_USER_SESSION_DELETED,
                                       ret, done, "smb2_getinfo_file "
                                       "returned unexpected status");
    h1 = NULL;

    smb2_oplock_create_share(&io2, fname,
                             smb2_util_share_access(""),
                             smb2_util_oplock_level("b"));

    status = smb2_create(tree2, mem_ctx, &io2);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");

    CHECK_CREATED(tctx, &io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");
    _h2 = io2.out.file.handle;
    h2 = &_h2;

done:
    if (h1 != NULL) {
        smb2_util_close(tree, *h1);
    }
    if (h2 != NULL) {
        smb2_util_close(tree2, *h2);
    }

    if (tree2 != NULL) {
        smb2_util_unlink(tree2, fname);
    }
    smb2_util_unlink(tree, fname);

    talloc_free(tree);
    talloc_free(tree2);

    talloc_free(mem_ctx);

    return ret;
}
Пример #10
0
static bool test_session_expire1(struct torture_context *tctx)
{
    NTSTATUS status;
    bool ret = false;
    struct smbcli_options options;
    const char *host = torture_setting_string(tctx, "host", NULL);
    const char *share = torture_setting_string(tctx, "share", NULL);
    struct cli_credentials *credentials = cmdline_credentials;
    struct smb2_tree *tree = NULL;
    enum credentials_use_kerberos use_kerberos;
    char fname[256];
    struct smb2_handle _h1;
    struct smb2_handle *h1 = NULL;
    struct smb2_create io1;
    union smb_fileinfo qfinfo;
    size_t i;

    use_kerberos = cli_credentials_get_kerberos_state(credentials);
    if (use_kerberos != CRED_MUST_USE_KERBEROS) {
        torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
        torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
    }

    torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
                             "please use -k yes");

    lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");

    lpcfg_smbcli_options(tctx->lp_ctx, &options);

    status = smb2_connect(tctx,
                          host,
                          lpcfg_smb_ports(tctx->lp_ctx),
                          share,
                          lpcfg_resolve_context(tctx->lp_ctx),
                          credentials,
                          &tree,
                          tctx->ev,
                          &options,
                          lpcfg_socket_options(tctx->lp_ctx),
                          lpcfg_gensec_settings(tctx, tctx->lp_ctx)
                         );
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_connect failed");

    /* Add some random component to the file name. */
    snprintf(fname, sizeof(fname), "session_expire1_%s.dat",
             generate_random_str(tctx, 8));

    smb2_util_unlink(tree, fname);

    smb2_oplock_create_share(&io1, fname,
                             smb2_util_share_access(""),
                             smb2_util_oplock_level("b"));
    io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;

    status = smb2_create(tree, tctx, &io1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_create failed");
    _h1 = io1.out.file.handle;
    h1 = &_h1;
    CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
    torture_assert_int_equal(tctx, io1.out.oplock_level,
                             smb2_util_oplock_level("b"),
                             "oplock_level incorrect");

    /* get the security descriptor */

    ZERO_STRUCT(qfinfo);

    qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
    qfinfo.access_information.in.file.handle = _h1;

    for (i=0; i < 2; i++) {
        torture_comment(tctx, "query info => OK\n");

        ZERO_STRUCT(qfinfo.access_information.out);
        status = smb2_getinfo_file(tree, tctx, &qfinfo);
        torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                        "smb2_getinfo_file failed");

        torture_comment(tctx, "sleep 5 seconds\n");
        smb_msleep(5*1000);

        torture_comment(tctx, "query info => EXPIRED\n");
        ZERO_STRUCT(qfinfo.access_information.out);
        status = smb2_getinfo_file(tree, tctx, &qfinfo);
        torture_assert_ntstatus_equal_goto(tctx, status,
                                           NT_STATUS_NETWORK_SESSION_EXPIRED,
                                           ret, done, "smb2_getinfo_file "
                                           "returned unexpected status");

        /*
         * the krb5 library may not handle expired creds
         * well, lets start with an empty ccache.
         */
        cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);

        torture_comment(tctx, "reauth => OK\n");
        status = smb2_session_setup_spnego(tree->session,
                                           credentials,
                                           0 /* previous_session_id */);
        torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                        "smb2_session_seutup_spnego failed");
    }

    ZERO_STRUCT(qfinfo.access_information.out);
    status = smb2_getinfo_file(tree, tctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

    ret = true;
done:
    if (h1 != NULL) {
        smb2_util_close(tree, *h1);
    }

    talloc_free(tree);
    lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
    return ret;
}
Пример #11
0
static bool test_session_expire1(struct torture_context *tctx)
{
	NTSTATUS status;
	bool ret = false;
	struct smbcli_options options;
	struct smbcli_session_options session_options;
	const char *host = torture_setting_string(tctx, "host", NULL);
	const char *share = torture_setting_string(tctx, "share", NULL);
	struct cli_credentials *credentials = cmdline_credentials;
	struct smbcli_state *cli = NULL;
	enum credentials_use_kerberos use_kerberos;
	char fname[256];
	union smb_fileinfo qfinfo;
	uint16_t vuid;
	uint16_t fnum = 0;
	struct smb_composite_sesssetup io_sesssetup;
	size_t i;

	use_kerberos = cli_credentials_get_kerberos_state(credentials);
	if (use_kerberos != CRED_MUST_USE_KERBEROS) {
		torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
		torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
	}

	torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
				 "please use -k yes");

	lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");

	lpcfg_smbcli_options(tctx->lp_ctx, &options);

	lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options);

	status = smbcli_full_connection(tctx, &cli,
					host,
					lpcfg_smb_ports(tctx->lp_ctx),
					share, NULL,
					lpcfg_socket_options(tctx->lp_ctx),
					credentials,
					lpcfg_resolve_context(tctx->lp_ctx),
					tctx->ev, &options, &session_options,
					lpcfg_gensec_settings(tctx, tctx->lp_ctx));
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"smbcli_full_connection failed");

	vuid = cli->session->vuid;

	/* Add some random component to the file name. */
	snprintf(fname, 256, "session_expire1_%s.dat",
		 generate_random_str(tctx, 8));

	smbcli_unlink(cli->tree, fname);

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

	/* get the access information */

	ZERO_STRUCT(qfinfo);

	qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
	qfinfo.access_information.in.file.fnum = fnum;

	for (i=0; i < 2; i++) {
		torture_comment(tctx, "query info => OK\n");
		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"raw_fileinfo failed");

		torture_comment(tctx, "sleep 5 seconds\n");
		smb_msleep(5*1000);
	}

	/*
	 * the krb5 library may not handle expired creds
	 * well, lets start with an empty ccache.
	 */
	cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);

	/*
	 * now with CAP_DYNAMIC_REAUTH
	 *
	 * This should trigger NT_STATUS_NETWORK_SESSION_EXPIRED
	 */
	ZERO_STRUCT(io_sesssetup);
	io_sesssetup.in.sesskey      = cli->transport->negotiate.sesskey;
	io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities;
	io_sesssetup.in.capabilities |= CAP_DYNAMIC_REAUTH;
	io_sesssetup.in.credentials  = credentials;
	io_sesssetup.in.workgroup    = lpcfg_workgroup(tctx->lp_ctx);
	io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(tctx,
							tctx->lp_ctx);

	torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n");
	ZERO_STRUCT(io_sesssetup.out);
	status = smb_composite_sesssetup(cli->session, &io_sesssetup);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"reauth failed");
	torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
				      ret, done, "reauth");

	for (i=0; i < 2; i++) {
		torture_comment(tctx, "query info => OK\n");
		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"raw_fileinfo failed");

		torture_comment(tctx, "sleep 5 seconds\n");
		smb_msleep(5*1000);

		torture_comment(tctx, "query info => EXPIRED\n");
		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_equal_goto(tctx, status,
					NT_STATUS_NETWORK_SESSION_EXPIRED,
					ret, done, "raw_fileinfo expired");

		/*
		 * the krb5 library may not handle expired creds
		 * well, lets start with an empty ccache.
		 */
		cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);

		torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n");
		ZERO_STRUCT(io_sesssetup.out);
		status = smb_composite_sesssetup(cli->session, &io_sesssetup);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"reauth failed");
		torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
					      ret, done, "reauth");
	}

	torture_comment(tctx, "query info => OK\n");
	ZERO_STRUCT(qfinfo.access_information.out);
	status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"raw_fileinfo failed");

	/*
	 * the krb5 library may not handle expired creds
	 * well, lets start with an empty ccache.
	 */
	cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);

	/*
	 * now without CAP_DYNAMIC_REAUTH
	 *
	 * This should not trigger NT_STATUS_NETWORK_SESSION_EXPIRED
	 */
	torture_comment(tctx, "reauth without CAP_DYNAMIC_REAUTH => OK\n");
	io_sesssetup.in.capabilities &= ~CAP_DYNAMIC_REAUTH;

	ZERO_STRUCT(io_sesssetup.out);
	status = smb_composite_sesssetup(cli->session, &io_sesssetup);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"reauth failed");
	torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid,
				      ret, done, "reauth");

	for (i=0; i < 2; i++) {
		torture_comment(tctx, "query info => OK\n");

		ZERO_STRUCT(qfinfo.access_information.out);
		status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
						"raw_fileinfo failed");

		torture_comment(tctx, "sleep 5 seconds\n");
		smb_msleep(5*1000);
	}

	torture_comment(tctx, "query info => OK\n");
	ZERO_STRUCT(qfinfo.access_information.out);
	status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"raw_fileinfo failed");

	ret = true;
done:
	if (fnum > 0) {
		smbcli_close(cli->tree, fnum);
	}

	talloc_free(cli);
	lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
	return ret;
}