Exemplo n.º 1
0
static bool test_session_reauth1(struct torture_context *tctx,
				 struct smbcli_state *cli)
{
	NTSTATUS status;
	struct smb_composite_sesssetup io;
	int fnum, num;
	const int dlen = 255;
	char *data;
	char fname[256];
	char buf[dlen+1];
	bool ok = true;
	uint16_t vuid1 = cli->session->vuid;

	data = generate_random_str(tctx, dlen);
	torture_assert(tctx, (data != NULL), "memory allocation failed");
	snprintf(fname, sizeof(fname), "raw_session_reconnect_%.8s.dat", data);

	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), ok,
					done, "create file");
	torture_assert_goto(tctx, fnum > 0, ok, done, "create file");

	num = smbcli_smbwrite(cli->tree, fnum, data, 0, dlen);
	torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "write file");

	ZERO_STRUCT(io);
	io.in.sesskey         = cli->transport->negotiate.sesskey;
	io.in.capabilities    = cli->transport->negotiate.capabilities;
	io.in.credentials     = cmdline_credentials;
	io.in.workgroup       = lpcfg_workgroup(tctx->lp_ctx);
	io.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx);
	status = smb_composite_sesssetup(cli->session, &io);
	torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "setup2");
	torture_assert_int_equal_goto(tctx, io.out.vuid, vuid1, ok, done, "setup2");

	buf[dlen] = '\0';

	num = smbcli_read(cli->tree, fnum, &buf, 0, dlen);
	torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "read file");
	torture_assert_str_equal_goto(tctx, buf, data, ok, done, "read file");

done:
	talloc_free(data);

	if (fnum > 0) {
		status = smbcli_close(cli->tree, fnum);
		torture_assert_ntstatus_ok(tctx, status, "close");
	}
	return ok;
}
Exemplo n.º 2
0
static NTSTATUS populate_tree(struct torture_context *tctx,
			      TALLOC_CTX *mem_ctx,
			      struct smb2_tree *tree,
			      struct file_elem *files,
			      int nfiles,
			      struct smb2_handle *h_out)
{
	struct smb2_create create;
	char **strs = NULL;
	NTSTATUS status;
	bool ret;
	int i;

	smb2_deltree(tree, DNAME);

	ZERO_STRUCT(create);
	create.in.desired_access = SEC_RIGHTS_DIR_ALL;
	create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
	create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
				 NTCREATEX_SHARE_ACCESS_WRITE |
				 NTCREATEX_SHARE_ACCESS_DELETE;
	create.in.create_disposition = NTCREATEX_DISP_CREATE;
	create.in.fname = DNAME;

	status = smb2_create(tree, mem_ctx, &create);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");
	*h_out = create.out.file.handle;

	ZERO_STRUCT(create);
	create.in.desired_access = SEC_RIGHTS_FILE_ALL;
	create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
	create.in.create_disposition = NTCREATEX_DISP_CREATE;

	strs = generate_unique_strs(mem_ctx, 8, nfiles);
	if (strs == NULL) {
		status = NT_STATUS_OBJECT_NAME_COLLISION;
		goto done;
	}
	for (i = 0; i < nfiles; i++) {
		files[i].name = strs[i];
		create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
		    DNAME, files[i].name);
		status = smb2_create(tree, mem_ctx, &create);
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");
		smb2_util_close(tree, create.out.file.handle);
	}
 done:
	return status;
}
Exemplo n.º 3
0
/**
 * Create and initialize libnet_context Context.
 * Use this function in cases where we need to have SAMR and LSA pipes
 * of libnet_context to be connected before executing any other
 * libnet call
 *
 * @param rpc_connect [in] Connects SAMR and LSA pipes
 */
bool test_libnet_context_init(struct torture_context *tctx,
			      bool rpc_connect,
			      struct libnet_context **_net_ctx)
{
	NTSTATUS status;
	bool bret = true;
	struct libnet_context *net_ctx;

	net_ctx = libnet_context_init(tctx->ev, tctx->lp_ctx);
	torture_assert(tctx, net_ctx != NULL, "Failed to create libnet_context");

	/* Use command line credentials for testing */
	net_ctx->cred = cmdline_credentials;

