The branch, master has been updated
       via  e89502e... s4-smbtorture: add RPC-SPOOLSS-ACCESS.
       via  29c0c10... s4-smbtorture: share test_ClosePrinter between 
RPC-SPOOLSS and RPC-SPOOLSS-WIN.
       via  b3ebebd... s3-rpcclient: allow to add access_mask in 
cmd_spoolss_open_printer_ex().
       via  8b3059d... s4-smbtorture: check error codes in RAP-SAM testsuite.
      from  fb79a8d... Oops. Forgot to re-initialize the aio_ex pointer from 
sival_ptr.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e89502e0f5a79c960cbecf50f49af3aa4bba8e35
Author: Günther Deschner <g...@samba.org>
Date:   Fri Jun 4 19:03:11 2010 +0200

    s4-smbtorture: add RPC-SPOOLSS-ACCESS.
    
    This test creates
    
    - a user
    - a user with BUILTIN\Administrators membership
    - a user with BUILTIN\Print Operators membership
    - a user with SePrintOperatorPrivilege (if available)
    - a user with full access in security descriptor
    
    and checks what access rights are granted in spoolss_OpenPrinterEx.
    
    Guenther

commit 29c0c103afed7238698cc83ff3ab017fc1510dcd
Author: Günther Deschner <g...@samba.org>
Date:   Fri Jun 4 19:02:17 2010 +0200

    s4-smbtorture: share test_ClosePrinter between RPC-SPOOLSS and 
RPC-SPOOLSS-WIN.
    
    Guenther

commit b3ebebd3b18e4d9ebfc50012e02f7011f8d067be
Author: Günther Deschner <g...@samba.org>
Date:   Fri Jun 4 16:55:07 2010 +0200

    s3-rpcclient: allow to add access_mask in cmd_spoolss_open_printer_ex().
    
    Guenther

commit 8b3059de977eeeae69ebff7d33119bd6b565b637
Author: Günther Deschner <g...@samba.org>
Date:   Fri Jun 4 19:05:24 2010 +0200

    s4-smbtorture: check error codes in RAP-SAM testsuite.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source3/rpcclient/cmd_spoolss.c      |   12 +-
 source4/torture/config.mk            |    2 +-
 source4/torture/rap/sam.c            |    2 +
 source4/torture/rpc/rpc.c            |    1 +
 source4/torture/rpc/spoolss.c        |   10 +-
 source4/torture/rpc/spoolss_access.c |  751 ++++++++++++++++++++++++++++++++++
 source4/torture/rpc/spoolss_win.c    |   19 -
 source4/torture/wscript_build        |    2 +-
 8 files changed, 766 insertions(+), 33 deletions(-)
 create mode 100644 source4/torture/rpc/spoolss_access.c


Changeset truncated at 500 lines:

diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index d5a7ce7..39c581c 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -105,20 +105,22 @@ static WERROR cmd_spoolss_open_printer_ex(struct 
rpc_pipe_client *cli,
 {
        WERROR          werror;
        struct policy_handle    hnd;
+       uint32_t access_mask = PRINTER_ALL_ACCESS;
 
-       if (argc != 2) {
-               printf("Usage: %s <printername>\n", argv[0]);
+       if (argc < 2) {
+               printf("Usage: %s <printername> [access_mask]\n", argv[0]);
                return WERR_OK;
        }
 
-       if (!cli)
-            return WERR_GENERAL_FAILURE;
+       if (argc >= 3) {
+               sscanf(argv[2], "%x", &access_mask);
+       }
 
        /* Open the printer handle */
 
        werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
                                               argv[1],
-                                              PRINTER_ALL_ACCESS,
+                                              access_mask,
                                               &hnd);
        if (W_ERROR_IS_OK(werror)) {
                printf("Printer %s opened successfully\n", argv[1]);
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index 4d65256..25e9b53 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -124,7 +124,7 @@ PRIVATE_DEPENDENCIES = \
 
 torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \
                join.o lsa.o lsa_lookup.o session_key.o echo.o dfs.o drsuapi.o \
-               drsuapi_cracknames.o dssync.o dsgetinfo.o spoolss.o 
spoolss_notify.o spoolss_win.o \
+               drsuapi_cracknames.o dssync.o dsgetinfo.o spoolss.o 
spoolss_notify.o spoolss_win.o spoolss_access.o \
                unixinfo.o samr.o samr_accessmask.o wkssvc.o srvsvc.o svcctl.o 
atsvc.o \
                eventlog.o epmapper.o winreg.o initshutdown.o oxidresolve.o 
remact.o mgmt.o \
                scanner.o autoidl.o countcalls.o testjoin.o schannel.o 
netlogon.o remote_pac.o samlogon.o \
diff --git a/source4/torture/rap/sam.c b/source4/torture/rap/sam.c
index 290ba08..144abaa 100644
--- a/source4/torture/rap/sam.c
+++ b/source4/torture/rap/sam.c
@@ -206,6 +206,8 @@ static bool test_usergetinfo_byname(struct torture_context 
*tctx,
                torture_assert_ntstatus_ok(tctx,
                        smbcli_rap_netusergetinfo(cli->tree, tctx, &r),
                        "smbcli_rap_netusergetinfo failed");
+               torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
+                       "smbcli_rap_netusergetinfo failed");
        }
 
        return true;
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 746698e..a860bda 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -445,6 +445,7 @@ NTSTATUS torture_rpc_init(void)
        torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite));
        torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite));
        torture_suite_add_suite(suite, torture_rpc_spoolss_driver(suite));
