LCOV - code coverage report
Current view: top level - source4/torture/rpc - spoolss_access.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 22 370 5.9 %
Date: 2024-02-28 12:06:22 Functions: 1 20 5.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    test suite for spoolss rpc operations
       4             : 
       5             :    Copyright (C) Guenther Deschner 2010
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "torture/torture.h"
      23             : #include "librpc/gen_ndr/ndr_misc.h"
      24             : #include "librpc/gen_ndr/ndr_spoolss.h"
      25             : #include "librpc/gen_ndr/ndr_spoolss_c.h"
      26             : #include "librpc/gen_ndr/ndr_samr_c.h"
      27             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      28             : #include "librpc/gen_ndr/ndr_security.h"
      29             : #include "libcli/security/security.h"
      30             : #include "torture/rpc/torture_rpc.h"
      31             : #include "param/param.h"
      32             : #include "lib/cmdline/cmdline.h"
      33             : 
      34             : #define TORTURE_USER                    "torture_user"
      35             : #define TORTURE_USER_ADMINGROUP         "torture_user_544"
      36             : #define TORTURE_USER_PRINTOPGROUP       "torture_user_550"
      37             : #define TORTURE_USER_PRINTOPPRIV        "torture_user_priv"
      38             : #define TORTURE_USER_SD                 "torture_user_sd"
      39             : #define TORTURE_WORKSTATION             "torture_workstation"
      40             : 
      41             : struct torture_user {
      42             :         const char *username;
      43             :         void *testuser;
      44             :         uint32_t *builtin_memberships;
      45             :         uint32_t num_builtin_memberships;
      46             :         const char **privs;
      47             :         uint32_t num_privs;
      48             :         bool privs_present;
      49             :         bool sd;
      50             :         bool admin_rights;
      51             :         bool system_security;
      52             : };
      53             : 
      54             : struct torture_access_context {
      55             :         struct dcerpc_pipe *spoolss_pipe;
      56             :         const char *printername;
      57             :         struct security_descriptor *sd_orig;
      58             :         struct torture_user user;
      59             : };
      60             : 
      61           0 : static bool test_openprinter_handle(struct torture_context *tctx,
      62             :                                     struct dcerpc_pipe *p,
      63             :                                     const char *name,
      64             :                                     const char *printername,
      65             :                                     const char *username,
      66             :                                     uint32_t access_mask,
      67             :                                     WERROR expected_result,
      68             :                                     struct policy_handle *handle)
      69             : {
      70           0 :         struct spoolss_OpenPrinterEx r;
      71           0 :         struct spoolss_UserLevel1 level1;
      72           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
      73             : 
      74           0 :         level1.size     = 28;
      75           0 :         level1.client   = talloc_asprintf(tctx, "\\\\%s", "smbtorture");
      76           0 :         level1.user     = username;
      77             :         /* Windows 7 and Windows Server 2008 R2 */
      78           0 :         level1.build    = 7007;
      79           0 :         level1.major    = 6;
      80           0 :         level1.minor    = 1;
      81           0 :         level1.processor= 0;
      82             : 
      83           0 :         r.in.printername        = printername;
      84           0 :         r.in.datatype           = NULL;
      85           0 :         r.in.devmode_ctr.devmode= NULL;
      86           0 :         r.in.access_mask        = access_mask;
      87           0 :         r.in.userlevel_ctr.level = 1;
      88           0 :         r.in.userlevel_ctr.user_info.level1 = &level1;
      89           0 :         r.out.handle            = handle;
      90             : 
      91           0 :         torture_comment(tctx, "Testing OpenPrinterEx(%s) with access_mask 0x%08x (%s)\n",
      92             :                 r.in.printername, r.in.access_mask, name);
      93             : 
      94           0 :         torture_assert_ntstatus_ok(tctx,
      95             :                 dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r),
      96             :                 "OpenPrinterEx failed");
      97           0 :         torture_assert_werr_equal(tctx, r.out.result, expected_result,
      98             :                 talloc_asprintf(tctx, "OpenPrinterEx(%s) as '%s' with access_mask: 0x%08x (%s) failed",
      99             :                         r.in.printername, username, r.in.access_mask, name));
     100             : 
     101           0 :         return true;
     102             : }
     103             : 
     104           0 : static bool test_openprinter_access(struct torture_context *tctx,
     105             :                                     struct dcerpc_pipe *p,
     106             :                                     const char *name,
     107             :                                     const char *printername,
     108             :                                     const char *username,
     109             :                                     uint32_t access_mask,
     110             :                                     WERROR expected_result)
     111             : {
     112           0 :         struct policy_handle handle;
     113           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     114           0 :         bool ret = true;
     115             : 
     116           0 :         ZERO_STRUCT(handle);
     117             : 
     118           0 :         if (printername == NULL) {
     119           0 :                 torture_comment(tctx, "skipping test %s as there is no printer\n", name);
     120           0 :                 return true;
     121             :         }
     122             : 
     123           0 :         ret = test_openprinter_handle(tctx, p, name, printername, username, access_mask, expected_result, &handle);
     124           0 :         if (is_valid_policy_hnd(&handle)) {
     125           0 :                 test_ClosePrinter(tctx, b, &handle);
     126             :         }
     127             : 
     128           0 :         return ret;
     129             : }
     130             : 
     131           0 : static bool spoolss_access_setup_membership(struct torture_context *tctx,
     132             :                                             struct dcerpc_pipe *p,
     133             :                                             uint32_t num_members,
     134             :                                             uint32_t *members,
     135             :                                             struct dom_sid *user_sid)
     136             : {
     137           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     138           0 :         struct policy_handle connect_handle, domain_handle;
     139           0 :         int i;
     140             : 
     141           0 :         torture_comment(tctx,
     142             :                 "Setting up BUILTIN membership for %s\n",
     143             :                 dom_sid_string(tctx, user_sid));
     144           0 :         for (i=0; i < num_members; i++) {
     145           0 :                 torture_comment(tctx, "adding user to S-1-5-32-%d\n", members[i]);
     146             :         }
     147             : 
     148             :         {
     149           0 :                 struct samr_Connect2 r;
     150           0 :                 r.in.system_name = "";
     151           0 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     152           0 :                 r.out.connect_handle = &connect_handle;
     153             : 
     154           0 :                 torture_assert_ntstatus_ok(tctx,
     155             :                         dcerpc_samr_Connect2_r(b, tctx, &r),
     156             :                         "samr_Connect2 failed");
     157           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     158             :                         "samr_Connect2 failed");
     159             :         }
     160             : 
     161             :         {
     162           0 :                 struct samr_OpenDomain r;
     163           0 :                 r.in.connect_handle = &connect_handle;
     164           0 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     165           0 :                 r.in.sid = dom_sid_parse_talloc(tctx, "S-1-5-32");
     166           0 :                 r.out.domain_handle = &domain_handle;
     167             : 
     168           0 :                 torture_assert_ntstatus_ok(tctx,
     169             :                         dcerpc_samr_OpenDomain_r(b, tctx, &r),
     170             :                         "samr_OpenDomain failed");
     171           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     172             :                         "samr_OpenDomain failed");
     173             :         }
     174             : 
     175           0 :         for (i=0; i < num_members; i++) {
     176             : 
     177           0 :                 struct policy_handle alias_handle;
     178             : 
     179             :                 {
     180           0 :                 struct samr_OpenAlias r;
     181           0 :                 r.in.domain_handle = &domain_handle;
     182           0 :                 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     183           0 :                 r.in.rid = members[i];
     184           0 :                 r.out.alias_handle = &alias_handle;
     185             : 
     186           0 :                 torture_assert_ntstatus_ok(tctx,
     187             :                         dcerpc_samr_OpenAlias_r(b, tctx, &r),
     188             :                         "samr_OpenAlias failed");
     189           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     190             :                         "samr_OpenAlias failed");
     191             :                 }
     192             : 
     193             :                 {
     194           0 :                 struct samr_AddAliasMember r;
     195           0 :                 r.in.alias_handle = &alias_handle;
     196           0 :                 r.in.sid = user_sid;
     197             : 
     198           0 :                 torture_assert_ntstatus_ok(tctx,
     199             :                         dcerpc_samr_AddAliasMember_r(b, tctx, &r),
     200             :                         "samr_AddAliasMember failed");
     201           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     202             :                         "samr_AddAliasMember failed");
     203             :                 }
     204             : 
     205           0 :                 test_samr_handle_Close(b, tctx, &alias_handle);
     206             :         }
     207             : 
     208           0 :         test_samr_handle_Close(b, tctx, &domain_handle);
     209           0 :         test_samr_handle_Close(b, tctx, &connect_handle);
     210             : 
     211           0 :         return true;
     212             : }
     213             : 
     214           0 : static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
     215             : {
     216           0 :         name->string = s;
     217           0 : }
     218           0 : static void init_lsa_String(struct lsa_String *name, const char *s)
     219             : {
     220           0 :         name->string = s;
     221           0 : }
     222             : 
     223           0 : static bool spoolss_access_setup_privs(struct torture_context *tctx,
     224             :                                        struct dcerpc_pipe *p,
     225             :                                        uint32_t num_privs,
     226             :                                        const char **privs,
     227             :                                        struct dom_sid *user_sid,
     228             :                                        bool *privs_present)
     229             : {
     230           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     231           0 :         struct policy_handle *handle;
     232           0 :         int i;
     233             : 
     234           0 :         torture_assert(tctx,
     235             :                 test_lsa_OpenPolicy2(b, tctx, &handle),
     236             :                 "failed to open policy");
     237             : 
     238           0 :         for (i=0; i < num_privs; i++) {
     239           0 :                 struct lsa_LookupPrivValue r;
     240           0 :                 struct lsa_LUID luid;
     241           0 :                 struct lsa_String name;
     242             : 
     243           0 :                 init_lsa_String(&name, privs[i]);
     244             : 
     245           0 :                 r.in.handle = handle;
     246           0 :                 r.in.name = &name;
     247           0 :                 r.out.luid = &luid;
     248             : 
     249           0 :                 torture_assert_ntstatus_ok(tctx,
     250             :                         dcerpc_lsa_LookupPrivValue_r(b, tctx, &r),
     251             :                         "lsa_LookupPrivValue failed");
     252           0 :                 if (!NT_STATUS_IS_OK(r.out.result)) {
     253           0 :                         torture_comment(tctx, "lsa_LookupPrivValue failed for '%s' with %s\n",
     254           0 :                                         privs[i], nt_errstr(r.out.result));
     255           0 :                         *privs_present = false;
     256           0 :                         return true;
     257             :                 }
     258             :         }
     259             : 
     260           0 :         *privs_present = true;
     261             : 
     262             :         {
     263           0 :                 struct lsa_AddAccountRights r;
     264           0 :                 struct lsa_RightSet rights;
     265             : 
     266           0 :                 rights.count = num_privs;
     267           0 :                 rights.names = talloc_zero_array(tctx, struct lsa_StringLarge, rights.count);
     268             : 
     269           0 :                 for (i=0; i < rights.count; i++) {
     270           0 :                         init_lsa_StringLarge(&rights.names[i], privs[i]);
     271             :                 }
     272             : 
     273           0 :                 r.in.handle = handle;
     274           0 :                 r.in.sid = user_sid;
     275           0 :                 r.in.rights = &rights;
     276             : 
     277           0 :                 torture_assert_ntstatus_ok(tctx,
     278             :                         dcerpc_lsa_AddAccountRights_r(b, tctx, &r),
     279             :                         "lsa_AddAccountRights failed");
     280           0 :                 torture_assert_ntstatus_ok(tctx, r.out.result,
     281             :                         "lsa_AddAccountRights failed");
     282             :         }
     283             : 
     284           0 :         test_lsa_Close(b, tctx, handle);
     285             : 
     286           0 :         return true;
     287             : }
     288             : 
     289           0 : static bool test_SetPrinter(struct torture_context *tctx,
     290             :                             struct dcerpc_binding_handle *b,
     291             :                             struct policy_handle *handle,
     292             :                             struct spoolss_SetPrinterInfoCtr *info_ctr,
     293             :                             struct spoolss_DevmodeContainer *devmode_ctr,
     294             :                             struct sec_desc_buf *secdesc_ctr,
     295             :                             enum spoolss_PrinterControl command)
     296             : {
     297           0 :         struct spoolss_SetPrinter r;
     298             : 
     299           0 :         r.in.handle = handle;
     300           0 :         r.in.info_ctr = info_ctr;
     301           0 :         r.in.devmode_ctr = devmode_ctr;
     302           0 :         r.in.secdesc_ctr = secdesc_ctr;
     303           0 :         r.in.command = command;
     304             : 
     305           0 :         torture_comment(tctx, "Testing SetPrinter level %d\n", r.in.info_ctr->level);
     306             : 
     307           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter_r(b, tctx, &r),
     308             :                 "failed to call SetPrinter");
     309           0 :         torture_assert_werr_ok(tctx, r.out.result,
     310             :                 "failed to call SetPrinter");
     311             : 
     312           0 :         return true;
     313             : }
     314             : 
     315           0 : static bool spoolss_access_setup_sd(struct torture_context *tctx,
     316             :                                     struct dcerpc_pipe *p,
     317             :                                     const char *printername,
     318             :                                     const struct dom_sid *user_sid,
     319             :                                     struct security_descriptor **sd_orig)
     320             : {
     321           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     322           0 :         struct policy_handle handle;
     323           0 :         union spoolss_PrinterInfo info;
     324           0 :         struct spoolss_SetPrinterInfoCtr info_ctr;
     325           0 :         struct spoolss_SetPrinterInfo3 info3;
     326           0 :         struct spoolss_DevmodeContainer devmode_ctr;
     327           0 :         struct sec_desc_buf secdesc_ctr;
     328           0 :         struct security_ace *ace;
     329           0 :         struct security_descriptor *sd;
     330             : 
     331           0 :         torture_assert(tctx,
     332             :                 test_openprinter_handle(tctx, p, "", printername, "", SEC_FLAG_MAXIMUM_ALLOWED, WERR_OK, &handle),
     333             :                 "failed to open printer");
     334             : 
     335           0 :         torture_assert(tctx,
     336             :                 test_GetPrinter_level(tctx, b, &handle, 3, &info),
     337             :                 "failed to get sd");
     338             : 
     339           0 :         sd = security_descriptor_copy(tctx, info.info3.secdesc);
     340           0 :         *sd_orig = security_descriptor_copy(tctx, info.info3.secdesc);
     341             : 
     342           0 :         ace = talloc_zero(tctx, struct security_ace);
     343             : 
     344           0 :         ace->type            = SEC_ACE_TYPE_ACCESS_ALLOWED;
     345           0 :         ace->flags           = 0;
     346           0 :         ace->access_mask     = PRINTER_ALL_ACCESS;
     347           0 :         ace->trustee         = *user_sid;
     348             : 
     349           0 :         torture_assert_ntstatus_ok(tctx,
     350             :                 security_descriptor_dacl_add(sd, ace),
     351             :                 "failed to add new ace");
     352             : 
     353           0 :         ace = talloc_zero(tctx, struct security_ace);
     354             : 
     355           0 :         ace->type            = SEC_ACE_TYPE_ACCESS_ALLOWED;
     356           0 :         ace->flags           = SEC_ACE_FLAG_OBJECT_INHERIT |
     357             :                                   SEC_ACE_FLAG_CONTAINER_INHERIT |
     358             :                                   SEC_ACE_FLAG_INHERIT_ONLY;
     359           0 :         ace->access_mask     = SEC_GENERIC_ALL;
     360           0 :         ace->trustee         = *user_sid;
     361             : 
     362           0 :         torture_assert_ntstatus_ok(tctx,
     363             :                 security_descriptor_dacl_add(sd, ace),
     364             :                 "failed to add new ace");
     365             : 
     366           0 :         ZERO_STRUCT(info3);
     367           0 :         ZERO_STRUCT(info_ctr);
     368           0 :         ZERO_STRUCT(devmode_ctr);
     369           0 :         ZERO_STRUCT(secdesc_ctr);
     370             : 
     371           0 :         info_ctr.level = 3;
     372           0 :         info_ctr.info.info3 = &info3;
     373           0 :         secdesc_ctr.sd = sd;
     374             : 
     375           0 :         torture_assert(tctx,
     376             :                 test_SetPrinter(tctx, b, &handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
     377             :                 "failed to set sd");
     378             : 
     379           0 :         return true;
     380             : }
     381             : 
     382           0 : static bool test_EnumPrinters_findone(struct torture_context *tctx,
     383             :                                       struct dcerpc_pipe *p,
     384             :                                       const char **printername)
     385             : {
     386           0 :         struct spoolss_EnumPrinters r;
     387           0 :         uint32_t count;
     388           0 :         union spoolss_PrinterInfo *info;
     389           0 :         uint32_t needed;
     390           0 :         int i;
     391           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     392             : 
     393           0 :         *printername = NULL;
     394             : 
     395           0 :         r.in.flags = PRINTER_ENUM_LOCAL;
     396           0 :         r.in.server = NULL;
     397           0 :         r.in.level = 1;
     398           0 :         r.in.buffer = NULL;
     399           0 :         r.in.offered = 0;
     400           0 :         r.out.count = &count;
     401           0 :         r.out.info = &info;
     402           0 :         r.out.needed = &needed;
     403             : 
     404           0 :         torture_assert_ntstatus_ok(tctx,
     405             :                 dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
     406             :                 "failed to enum printers");
     407             : 
     408           0 :         if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
     409           0 :                 DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
     410           0 :                 r.in.buffer = &blob;
     411           0 :                 r.in.offered = needed;
     412             : 
     413           0 :                 torture_assert_ntstatus_ok(tctx,
     414             :                         dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
     415             :                         "failed to enum printers");
     416             :         }
     417             : 
     418           0 :         torture_assert_werr_ok(tctx, r.out.result,
     419             :                 "failed to enum printers");
     420             : 
     421           0 :         for (i=0; i < count; i++) {
     422             : 
     423           0 :                 if (count > 1 && strequal(info[i].info1.name, "Microsoft XPS Document Writer")) {
     424           0 :                         continue;
     425             :                 }
     426             : 
     427           0 :                 torture_comment(tctx, "testing printer: %s\n",
     428           0 :                         info[i].info1.name);
     429             : 
     430           0 :                 *printername = talloc_strdup(tctx, info[i].info1.name);
     431             : 
     432           0 :                 break;
     433             :         }
     434             : 
     435           0 :         return true;
     436             : }
     437             : 
     438           0 : static bool torture_rpc_spoolss_access_setup_common(struct torture_context *tctx, struct torture_access_context *t)
     439             : {
     440           0 :         void *testuser;
     441           0 :         const char *testuser_passwd;
     442           0 :         struct cli_credentials *test_credentials;
     443           0 :         struct dom_sid *test_sid;
     444           0 :         struct dcerpc_pipe *p;
     445           0 :         const char *printername;
     446           0 :         const char *binding = torture_setting_string(tctx, "binding", NULL);
     447           0 :         struct dcerpc_pipe *spoolss_pipe;
     448             : 
     449           0 :         testuser = torture_create_testuser_max_pwlen(tctx, t->user.username,
     450             :                                                      torture_setting_string(tctx, "workgroup", NULL),
     451             :                                                      ACB_NORMAL,
     452             :                                                      &testuser_passwd,
     453             :                                                      32);
     454           0 :         if (!testuser) {
     455           0 :                 torture_fail(tctx, "Failed to create test user");
     456             :         }
     457             : 
     458           0 :         test_credentials = cli_credentials_init(tctx);
     459           0 :         cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED);
     460           0 :         cli_credentials_set_domain(test_credentials, lpcfg_workgroup(tctx->lp_ctx),
     461             :                                    CRED_SPECIFIED);
     462           0 :         cli_credentials_set_username(test_credentials, t->user.username, CRED_SPECIFIED);
     463           0 :         cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED);
     464           0 :         test_sid = discard_const_p(struct dom_sid,
     465             :                                    torture_join_user_sid(testuser));
     466             : 
     467           0 :         if (t->user.num_builtin_memberships) {
     468           0 :                 struct dcerpc_pipe *samr_pipe = torture_join_samr_pipe(testuser);
     469             : 
     470           0 :                 torture_assert(tctx,
     471             :                         spoolss_access_setup_membership(tctx, samr_pipe,
     472             :                                                         t->user.num_builtin_memberships,
     473             :                                                         t->user.builtin_memberships,
     474             :                                                         test_sid),
     475             :                         "failed to setup membership");
     476             :         }
     477             : 
     478           0 :         if (t->user.num_privs) {
     479           0 :                 struct dcerpc_pipe *lsa_pipe;
     480             : 
     481           0 :                 torture_assert_ntstatus_ok(tctx,
     482             :                         torture_rpc_connection(tctx, &lsa_pipe, &ndr_table_lsarpc),
     483             :                         "Error connecting to server");
     484             : 
     485           0 :                 torture_assert(tctx,
     486             :                         spoolss_access_setup_privs(tctx, lsa_pipe,
     487             :                                                    t->user.num_privs,
     488             :                                                    t->user.privs,
     489             :                                                    test_sid,
     490             :                                                    &t->user.privs_present),
     491             :                         "failed to setup privs");
     492           0 :                 talloc_free(lsa_pipe);
     493             :         }
     494             : 
     495           0 :         torture_assert_ntstatus_ok(tctx,
     496             :                 torture_rpc_connection(tctx, &spoolss_pipe, &ndr_table_spoolss),
     497             :                 "Error connecting to server");
     498             : 
     499           0 :         torture_assert(tctx,
     500             :                 test_EnumPrinters_findone(tctx, spoolss_pipe, &printername),
     501             :                 "failed to enumerate printers");
     502             : 
     503           0 :         if (t->user.sd && printername) {
     504           0 :                 torture_assert(tctx,
     505             :                         spoolss_access_setup_sd(tctx, spoolss_pipe,
     506             :                                                 printername,
     507             :                                                 test_sid,
     508             :                                                 &t->sd_orig),
     509             :                         "failed to setup sd");
     510             :         }
     511             : 
     512           0 :         talloc_free(spoolss_pipe);
     513             : 
     514           0 :         torture_assert_ntstatus_ok(tctx,
     515             :                 dcerpc_pipe_connect(tctx, &p, binding, &ndr_table_spoolss,
     516             :                                     test_credentials, tctx->ev, tctx->lp_ctx),
     517             :                 "Error connecting to server");
     518             : 
     519           0 :         t->spoolss_pipe = p;
     520           0 :         t->printername = printername;
     521           0 :         t->user.testuser = testuser;
     522             : 
     523           0 :         return true;
     524             : }
     525             : 
     526           0 : static bool torture_rpc_spoolss_access_setup(struct torture_context *tctx, void **data)
     527             : {
     528           0 :         struct torture_access_context *t;
     529             : 
     530           0 :         *data = t = talloc_zero(tctx, struct torture_access_context);
     531             : 
     532           0 :         t->user.username = talloc_strdup(t, TORTURE_USER);
     533             : 
     534           0 :         return torture_rpc_spoolss_access_setup_common(tctx, t);
     535             : }
     536             : 
     537           0 : static bool torture_rpc_spoolss_access_admin_setup(struct torture_context *tctx, void **data)
     538             : {
     539           0 :         struct torture_access_context *t;
     540             : 
     541           0 :         *data = t = talloc_zero(tctx, struct torture_access_context);
     542             : 
     543           0 :         t->user.num_builtin_memberships = 1;
     544           0 :         t->user.builtin_memberships = talloc_zero_array(t, uint32_t, t->user.num_builtin_memberships);
     545           0 :         t->user.builtin_memberships[0] = BUILTIN_RID_ADMINISTRATORS;
     546           0 :         t->user.username = talloc_strdup(t, TORTURE_USER_ADMINGROUP);
     547           0 :         t->user.admin_rights = true;
     548           0 :         t->user.system_security = true;
     549             : 
     550           0 :         return torture_rpc_spoolss_access_setup_common(tctx, t);
     551             : }
     552             : 
     553           0 : static bool torture_rpc_spoolss_access_printop_setup(struct torture_context *tctx, void **data)
     554             : {
     555           0 :         struct torture_access_context *t;
     556             : 
     557           0 :         *data = t = talloc_zero(tctx, struct torture_access_context);
     558             : 
     559           0 :         t->user.num_builtin_memberships = 1;
     560           0 :         t->user.builtin_memberships = talloc_zero_array(t, uint32_t, t->user.num_builtin_memberships);
     561           0 :         t->user.builtin_memberships[0] = BUILTIN_RID_PRINT_OPERATORS;
     562           0 :         t->user.username = talloc_strdup(t, TORTURE_USER_PRINTOPGROUP);
     563           0 :         t->user.admin_rights = true;
     564             : 
     565           0 :         return torture_rpc_spoolss_access_setup_common(tctx, t);
     566             : }
     567             : 
     568           0 : static bool torture_rpc_spoolss_access_priv_setup(struct torture_context *tctx, void **data)
     569             : {
     570           0 :         struct torture_access_context *t;
     571             : 
     572           0 :         *data = t = talloc_zero(tctx, struct torture_access_context);
     573             : 
     574           0 :         t->user.username = talloc_strdup(t, TORTURE_USER_PRINTOPPRIV);
     575           0 :         t->user.num_privs = 1;
     576           0 :         t->user.privs = talloc_zero_array(t, const char *, t->user.num_privs);
     577           0 :         t->user.privs[0] = talloc_strdup(t, "SePrintOperatorPrivilege");
     578           0 :         t->user.admin_rights = true;
     579             : 
     580           0 :         return torture_rpc_spoolss_access_setup_common(tctx, t);
     581             : }
     582             : 
     583           0 : static bool torture_rpc_spoolss_access_sd_setup(struct torture_context *tctx, void **data)
     584             : {
     585           0 :         struct torture_access_context *t;
     586             : 
     587           0 :         *data = t = talloc_zero(tctx, struct torture_access_context);
     588             : 
     589           0 :         t->user.username = talloc_strdup(t, TORTURE_USER_SD);
     590           0 :         t->user.sd = true;
     591           0 :         t->user.admin_rights = true;
     592             : 
     593           0 :         return torture_rpc_spoolss_access_setup_common(tctx, t);
     594             : }
     595             : 
     596           0 : static bool torture_rpc_spoolss_access_teardown_common(struct torture_context *tctx, struct torture_access_context *t)
     597             : {
     598           0 :         if (t->user.testuser) {
     599           0 :                 torture_leave_domain(tctx, t->user.testuser);
     600             :         }
     601             : 
     602             :         /* remove membership ? */
     603           0 :         if (t->user.num_builtin_memberships) {
     604           0 :         }
     605             : 
     606             :         /* remove privs ? */
     607           0 :         if (t->user.num_privs) {
     608           0 :         }
     609             : 
     610             :         /* restore sd */
     611           0 :         if (t->user.sd && t->printername) {
     612           0 :                 struct policy_handle handle;
     613           0 :                 struct spoolss_SetPrinterInfoCtr info_ctr;
     614           0 :                 struct spoolss_SetPrinterInfo3 info3;
     615           0 :                 struct spoolss_DevmodeContainer devmode_ctr;
     616           0 :                 struct sec_desc_buf secdesc_ctr;
     617           0 :                 struct dcerpc_pipe *spoolss_pipe;
     618           0 :                 struct dcerpc_binding_handle *b;
     619             : 
     620           0 :                 torture_assert_ntstatus_ok(tctx,
     621             :                         torture_rpc_connection(tctx, &spoolss_pipe, &ndr_table_spoolss),
     622             :                         "Error connecting to server");
     623             : 
     624           0 :                 b = spoolss_pipe->binding_handle;
     625             : 
     626           0 :                 ZERO_STRUCT(info_ctr);
     627           0 :                 ZERO_STRUCT(info3);
     628           0 :                 ZERO_STRUCT(devmode_ctr);
     629           0 :                 ZERO_STRUCT(secdesc_ctr);
     630             : 
     631           0 :                 info_ctr.level = 3;
     632           0 :                 info_ctr.info.info3 = &info3;
     633           0 :                 secdesc_ctr.sd = t->sd_orig;
     634             : 
     635           0 :                 torture_assert(tctx,
     636             :                         test_openprinter_handle(tctx, spoolss_pipe, "", t->printername, "", SEC_FLAG_MAXIMUM_ALLOWED, WERR_OK, &handle),
     637             :                         "failed to open printer");
     638             : 
     639           0 :                 torture_assert(tctx,
     640             :                         test_SetPrinter(tctx, b, &handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
     641             :                         "failed to set sd");
     642             : 
     643           0 :                 talloc_free(spoolss_pipe);
     644             :         }
     645             : 
     646           0 :         return true;
     647             : }
     648             : 
     649           0 : static bool torture_rpc_spoolss_access_teardown(struct torture_context *tctx, void *data)
     650             : {
     651           0 :         struct torture_access_context *t = talloc_get_type(data, struct torture_access_context);
     652           0 :         bool ret;
     653             : 
     654           0 :         ret = torture_rpc_spoolss_access_teardown_common(tctx, t);
     655           0 :         talloc_free(t);
     656             : 
     657           0 :         return ret;
     658             : }
     659             : 
     660           0 : static bool test_openprinter(struct torture_context *tctx,
     661             :                              void *private_data)
     662             : {
     663           0 :         struct torture_access_context *t =
     664           0 :                 (struct torture_access_context *)talloc_get_type_abort(private_data, struct torture_access_context);
     665           0 :         struct dcerpc_pipe *p = t->spoolss_pipe;
     666           0 :         bool ret = true;
     667           0 :         const char *username = t->user.username;
     668           0 :         const char *servername_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
     669           0 :         int i;
     670             : 
     671           0 :         struct {
     672             :                 const char *name;
     673             :                 uint32_t access_mask;
     674             :                 const char *printername;
     675             :                 WERROR expected_result;
     676           0 :         } checks[] = {
     677             : 
     678             :                 /* printserver handle tests */
     679             : 
     680             :                 {
     681             :                         .name                   = "0",
     682             :                         .access_mask            = 0,
     683             :                         .printername            = servername_slash,
     684             :                         .expected_result        = WERR_OK
     685             :                 },
     686             :                 {
     687             :                         .name                   = "SEC_FLAG_MAXIMUM_ALLOWED",
     688             :                         .access_mask            = SEC_FLAG_MAXIMUM_ALLOWED,
     689             :                         .printername            = servername_slash,
     690             :                         .expected_result        = WERR_OK
     691             :                 },
     692             :                 {
     693             :                         .name                   = "SERVER_ACCESS_ENUMERATE",
     694             :                         .access_mask            = SERVER_ACCESS_ENUMERATE,
     695             :                         .printername            = servername_slash,
     696             :                         .expected_result        = WERR_OK
     697             :                 },
     698             :                 {
     699             :                         .name                   = "SERVER_ACCESS_ADMINISTER",
     700             :                         .access_mask            = SERVER_ACCESS_ADMINISTER,
     701             :                         .printername            = servername_slash,
     702           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     703             :                 },
     704             :                 {
     705             :                         .name                   = "SERVER_READ",
     706             :                         .access_mask            = SERVER_READ,
     707             :                         .printername            = servername_slash,
     708             :                         .expected_result        = WERR_OK
     709             :                 },
     710             :                 {
     711             :                         .name                   = "SERVER_WRITE",
     712             :                         .access_mask            = SERVER_WRITE,
     713             :                         .printername            = servername_slash,
     714           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     715             :                 },
     716             :                 {
     717             :                         .name                   = "SERVER_EXECUTE",
     718             :                         .access_mask            = SERVER_EXECUTE,
     719             :                         .printername            = servername_slash,
     720             :                         .expected_result        = WERR_OK
     721             :                 },
     722             :                 {
     723             :                         .name                   = "SERVER_ALL_ACCESS",
     724             :                         .access_mask            = SERVER_ALL_ACCESS,
     725             :                         .printername            = servername_slash,
     726           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     727             :                 },
     728             : 
     729             :                 /* printer handle tests */
     730             : 
     731             :                 {
     732             :                         .name                   = "0",
     733             :                         .access_mask            = 0,
     734           0 :                         .printername            = t->printername,
     735             :                         .expected_result        = WERR_OK
     736             :                 },
     737             :                 {
     738             :                         .name                   = "SEC_FLAG_MAXIMUM_ALLOWED",
     739             :                         .access_mask            = SEC_FLAG_MAXIMUM_ALLOWED,
     740           0 :                         .printername            = t->printername,
     741             :                         .expected_result        = WERR_OK
     742             :                 },
     743             :                 {
     744             :                         .name                   = "SEC_FLAG_SYSTEM_SECURITY",
     745             :                         .access_mask            = SEC_FLAG_SYSTEM_SECURITY,
     746           0 :                         .printername            = t->printername,
     747           0 :                         .expected_result        = t->user.system_security ? WERR_OK : WERR_ACCESS_DENIED
     748             :                 },
     749             :                 {
     750             :                         .name                   = "0x010e0000",
     751             :                         .access_mask            = 0x010e0000,
     752           0 :                         .printername            = t->printername,
     753           0 :                         .expected_result        = t->user.system_security ? WERR_OK : WERR_ACCESS_DENIED
     754             :                 },
     755             :                 {
     756             :                         .name                   = "PRINTER_ACCESS_USE",
     757             :                         .access_mask            = PRINTER_ACCESS_USE,
     758           0 :                         .printername            = t->printername,
     759             :                         .expected_result        = WERR_OK
     760             :                 },
     761             :                 {
     762             :                         .name                   = "SEC_STD_READ_CONTROL",
     763             :                         .access_mask            = SEC_STD_READ_CONTROL,
     764           0 :                         .printername            = t->printername,
     765             :                         .expected_result        = WERR_OK
     766             :                 },
     767             :                 {
     768             :                         .name                   = "PRINTER_ACCESS_ADMINISTER",
     769             :                         .access_mask            = PRINTER_ACCESS_ADMINISTER,
     770           0 :                         .printername            = t->printername,
     771           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     772             :                 },
     773             :                 {
     774             :                         .name                   = "SEC_STD_WRITE_DAC",
     775             :                         .access_mask            = SEC_STD_WRITE_DAC,
     776           0 :                         .printername            = t->printername,
     777           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     778             :                 },
     779             :                 {
     780             :                         .name                   = "SEC_STD_WRITE_OWNER",
     781             :                         .access_mask            = SEC_STD_WRITE_OWNER,
     782           0 :                         .printername            = t->printername,
     783           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     784             :                 },
     785             :                 {
     786             :                         .name                   = "PRINTER_READ",
     787             :                         .access_mask            = PRINTER_READ,
     788           0 :                         .printername            = t->printername,
     789             :                         .expected_result        = WERR_OK
     790             :                 },
     791             :                 {
     792             :                         .name                   = "PRINTER_WRITE",
     793             :                         .access_mask            = PRINTER_WRITE,
     794           0 :                         .printername            = t->printername,
     795           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     796             :                 },
     797             :                 {
     798             :                         .name                   = "PRINTER_EXECUTE",
     799             :                         .access_mask            = PRINTER_EXECUTE,
     800           0 :                         .printername            = t->printername,
     801             :                         .expected_result        = WERR_OK
     802             :                 },
     803             :                 {
     804             :                         .name                   = "PRINTER_ALL_ACCESS",
     805             :                         .access_mask            = PRINTER_ALL_ACCESS,
     806           0 :                         .printername            = t->printername,
     807           0 :                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
     808             :                 }
     809             :         };
     810             : 
     811           0 :         if (t->user.num_privs && !t->user.privs_present) {
     812           0 :                 torture_skip(tctx, "skipping test as not all required privileges are present on the server\n");
     813             :         }
     814             : 
     815           0 :         for (i=0; i < ARRAY_SIZE(checks); i++) {
     816           0 :                 ret &= test_openprinter_access(tctx, p,
     817             :                                                checks[i].name,
     818             :                                                checks[i].printername,
     819             :                                                username,
     820             :                                                checks[i].access_mask,
     821             :                                                checks[i].expected_result);
     822             :         }
     823             : 
     824           0 :         return ret;
     825             : }
     826             : 
     827           0 : static bool test_openprinter_wrap(struct torture_context *tctx,
     828             :                                   struct dcerpc_pipe *p)
     829             : {
     830           0 :         struct torture_access_context *t;
     831           0 :         const char *printername;
     832           0 :         bool ret = true;
     833             : 
     834           0 :         t = talloc_zero(tctx, struct torture_access_context);
     835             : 
     836           0 :         t->user.username = talloc_strdup(tctx, "dummy");
     837           0 :         t->spoolss_pipe = p;
     838             : 
     839           0 :         torture_assert(tctx,
     840             :                 test_EnumPrinters_findone(tctx, p, &printername),
     841             :                 "failed to enumerate printers");
     842             : 
     843           0 :         t->printername = printername;
     844             : 
     845           0 :         ret = test_openprinter(tctx, (void *)t);
     846             : 
     847           0 :         talloc_free(t);
     848             : 
     849           0 :         return ret;
     850             : }
     851             : 
     852        2379 : struct torture_suite *torture_rpc_spoolss_access(TALLOC_CTX *mem_ctx)
     853             : {
     854        2379 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "spoolss.access");
     855         125 :         struct torture_tcase *tcase;
     856         125 :         struct torture_rpc_tcase *rpc_tcase;
     857             : 
     858        2379 :         tcase = torture_suite_add_tcase(suite, "normaluser");
     859             : 
     860        2379 :         torture_tcase_set_fixture(tcase,
     861             :                                   torture_rpc_spoolss_access_setup,
     862             :                                   torture_rpc_spoolss_access_teardown);
     863             : 
     864        2379 :         torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
     865             : 
     866        2379 :         tcase = torture_suite_add_tcase(suite, "adminuser");
     867             : 
     868        2379 :         torture_tcase_set_fixture(tcase,
     869             :                                   torture_rpc_spoolss_access_admin_setup,
     870             :                                   torture_rpc_spoolss_access_teardown);
     871             : 
     872        2379 :         torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
     873             : 
     874        2379 :         tcase = torture_suite_add_tcase(suite, "printopuser");
     875             : 
     876        2379 :         torture_tcase_set_fixture(tcase,
     877             :                                   torture_rpc_spoolss_access_printop_setup,
     878             :                                   torture_rpc_spoolss_access_teardown);
     879             : 
     880        2379 :         torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
     881             : 
     882        2379 :         tcase = torture_suite_add_tcase(suite, "printopuserpriv");
     883             : 
     884        2379 :         torture_tcase_set_fixture(tcase,
     885             :                                   torture_rpc_spoolss_access_priv_setup,
     886             :                                   torture_rpc_spoolss_access_teardown);
     887             : 
     888        2379 :         torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
     889             : 
     890        2379 :         tcase = torture_suite_add_tcase(suite, "normaluser_sd");
     891             : 
     892        2379 :         torture_tcase_set_fixture(tcase,
     893             :                                   torture_rpc_spoolss_access_sd_setup,
     894             :                                   torture_rpc_spoolss_access_teardown);
     895             : 
     896        2379 :         torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
     897             : 
     898        2379 :         rpc_tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "workstation",
     899             :                                                                           &ndr_table_spoolss,
     900             :                                                                           TORTURE_WORKSTATION);
     901             : 
     902        2379 :         torture_rpc_tcase_add_test(rpc_tcase, "openprinter", test_openprinter_wrap);
     903             : 
     904        2379 :         return suite;
     905             : }

Generated by: LCOV version 1.14