	if (rpc_connect) {
		/* connect SAMR pipe */
		status = torture_rpc_connection(tctx,
						&net_ctx->samr.pipe,
						&ndr_table_samr);
		torture_assert_ntstatus_ok_goto(tctx, status, bret, done,
						"Failed to connect SAMR pipe");

		net_ctx->samr.samr_handle = net_ctx->samr.pipe->binding_handle;

		/* connect LSARPC pipe */
		status = torture_rpc_connection(tctx,
						&net_ctx->lsa.pipe,
						&ndr_table_lsarpc);
		torture_assert_ntstatus_ok_goto(tctx, status, bret, done,
						"Failed to connect LSA pipe");

		net_ctx->lsa.lsa_handle = net_ctx->lsa.pipe->binding_handle;
	}

	*_net_ctx = net_ctx;

done:
	if (!bret) {
		/* a previous call has failed,
		 * clean up memory before exit */
		talloc_free(net_ctx);
	}
	return bret;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/**
 * test setting security descriptor after reauth.
 */
bool test_session_reauth4(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;
    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 *sd1;
    struct security_ace ace;
    struct dom_sid *extra_sid;

    /* Add some random component to the file name. */
    snprintf(fname, sizeof(fname), "session_reauth4_%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");

    /* 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");

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

    /* 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_STD_ALL | SEC_FILE_ALL;
    ace.trustee = *extra_sid;

    status = security_descriptor_dacl_add(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_DACL;
    sfinfo.set_secdesc.in.sd = sd1;

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

    /* 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");

    /* 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");

    ret = true;

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

    smb2_util_unlink(tree, fname);

    talloc_free(tree);

    talloc_free(mem_ctx);

    return ret;
}
Exemplo n.º 8
0
/**
 * test getting security descriptor after reauth
 */
bool test_session_reauth3(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;
    union smb_fileinfo qfinfo;
    struct cli_credentials *anon_creds = NULL;
    uint32_t secinfo_flags = SECINFO_OWNER
                             | SECINFO_GROUP
                             | SECINFO_DACL
                             | SECINFO_PROTECTED_DACL
                             | SECINFO_UNPROTECTED_DACL;

    /* Add some random component to the file name. */
    snprintf(fname, sizeof(fname), "session_reauth3_%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");

    /* 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 */

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

    /* 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");

    /* 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 (h1 != NULL) {
        smb2_util_close(tree, *h1);
    }

    smb2_util_unlink(tree, fname);

    talloc_free(tree);

    talloc_free(mem_ctx);

    return ret;
}
Exemplo n.º 9
0
bool test_session_reauth1(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;
    union smb_fileinfo qfinfo;

    /* 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"));

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

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

    /* 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_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

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

    /* 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_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

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

    smb2_util_unlink(tree, fname);

    talloc_free(tree);

    talloc_free(mem_ctx);

    return ret;
}
Exemplo n.º 10
0
bool torture_net_become_dc(struct torture_context *torture)
{
	bool ret = true;
	NTSTATUS status;
	struct libnet_BecomeDC b;
	struct libnet_UnbecomeDC u;
	struct libnet_vampire_cb_state *s;
	struct ldb_message *msg;
	int ldb_ret;
	uint32_t i;
	char *private_dir;
	const char *address;
	struct nbt_name name;
	const char *netbios_name;
	struct cli_credentials *machine_account;
	struct test_join *tj;
	struct loadparm_context *lp_ctx;
	struct ldb_context *ldb;
	struct libnet_context *ctx;
	struct dsdb_schema *schema;

	char *location = NULL;
	torture_assert_ntstatus_ok(torture, torture_temp_dir(torture, "libnet_BecomeDC", &location), 
				   "torture_temp_dir should return NT_STATUS_OK" );

	netbios_name = lpcfg_parm_string(torture->lp_ctx, NULL, "become dc", "smbtorture dc");
	if (!netbios_name || !netbios_name[0]) {
		netbios_name = "smbtorturedc";
	}

	make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));

	/* do an initial name resolution to find its IP */
	status = resolve_name_ex(lpcfg_resolve_context(torture->lp_ctx),
				 0, 0,
				 &name, torture, &address, torture->ev);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "Failed to resolve %s - %s\n",
				   name.name, nt_errstr(status)));