+       torture_suite_add_suite(suite, torture_rpc_spoolss_access(suite));
        torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr);
        torture_suite_add_simple_test(suite, "SAMR-USERS", 
torture_rpc_samr_users);
        torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", 
torture_rpc_samr_passwords);
diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index 7154b83..e61adfe 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -2185,10 +2185,6 @@ static bool call_OpenPrinterEx(struct torture_context 
*tctx,
                               struct spoolss_DeviceMode *devmode,
                               struct policy_handle *handle);
 
-static bool test_ClosePrinter(struct torture_context *tctx,
-                             struct dcerpc_binding_handle *b,
-                             struct policy_handle *handle);
-
 static bool test_PrinterInfo_DevModes(struct torture_context *tctx,
                                      struct dcerpc_pipe *p,
                                      struct policy_handle *handle,
@@ -2373,9 +2369,9 @@ static bool test_PrinterInfo_DevMode(struct 
torture_context *tctx,
        return ret;
 }
 
-static bool test_ClosePrinter(struct torture_context *tctx,
-                             struct dcerpc_binding_handle *b,
-                             struct policy_handle *handle)
+bool test_ClosePrinter(struct torture_context *tctx,
+                      struct dcerpc_binding_handle *b,
+                      struct policy_handle *handle)
 {
        NTSTATUS status;
        struct spoolss_ClosePrinter r;
diff --git a/source4/torture/rpc/spoolss_access.c 
b/source4/torture/rpc/spoolss_access.c
new file mode 100644
index 0000000..f86c2e3
--- /dev/null
+++ b/source4/torture/rpc/spoolss_access.c
@@ -0,0 +1,751 @@
+/*
+   Unix SMB/CIFS implementation.
+   test suite for spoolss rpc operations
+
+   Copyright (C) Guenther Deschner 2010
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "librpc/gen_ndr/ndr_spoolss.h"
+#include "librpc/gen_ndr/ndr_spoolss_c.h"
+#include "librpc/gen_ndr/ndr_samr_c.h"
+#include "librpc/gen_ndr/ndr_lsa_c.h"
+#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/security/security.h"
+#include "torture/rpc/torture_rpc.h"
+#include "param/param.h"
+#include "lib/cmdline/popt_common.h"
+
+#define TORTURE_USER                   "torture_user"
+#define TORTURE_USER_ADMINGROUP                "torture_user_544"
+#define TORTURE_USER_PRINTOPGROUP      "torture_user_550"
+#define TORTURE_USER_PRINTOPPRIV       "torture_user_priv"
+#define TORTURE_USER_SD                        "torture_user_sd"
+
+struct torture_user {
+       const char *username;
+       void *testuser;
+       uint32_t *builtin_memberships;
+       uint32_t num_builtin_memberships;
+       const char **privs;
+       uint32_t num_privs;
+       bool privs_present;
+       bool sd;
+};
+
+struct torture_access_context {
+       struct dcerpc_pipe *spoolss_pipe;
+       const char *printername;
+       struct security_descriptor *sd_orig;
+       struct torture_user user;
+};
+
+static bool test_openprinter_handle(struct torture_context *tctx,
+                                   struct dcerpc_pipe *p,
+                                   const char *printername,
+                                   const char *username,
+                                   uint32_t access_mask,
+                                   struct policy_handle *handle)
+{
+       struct spoolss_OpenPrinterEx r;
+       struct spoolss_UserLevel1 level1;
+       struct dcerpc_binding_handle *b = p->binding_handle;
+
+       level1.size     = 28;
+       level1.client   = talloc_asprintf(tctx, "\\\\%s", "smbtorture");
+       level1.user     = username;
+       level1.build    = 1381;
+       level1.major    = 3;
+       level1.minor    = 0;
+       level1.processor= 0;
+
+       r.in.printername        = printername;
+       r.in.datatype           = NULL;
+       r.in.devmode_ctr.devmode= NULL;
+       r.in.access_mask        = access_mask;
+       r.in.level              = 1;
+       r.in.userlevel.level1   = &level1;
+       r.out.handle            = handle;
+
+       torture_comment(tctx, "Testing OpenPrinterEx(%s) with access_mask 
0x%08x\n",
+               r.in.printername, r.in.access_mask);
+
+       torture_assert_ntstatus_ok(tctx,
+               dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r),
+               "OpenPrinterEx failed");
+       torture_assert_werr_ok(tctx, r.out.result,
+               talloc_asprintf(tctx, "OpenPrinterEx(%s) as '%s' with 
access_mask: 0x%08x failed",
+                       r.in.printername, username, r.in.access_mask));
+
+       return true;
+}
+
+static bool test_openprinter_access(struct torture_context *tctx,
+                                   struct dcerpc_pipe *p,
+                                   const char *printername,
+                                   const char *username,
+                                   uint32_t access_mask)
+{
+       struct policy_handle handle;
+       struct dcerpc_binding_handle *b = p->binding_handle;
+
+       if (test_openprinter_handle(tctx, p, printername, username, 
access_mask, &handle)) {
+               test_ClosePrinter(tctx, b, &handle);
+               return true;
+       }
+
+       return false;
+}
+
+static bool spoolss_access_setup_membership(struct torture_context *tctx,
+                                           struct dcerpc_pipe *p,
+                                           uint32_t num_members,
+                                           uint32_t *members,
+                                           struct dom_sid *user_sid)
+{
+       struct dcerpc_binding_handle *b = p->binding_handle;
+       struct policy_handle connect_handle, domain_handle;
+       int i;
+
+       {
+               struct samr_Connect2 r;
+               r.in.system_name = "";
+               r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+               r.out.connect_handle = &connect_handle;
+
+               torture_assert_ntstatus_ok(tctx,
+                       dcerpc_samr_Connect2_r(b, tctx, &r),
+                       "samr_Connect2 failed");
+               torture_assert_ntstatus_ok(tctx, r.out.result,
+                       "samr_Connect2 failed");
+       }
+
+       {
+               struct samr_OpenDomain r;
+               r.in.connect_handle = &connect_handle;
+               r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+               r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32");
+               r.out.domain_handle = &domain_handle;
+
+               torture_assert_ntstatus_ok(tctx,
+                       dcerpc_samr_OpenDomain_r(b, tctx, &r),
+                       "samr_OpenDomain failed");
+               torture_assert_ntstatus_ok(tctx, r.out.result,
+                       "samr_OpenDomain failed");
+       }
+
+       for (i=0; i < num_members; i++) {
+
+               struct policy_handle alias_handle;
+
+               {
+               struct samr_OpenAlias r;
+               r.in.domain_handle = &domain_handle;
+               r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+               r.in.rid = members[i];
+               r.out.alias_handle = &alias_handle;
+
+               torture_assert_ntstatus_ok(tctx,
+                       dcerpc_samr_OpenAlias_r(b, tctx, &r),
+                       "samr_OpenAlias failed");
+               torture_assert_ntstatus_ok(tctx, r.out.result,
+                       "samr_OpenAlias failed");
+               }
+
+               {
+               struct samr_AddAliasMember r;
+               r.in.alias_handle = &alias_handle;
+               r.in.sid = user_sid;
+
+               torture_assert_ntstatus_ok(tctx,
+                       dcerpc_samr_AddAliasMember_r(b, tctx, &r),
+                       "samr_AddAliasMember failed");
+               torture_assert_ntstatus_ok(tctx, r.out.result,
+                       "samr_AddAliasMember failed");
+               }
+
+               test_samr_handle_Close(b, tctx, &alias_handle);
+       }
+
+       test_samr_handle_Close(b, tctx, &domain_handle);
+       test_samr_handle_Close(b, tctx, &connect_handle);
+
+       return true;
+}
+
+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;
+}
+
+static bool spoolss_access_setup_privs(struct torture_context *tctx,
+                                      struct dcerpc_pipe *p,
+                                      uint32_t num_privs,
+                                      const char **privs,
+                                      struct dom_sid *user_sid,
+                                      bool *privs_present)
+{
+       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));
+                       *privs_present = false;
+                       return true;
+               }
+       }
+
+       *privs_present = true;
+
+       {
+               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 = 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;
+}
+
+static bool test_SetPrinter(struct torture_context *tctx,
+                           struct dcerpc_binding_handle *b,
+                           struct policy_handle *handle,
+                           struct spoolss_SetPrinterInfoCtr *info_ctr,
+                           struct spoolss_DevmodeContainer *devmode_ctr,
+                           struct sec_desc_buf *secdesc_ctr,
+                           enum spoolss_PrinterControl command)
+{
+       struct spoolss_SetPrinter r;
+
+       r.in.handle = handle;
+       r.in.info_ctr = info_ctr;
+       r.in.devmode_ctr = devmode_ctr;
+       r.in.secdesc_ctr = secdesc_ctr;
+       r.in.command = command;
+
+       torture_comment(tctx, "Testing SetPrinter level %d\n", 
r.in.info_ctr->level);
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter_r(b, tctx, 
&r),
+               "failed to call SetPrinter");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "failed to call SetPrinter");
+
+       return true;
+}
+
+static bool spoolss_access_setup_sd(struct torture_context *tctx,
+                                   struct dcerpc_pipe *p,
+                                   const char *printername,
+                                   struct dom_sid *user_sid,
+                                   struct security_descriptor **sd_orig)
+{
+       struct dcerpc_binding_handle *b = p->binding_handle;
+       struct policy_handle handle;
+       union spoolss_PrinterInfo info;
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       struct spoolss_SetPrinterInfo3 info3;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+       struct security_ace *ace;
+       struct security_descriptor *sd;
+
+       torture_assert(tctx,
+               test_openprinter_handle(tctx, p, printername, "", 
SEC_FLAG_MAXIMUM_ALLOWED, &handle),
+               "failed to open printer");
+
+       torture_assert(tctx,
+               test_GetPrinter_level(tctx, b, &handle, 3, &info),
+               "failed to get sd");
+
+       sd = security_descriptor_copy(tctx, info.info3.secdesc);
+       *sd_orig = security_descriptor_copy(tctx, info.info3.secdesc);
+
+       ace = talloc_zero(tctx, struct security_ace);
+
+       ace->type               = SEC_ACE_TYPE_ACCESS_ALLOWED;
+       ace->flags              = 0;
+       ace->access_mask        = PRINTER_ALL_ACCESS;
+       ace->trustee            = *user_sid;
+
+       torture_assert_ntstatus_ok(tctx,
+               security_descriptor_dacl_add(sd, ace),
+               "failed to add new ace");
+
+       ace = talloc_zero(tctx, struct security_ace);
+
+       ace->type               = SEC_ACE_TYPE_ACCESS_ALLOWED;
+       ace->flags              = SEC_ACE_FLAG_OBJECT_INHERIT |
+                                 SEC_ACE_FLAG_CONTAINER_INHERIT |
+                                 SEC_ACE_FLAG_INHERIT_ONLY;
+       ace->access_mask        = SEC_GENERIC_ALL;
+       ace->trustee            = *user_sid;
+
+       torture_assert_ntstatus_ok(tctx,
+               security_descriptor_dacl_add(sd, ace),
+               "failed to add new ace");
+
+       ZERO_STRUCT(info3);
+       ZERO_STRUCT(info_ctr);
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+
+       info_ctr.level = 3;
+       info_ctr.info.info3 = &info3;
+       secdesc_ctr.sd = sd;
+
+       torture_assert(tctx,
+               test_SetPrinter(tctx, b, &handle, &info_ctr, &devmode_ctr, 
&secdesc_ctr, 0),
+               "failed to set sd");
+
+       return true;
+}
+
+static bool test_EnumPrinters_findone(struct torture_context *tctx,
+                                     struct dcerpc_binding_handle *b,
+                                     const char **printername)
+{
+       struct spoolss_EnumPrinters r;
+       uint32_t count;
+       union spoolss_PrinterInfo *info;
+       uint32_t needed;
+       int i;
+
+       *printername = NULL;
+
+       r.in.flags = PRINTER_ENUM_LOCAL;
+       r.in.server = NULL;
+       r.in.level = 1;
+       r.in.buffer = NULL;
+       r.in.offered = 0;
+       r.out.count = &count;
+       r.out.info = &info;
+       r.out.needed = &needed;
+
+       torture_assert_ntstatus_ok(tctx,
+               dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
+               "failed to enum printers");
+
+       if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+               DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
+               r.in.buffer = &blob;
+               r.in.offered = needed;
+
+               torture_assert_ntstatus_ok(tctx,
+                       dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
+                       "failed to enum printers");
+       }
+
+       torture_assert_werr_ok(tctx, r.out.result,
+               "failed to enum printers");
+


-- 
Samba Shared Repository

Reply via email to