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