	/* Join domain as a member server. */
	tj = torture_join_domain(torture, netbios_name,
				 ACB_WSTRUST,
				 &machine_account);
	torture_assert(torture, tj, talloc_asprintf(torture,
						    "%s failed to join domain as workstation\n",
						    netbios_name));

	s = libnet_vampire_cb_state_init(torture, torture->lp_ctx, torture->ev,
			       netbios_name,
			       torture_join_dom_netbios_name(tj),
			       torture_join_dom_dns_name(tj),
			       location);
	torture_assert(torture, s, "libnet_vampire_cb_state_init");

	ctx = libnet_context_init(torture->ev, torture->lp_ctx);
	ctx->cred = cmdline_credentials;

	ZERO_STRUCT(b);
	b.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	b.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	b.in.domain_sid			= torture_join_sid(tj);
	b.in.source_dsa_address		= address;
	b.in.dest_dsa_netbios_name	= netbios_name;

	b.in.callbacks.private_data	= s;
	b.in.callbacks.check_options	= libnet_vampire_cb_check_options;
	b.in.callbacks.prepare_db       = libnet_vampire_cb_prepare_db;
	b.in.callbacks.schema_chunk	= libnet_vampire_cb_schema_chunk;
	b.in.callbacks.config_chunk	= libnet_vampire_cb_store_chunk;
	b.in.callbacks.domain_chunk	= libnet_vampire_cb_store_chunk;

	status = libnet_BecomeDC(ctx, s, &b);
	torture_assert_ntstatus_ok_goto(torture, status, ret, cleanup, talloc_asprintf(torture,
				   "libnet_BecomeDC() failed - %s %s\n",
				   nt_errstr(status), b.out.error_string));
	ldb = libnet_vampire_cb_ldb(s);

	msg = ldb_msg_new(s);
	torture_assert_int_equal_goto(torture, (msg?1:0), 1, ret, cleanup,
				      "ldb_msg_new() failed\n");
	msg->dn = ldb_dn_new(msg, ldb, "@ROOTDSE");
	torture_assert_int_equal_goto(torture, (msg->dn?1:0), 1, ret, cleanup,
				      "ldb_msg_new(@ROOTDSE) failed\n");

	ldb_ret = ldb_msg_add_string(msg, "isSynchronized", "TRUE");
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_msg_add_string(msg, isSynchronized, TRUE) failed\n");

	for (i=0; i < msg->num_elements; i++) {
		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
	}

	torture_comment(torture, "mark ROOTDSE with isSynchronized=TRUE\n");
	ldb_ret = ldb_modify(libnet_vampire_cb_ldb(s), msg);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_modify() failed\n");
	
	/* commit the transaction now we know the secrets were written
	 * out properly
	*/
	ldb_ret = ldb_transaction_commit(ldb);
	torture_assert_int_equal_goto(torture, ldb_ret, LDB_SUCCESS, ret, cleanup,
				      "ldb_transaction_commit() failed\n");

	/* reopen the ldb */
	talloc_unlink(s, ldb);

	lp_ctx = libnet_vampire_cb_lp_ctx(s);
	private_dir = talloc_asprintf(s, "%s/%s", location, "private");
	lpcfg_set_cmdline(lp_ctx, "private dir", private_dir);
	torture_comment(torture, "Reopen the SAM LDB with system credentials and all replicated data: %s\n", private_dir);
	ldb = samdb_connect(s, torture->ev, lp_ctx, system_session(lp_ctx), 0);
	torture_assert_goto(torture, ldb != NULL, ret, cleanup,
				      talloc_asprintf(torture,
				      "Failed to open '%s/sam.ldb'\n", private_dir));

	torture_assert_goto(torture, dsdb_uses_global_schema(ldb), ret, cleanup,
						"Uses global schema");

	schema = dsdb_get_schema(ldb, s);
	torture_assert_goto(torture, schema != NULL, ret, cleanup,
				      "Failed to get loaded dsdb_schema\n");

	/* Make sure we get this from the command line */
	if (lpcfg_parm_bool(torture->lp_ctx, NULL, "become dc", "do not unjoin", false)) {
		talloc_free(s);
		return ret;
	}

cleanup:
	ZERO_STRUCT(u);
	u.in.domain_dns_name		= torture_join_dom_dns_name(tj);
	u.in.domain_netbios_name	= torture_join_dom_netbios_name(tj);
	u.in.source_dsa_address		= address;
	u.in.dest_dsa_netbios_name	= netbios_name;

