From 6550bc0d26278ce96a2a752231efef274c0dcf12 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 31 Aug 2012 12:42:16 -0700 Subject: [PATCH] Rewrite torture_samba3_rpc_sharesec() to use a non-privileged user for share security descriptor testing. --- source4/torture/rpc/samba3rpc.c | 123 ++++++++++++++++++++++++++++---- source4/torture/rpc/testjoin.c | 74 +++++++++++++++++++ 2 files changed, 182 insertions(+), 15 deletions(-) diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index e2c8b66182..f7968b1c56 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -2391,36 +2391,129 @@ bool try_tcon(struct torture_context *tctx, static bool torture_samba3_rpc_sharesec(struct torture_context *torture) { - struct smbcli_state *cli; - struct security_descriptor *sd; - struct dom_sid *user_sid; + struct smbcli_state *cli = NULL; + struct security_descriptor *sd = NULL; + struct dom_sid *user_sid = NULL; + const char *testuser_passwd = NULL; + struct cli_credentials *test_credentials = NULL; + struct smbcli_options options; + struct smbcli_session_options session_options; + NTSTATUS status; + struct test_join *tj = NULL; + struct dcerpc_pipe *lsa_pipe = NULL; + const char *priv_array[1]; + + /* Create a new user. The normal user has SeBackup and SeRestore + privs so we can't lock them out with a share security descriptor. */ + tj = torture_create_testuser(torture, + "sharesec_user", + torture_setting_string(torture, "workgroup", NULL), + ACB_NORMAL, + &testuser_passwd); + if (!tj) { + torture_fail(torture, "Creating sharesec_user failed\n"); + } + + /* Give them SeDiskOperatorPrivilege but no other privs. */ + status = torture_rpc_connection(torture, &lsa_pipe, &ndr_table_lsarpc); + if (!NT_STATUS_IS_OK(status)) { + torture_delete_testuser(torture, tj, "sharesec_user"); + talloc_free(tj); + torture_fail(torture, "Error connecting to LSA pipe"); + } + + priv_array[0] = "SeDiskOperatorPrivilege"; + if (!torture_setup_privs(torture, + lsa_pipe, + 1, + priv_array, + torture_join_user_sid(tj))) { + talloc_free(lsa_pipe); + torture_delete_testuser(torture, tj, "sharesec_user"); + talloc_free(tj); + torture_fail(torture, "Failed to setup privs\n"); + } + talloc_free(lsa_pipe); - if (!(torture_open_connection_share( - torture, &cli, torture, torture_setting_string(torture, "host", NULL), - "IPC$", torture->ev))) { - torture_fail(torture, "IPC$ connection failed\n"); + test_credentials = cli_credentials_init(torture); + cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED); + cli_credentials_set_domain(test_credentials, lpcfg_workgroup(torture->lp_ctx), + CRED_SPECIFIED); + cli_credentials_set_username(test_credentials, "sharesec_user", CRED_SPECIFIED); + cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED); + + ZERO_STRUCT(options); + ZERO_STRUCT(session_options); + lpcfg_smbcli_options(torture->lp_ctx, &options); + lpcfg_smbcli_session_options(torture->lp_ctx, &session_options); + + status = smbcli_full_connection(torture, + &cli, + torture_setting_string(torture, "host", NULL), + lpcfg_smb_ports(torture->lp_ctx), + "IPC$", + NULL, + lpcfg_socket_options(torture->lp_ctx), + test_credentials, + lpcfg_resolve_context(torture->lp_ctx), + torture->ev, + &options, + &session_options, + lpcfg_gensec_settings(torture, torture->lp_ctx)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(cli); + torture_delete_testuser(torture, tj, "sharesec_user"); + talloc_free(tj); + torture_fail(torture, "Failed to open connection\n"); } if (!(user_sid = whoami(torture, torture, cli->tree))) { + talloc_free(cli); + torture_delete_testuser(torture, tj, "sharesec_user"); + talloc_free(tj); torture_fail(torture, "whoami failed\n"); } sd = get_sharesec(torture, torture, cli->session, torture_setting_string(torture, "share", NULL)); - torture_assert(torture, try_tcon( - torture, torture, sd, cli->session, + if (!try_tcon(torture, torture, sd, cli->session, torture_setting_string(torture, "share", NULL), - user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK), - "failed to test tcon with 0 access_mask"); + user_sid, 0, NT_STATUS_ACCESS_DENIED, NT_STATUS_OK)) { + talloc_free(cli); + torture_delete_testuser(torture, tj, "sharesec_user"); + talloc_free(tj); + torture_fail(torture, "failed to test tcon with 0 access_mask"); + } - torture_assert(torture, try_tcon( - torture, torture, sd, cli->session, + if (!try_tcon(torture, torture, sd, cli->session, torture_setting_string(torture, "share", NULL), user_sid, SEC_FILE_READ_DATA, NT_STATUS_OK, - NT_STATUS_MEDIA_WRITE_PROTECTED), - "failed to test tcon with SEC_FILE_READ_DATA access_mask"); + NT_STATUS_MEDIA_WRITE_PROTECTED)) { + talloc_free(cli); + torture_delete_testuser(torture, tj, "sharesec_user"); + talloc_free(tj); + torture_fail(torture, "failed to test tcon with SEC_FILE_READ_DATA access_mask"); + } + + /* sharesec_user doesn't have any rights on the underlying file system. + Go back to the normal user. */ + + talloc_free(cli); + cli = NULL; + torture_delete_testuser(torture, tj, "sharesec_user"); + talloc_free(tj); + tj = NULL; + + if (!(torture_open_connection_share( + torture, &cli, torture, torture_setting_string(torture, "host", NULL), + "IPC$", torture->ev))) { + torture_fail(torture, "IPC$ connection failed\n"); + } + if (!(user_sid = whoami(torture, torture, cli->tree))) { + torture_fail(torture, "whoami failed\n"); + } torture_assert(torture, try_tcon( torture, torture, sd, cli->session, torture_setting_string(torture, "share", NULL), diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index eb49b8e3ab..e54650885b 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -29,6 +29,7 @@ #include "../lib/crypto/crypto.h" #include "libnet/libnet.h" #include "lib/cmdline/popt_common.h" +#include "librpc/gen_ndr/ndr_lsa_c.h" #include "librpc/gen_ndr/ndr_samr_c.h" #include "libcli/auth/libcli_auth.h" @@ -394,6 +395,79 @@ failed: return NULL; } +/* + * Set privileges on an account. + */ + +static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s) +{ + name->string = s; +} +static void init_lsa_String(struct lsa_String *name, const char *s) +{ + name->string = s; +} + +bool torture_setup_privs(struct torture_context *tctx, + struct dcerpc_pipe *p, + uint32_t num_privs, + const char **privs, + const struct dom_sid *user_sid) +{ + struct dcerpc_binding_handle *b = p->binding_handle; + struct policy_handle *handle; + int i; + + torture_assert(tctx, + test_lsa_OpenPolicy2(b, tctx, &handle), + "failed to open policy"); + + for (i=0; i < num_privs; i++) { + struct lsa_LookupPrivValue r; + struct lsa_LUID luid; + struct lsa_String name; + + init_lsa_String(&name, privs[i]); + + r.in.handle = handle; + r.in.name = &name; + r.out.luid = &luid; + + torture_assert_ntstatus_ok(tctx, + dcerpc_lsa_LookupPrivValue_r(b, tctx, &r), + "lsa_LookupPrivValue failed"); + if (!NT_STATUS_IS_OK(r.out.result)) { + torture_comment(tctx, "lsa_LookupPrivValue failed for '%s' with %s\n", + privs[i], nt_errstr(r.out.result)); + return false; + } + } + + { + struct lsa_AddAccountRights r; + struct lsa_RightSet rights; + + rights.count = num_privs; + rights.names = talloc_zero_array(tctx, struct lsa_StringLarge, rights.count); + for (i=0; i < rights.count; i++) { + init_lsa_StringLarge(&rights.names[i], privs[i]); + } + + r.in.handle = handle; + r.in.sid = discard_const_p(struct dom_sid, user_sid); + r.in.rights = &rights; + + torture_assert_ntstatus_ok(tctx, + dcerpc_lsa_AddAccountRights_r(b, tctx, &r), + "lsa_AddAccountRights failed"); + torture_assert_ntstatus_ok(tctx, r.out.result, + "lsa_AddAccountRights failed"); + } + + test_lsa_Close(b, tctx, handle); + + return true; +} struct test_join *torture_create_testuser(struct torture_context *torture, const char *username, -- 2.34.1