Rewrite torture_samba3_rpc_sharesec() to use a non-privileged user for share security...
authorJeremy Allison <jra@samba.org>
Fri, 31 Aug 2012 19:42:16 +0000 (12:42 -0700)
committerJeremy Allison <jra@samba.org>
Sat, 1 Sep 2012 03:29:13 +0000 (20:29 -0700)
source4/torture/rpc/samba3rpc.c
source4/torture/rpc/testjoin.c

index e2c8b66182fb553917eab903a1946e9d7bcef2a5..f7968b1c56e663081a36256c937c2d1b1b56c769 100644 (file)
@@ -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),
index eb49b8e3abfdd5b569362c005d750d5f163cbce5..e54650885b829a9f5859ebba9237b141d4a84adf 100644 (file)
@@ -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,