	status = libnet_UnbecomeDC(ctx, s, &u);
	torture_assert_ntstatus_ok(torture, status, talloc_asprintf(torture,
				   "libnet_UnbecomeDC() failed - %s %s\n",
				   nt_errstr(status), u.out.error_string));

	/* Leave domain. */
	torture_leave_domain(torture, tj);

	talloc_free(s);
	return ret;
}
Exemplo n.º 11
0
/*
   basic testing of all File Information Classes using a single file
*/
static bool test_one_file(struct torture_context *tctx,
			  struct smb2_tree *tree)
{
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	bool ret = true;
	const char *fname =  "torture_search.txt";
	NTSTATUS status;
	int i;
	unsigned int count;
	union smb_fileinfo all_info2, alt_info, internal_info;
	union smb_search_data *s;
	union smb_search_data d;
	struct smb2_handle h, h2;

	status = torture_smb2_testdir(tree, DNAME, &h);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

	status = smb2_create_complex_file(tree, DNAME "\\torture_search.txt",
					  &h2);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

	/* call all the File Information Classes */
	for (i=0;i<ARRAY_SIZE(levels);i++) {
		torture_comment(tctx, "testing %s %d\n", levels[i].name,
				levels[i].level);

		levels[i].status = torture_single_file_search(tree, mem_ctx,
				   fname, levels[i].level, levels[i].data_level,
				   i, &d, &count, &h);
		torture_assert_ntstatus_ok_goto(tctx, levels[i].status, ret,
						done, "");
	}

	/* get the all_info file into to check against */
	all_info2.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
	all_info2.generic.in.file.handle = h2;
	status = smb2_getinfo_file(tree, tctx, &all_info2);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"RAW_FILEINFO_ALL_INFO failed");

	alt_info.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
	alt_info.generic.in.file.handle = h2;
	status = smb2_getinfo_file(tree, tctx, &alt_info);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"RAW_FILEINFO_ALT_NAME_INFO failed");

	internal_info.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;
	internal_info.generic.in.file.handle = h2;
	status = smb2_getinfo_file(tree, tctx, &internal_info);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
					"RAW_FILEINFO_INTERNAL_INFORMATION "
				        "failed");

#define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \
	s = find(name); \
	if (s) { \
		if ((s->sname1.field1) != (v.sname2.out.field2)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%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))) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%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) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%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)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%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)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%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)) { \
			torture_result(tctx, TORTURE_FAIL, \
			    "(%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)) { \
			torture_result(tctx, TORTURE_FAIL, \
			   "(%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("SMB2_FIND_DIRECTORY_INFO",            directory_info,         attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, attrib, all_info2, all_info2, attrib);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, attrib, all_info2, all_info2, attrib);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, write_time, all_info2, all_info2, write_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, write_time, all_info2, all_info2, write_time);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, create_time, all_info2, all_info2, create_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, create_time, all_info2, all_info2, create_time);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, access_time, all_info2, all_info2, access_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, access_time, all_info2, all_info2, access_time);

	CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO",         directory_info,         change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO",    full_directory_info,    change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO",    both_directory_info,    change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, change_time, all_info2, all_info2, change_time);
	CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, change_time, all_info2, all_info2, change_time);

	CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, size, all_info2, all_info2, size);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, size, all_info2, all_info2, size);

	CHECK_VAL("SMB2_FIND_DIRECTORY_INFO",            directory_info,         alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, alloc_size, all_info2, all_info2, alloc_size);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, alloc_size, all_info2, all_info2, alloc_size);

	CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO",       full_directory_info,    ea_size, all_info2, all_info2, ea_size);
	CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO",       both_directory_info,    ea_size, all_info2, all_info2, ea_size);
	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, ea_size, all_info2, all_info2, ea_size);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, ea_size, all_info2, all_info2, ea_size);

	CHECK_NAME("SMB2_FIND_DIRECTORY_INFO",           directory_info,         name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_FULL_DIRECTORY_INFO",      full_directory_info,    name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_NAME_INFO",                name_info,              name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_BOTH_DIRECTORY_INFO",      both_directory_info,    name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_ID_FULL_DIRECTORY_INFO",   id_full_directory_info, name, fname, STR_TERMINATE_ASCII);
	CHECK_NAME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",   id_both_directory_info, name, fname, STR_TERMINATE_ASCII);

	CHECK_WSTR("SMB2_FIND_BOTH_DIRECTORY_INFO",      both_directory_info,    short_name, alt_info, alt_name_info, fname, STR_UNICODE);

	CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO",    id_full_directory_info, file_id, internal_info, internal_information, file_id);
	CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO",    id_both_directory_info, file_id, internal_info, internal_information, file_id);

done:
	smb2_util_close(tree, h);
	smb2_util_unlink(tree, fname);
	talloc_free(mem_ctx);

	return ret;
}
Exemplo n.º 12
0
static bool test_fixed(struct torture_context *tctx,
		       struct smb2_tree *tree)
{
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	struct smb2_create create;
	struct smb2_handle h, h2;
	struct smb2_find f;
	union smb_search_data *d;
	struct file_elem files[NFILES] = {};
	NTSTATUS status;
	bool ret = true;
	unsigned int count;
	int i;

	status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);

	ZERO_STRUCT(create);
	create.in.desired_access = SEC_RIGHTS_DIR_ALL;
	create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
	create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
				 NTCREATEX_SHARE_ACCESS_WRITE |
				 NTCREATEX_SHARE_ACCESS_DELETE;
	create.in.create_disposition = NTCREATEX_DISP_OPEN;
	create.in.fname = DNAME;

	status = smb2_create(tree, mem_ctx, &create);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");
	h2 = create.out.file.handle;

	ZERO_STRUCT(f);
	f.in.file.handle	= h;
	f.in.pattern		= "*";
	f.in.continue_flags	= SMB2_CONTINUE_FLAG_SINGLE;
	f.in.max_response_size	= 0x100;
	f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;

	/* Start enumeration on h, then delete all from h2 */
	status = smb2_find_level(tree, tree, &f, &count, &d);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

	f.in.file.handle	= h2;

	do {
		status = smb2_find_level(tree, tree, &f, &count, &d);
		if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
			break;
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

		for (i = 0; i < count; i++) {
			const char *found = d[i].both_directory_info.name.s;
			char *path = talloc_asprintf(mem_ctx, "%s\\%s",
			    DNAME, found);

			if (!strcmp(found, ".") || !strcmp(found, ".."))
				continue;

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

			talloc_free(path);
		}

		f.in.continue_flags = 0;
		f.in.max_response_size	= 4096;
	} while (count != 0);

	/* Now finish h enumeration. */
	f.in.file.handle = h;

	do {
		status = smb2_find_level(tree, tree, &f, &count, &d);
		if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
			break;
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

		for (i = 0; i < count; i++) {
			const char *found = d[i].both_directory_info.name.s;

			if (!strcmp(found, ".") || !strcmp(found, ".."))
				continue;

			torture_result(tctx, TORTURE_FAIL,
			    "(%s): didn't expect %s\n",
			    __location__, found);
			ret = false;
			goto done;
		}

		f.in.continue_flags = 0;
		f.in.max_response_size	= 4096;
	} while (count != 0);

 done:
	smb2_util_close(tree, h);
	smb2_util_close(tree, h2);
	smb2_deltree(tree, DNAME);
	talloc_free(mem_ctx);

	return ret;
}
Exemplo n.º 13
0
static bool test_find(struct torture_context *tctx,
		      struct smb2_tree *tree)
{
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	struct smb2_handle h;
	struct smb2_find f;
	union smb_search_data *d;
	struct file_elem files[NFILES] = {};
	NTSTATUS status;
	bool ret = true;
	unsigned int count;
	int i, j, file_count = 0;

	status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);

	ZERO_STRUCT(f);
	f.in.file.handle	= h;
	f.in.pattern		= "*";
	f.in.continue_flags	= SMB2_CONTINUE_FLAG_SINGLE;
	f.in.max_response_size	= 0x100;
	f.in.level              = SMB2_FIND_BOTH_DIRECTORY_INFO;

	do {
		status = smb2_find_level(tree, tree, &f, &count, &d);
		if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
			break;
		torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "");

		for (i = 0; i < count; i++) {
			bool expected;
			const char *found = d[i].both_directory_info.name.s;

			if (!strcmp(found, ".") || !strcmp(found, ".."))
				continue;

			expected = false;
			for (j = 0; j < NFILES; j++) {
				if (!strcmp(files[j].name, found)) {
					files[j].found = true;
					expected = true;
					break;
				}
			}

			if (expected)
				continue;

			torture_result(tctx, TORTURE_FAIL,
			    "(%s): didn't expect %s\n",
			    __location__, found);
			ret = false;
			goto done;
		}

		file_count = file_count + i;
		f.in.continue_flags = 0;
		f.in.max_response_size	= 4096;
	} while (count != 0);

	torture_assert_int_equal_goto(tctx, file_count, NFILES + 2, ret, done,
				      "");

	for (i = 0; i < NFILES; i++) {
		if (files[j].found)
			continue;

		torture_result(tctx, TORTURE_FAIL,
		    "(%s): expected to find %s, but didn't\n",
		    __location__, files[j].name);
		ret = false;
		goto done;
	}

 done:
	smb2_deltree(tree, DNAME);
	talloc_free(mem_ctx);

	return ret;
}
Exemplo n.º 14
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, 256, "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);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h1 = io1.out.file.handle;
	h1 = &_h1;
	CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));

	/* 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);
		CHECK_STATUS(status, NT_STATUS_OK);

		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);
		CHECK_STATUS(status, NT_STATUS_NETWORK_SESSION_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 => OK\n");
		status = smb2_session_setup_spnego(tree->session,
						   credentials,
						   0 /* previous_session_id */);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	ZERO_STRUCT(qfinfo.access_information.out);
	status = smb2_getinfo_file(tree, tctx, &qfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	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;
}
Exemplo n.º 15
0
bool test_session_bind1(struct torture_context *tctx, struct smb2_tree *tree1)
{
    const char *host = torture_setting_string(tctx, "host", NULL);
    const char *share = torture_setting_string(tctx, "share", NULL);
    struct cli_credentials *credentials = cmdline_credentials;
    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;
    union smb_fileinfo qfinfo;
    bool ret = false;
    struct smb2_tree *tree2 = NULL;
    struct smb2_transport *transport1 = tree1->session->transport;
    struct smb2_transport *transport2 = NULL;
    struct smb2_session *session1_1 = tree1->session;
    struct smb2_session *session1_2 = NULL;
    struct smb2_session *session2_1 = NULL;
    struct smb2_session *session2_2 = NULL;
    uint32_t caps;

    caps = smb2cli_conn_server_capabilities(transport1->conn);
    if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
        torture_skip(tctx, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
    }

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

    smb2_util_unlink(tree1, fname);

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

    status = smb2_create(tree1, 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");

    status = smb2_connect(tctx,
                          host,
                          lpcfg_smb_ports(tctx->lp_ctx),
                          share,
                          lpcfg_resolve_context(tctx->lp_ctx),
                          credentials,
                          &tree2,
                          tctx->ev,
                          &transport1->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");
    session2_2 = tree2->session;
    transport2 = tree2->session->transport;

    /*
     * Now bind the 2nd transport connection to the 1st session
     */
    session1_2 = smb2_session_channel(transport2,
                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx),
                                      tree2,
                                      session1_1);
    torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");

    status = smb2_session_setup_spnego(session1_2,
                                       cmdline_credentials,
                                       0 /* previous_session_id */);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_session_setup_spnego failed");

    /* use the 1st connection, 1st session */
    ZERO_STRUCT(qfinfo);
    qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
    qfinfo.generic.in.file.handle = _h1;
    tree1->session = session1_1;
    status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

    /* use the 2nd connection, 1st session */
    ZERO_STRUCT(qfinfo);
    qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
    qfinfo.generic.in.file.handle = _h1;
    tree1->session = session1_2;
    status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_getinfo_file failed");

    tree1->session = session1_1;
    status = smb2_util_close(tree1, *h1);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_util_close failed");
    h1 = NULL;

    /*
     * Now bind the 1st transport connection to the 2nd session
     */
    session2_1 = smb2_session_channel(transport1,
                                      lpcfg_gensec_settings(tctx, tctx->lp_ctx),
                                      tree1,
                                      session2_2);
    torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed");

    status = smb2_session_setup_spnego(session2_1,
                                       cmdline_credentials,
                                       0 /* previous_session_id */);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_session_setup_spnego failed");

    tree2->session = session2_1;
    status = smb2_util_unlink(tree2, fname);
    torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
                                    "smb2_util_unlink failed");
    ret = true;
done:
    talloc_free(tree2);
    tree1->session = session1_1;

    if (h1 != NULL) {
        smb2_util_close(tree1, *h1);
    }

    smb2_util_unlink(tree1, fname);

    talloc_free(tree1);

    talloc_free(mem_ctx);

    return ret;
}
Exemplo n.º 16
0
static bool test_default_acl_posix(struct torture_context *tctx,
				   struct smb2_tree *tree_unused)
{
	struct smb2_tree *tree = NULL;
	NTSTATUS status;
	bool ok;
	bool ret = true;
	const char *dname = BASEDIR "\\testdir";
	const char *fname = BASEDIR "\\testdir\\testfile";
	struct smb2_handle fhandle = {{0}};
	struct smb2_handle dhandle = {{0}};
	union smb_fileinfo q;
	union smb_setfileinfo set;
	struct security_descriptor *sd = NULL;
	struct security_descriptor *exp_sd = NULL;
	char *owner_sid = NULL;
	char *group_sid = NULL;

	ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_posix", &tree);
	torture_assert_goto(tctx, ok == true, ret, done,
			    "Unable to connect to 'acl_xattr_ign_sysacl_posix'\n");

	ok = smb2_util_setup_dir(tctx, tree, BASEDIR);
	torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n");

	ZERO_STRUCT(dhandle);
	status = torture_smb2_testdir(tree, dname, &dhandle);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n");

	torture_comment(tctx, "Get the original sd\n");

	ZERO_STRUCT(q);
	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	q.query_secdesc.in.file.handle = dhandle;
	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
	status = smb2_getinfo_file(tree, tctx, &q);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");

	sd = q.query_secdesc.out.sd;
	owner_sid = dom_sid_string(tctx, sd->owner_sid);
	group_sid = dom_sid_string(tctx, sd->group_sid);
	torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid);

	torture_comment(tctx, "Set ACL with no inheritable ACE\n");

	sd = security_descriptor_dacl_create(tctx,
					     0, NULL, NULL,
					     owner_sid,
					     SEC_ACE_TYPE_ACCESS_ALLOWED,
					     SEC_RIGHTS_DIR_ALL,
					     0,
					     NULL);

	ZERO_STRUCT(set);
	set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
	set.set_secdesc.in.file.handle = dhandle;
	set.set_secdesc.in.secinfo_flags = SECINFO_DACL;
	set.set_secdesc.in.sd = sd;
	status = smb2_setinfo_file(tree, &set);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n");

	TALLOC_FREE(sd);
	smb2_util_close(tree, dhandle);

	torture_comment(tctx, "Create file\n");

	ZERO_STRUCT(fhandle);
	status = torture_smb2_testfile(tree, fname, &fhandle);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n");

	torture_comment(tctx, "Query file SD\n");

	ZERO_STRUCT(q);
	q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	q.query_secdesc.in.file.handle = fhandle;
	q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP;
	status = smb2_getinfo_file(tree, tctx, &q);
	torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n");
	sd = q.query_secdesc.out.sd;

	smb2_util_close(tree, fhandle);
	ZERO_STRUCT(fhandle);

	torture_comment(tctx, "Checking actual file SD against expected SD\n");

	exp_sd = security_descriptor_dacl_create(
		tctx, 0, owner_sid, group_sid,
		owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
		group_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
		SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0,
		SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0,
		NULL);

	CHECK_SECURITY_DESCRIPTOR(sd, exp_sd);

done:
	if (!smb2_util_handle_empty(fhandle)) {
		smb2_util_close(tree, fhandle);
	}
	if (!smb2_util_handle_empty(dhandle)) {
		smb2_util_close(tree, dhandle);
	}
	if (tree != NULL) {
		smb2_deltree(tree, BASEDIR);
		smb2_tdis(tree);
	}

	return ret;
}
Exemplo n.º 17
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;
}