s4-loadparm: 2nd half of lp_ to lpcfg_ conversion
[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.level              = 1;
87         r.in.userlevel.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 is_valid_policy_hnd(const struct policy_handle *hnd)
104 {
105         struct policy_handle tmp;
106         ZERO_STRUCT(tmp);
107         return (memcmp(&tmp, hnd, sizeof(tmp)) != 0);
108 }
109
110 static bool test_openprinter_access(struct torture_context *tctx,
111                                     struct dcerpc_pipe *p,
112                                     const char *name,
113                                     const char *printername,
114                                     const char *username,
115                                     uint32_t access_mask,
116                                     WERROR expected_result)
117 {
118         struct policy_handle handle;
119         struct dcerpc_binding_handle *b = p->binding_handle;
120         bool ret = true;
121
122         ZERO_STRUCT(handle);
123
124         if (printername == NULL) {
125                 torture_comment(tctx, "skipping test %s as there is no printer\n", name);
126                 return true;
127         }
128
129         ret = test_openprinter_handle(tctx, p, name, printername, username, access_mask, expected_result, &handle);
130         if (is_valid_policy_hnd(&handle)) {
131                 test_ClosePrinter(tctx, b, &handle);
132         }
133
134         return ret;
135 }
136
137 static bool spoolss_access_setup_membership(struct torture_context *tctx,
138                                             struct dcerpc_pipe *p,
139                                             uint32_t num_members,
140                                             uint32_t *members,
141                                             struct dom_sid *user_sid)
142 {
143         struct dcerpc_binding_handle *b = p->binding_handle;
144         struct policy_handle connect_handle, domain_handle;
145         int i;
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                                     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 = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
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                 *printername = talloc_strdup(tctx, info[i].info1.name);
423
424                 break;
425         }
426
427         return true;
428 }
429
430 static bool torture_rpc_spoolss_access_setup_common(struct torture_context *tctx, struct torture_access_context *t)
431 {
432         void *testuser;
433         const char *testuser_passwd;
434         struct cli_credentials *test_credentials;
435         struct dom_sid *test_sid;
436         struct dcerpc_pipe *p;
437         const char *printername;
438         const char *binding = torture_setting_string(tctx, "binding", NULL);
439         struct dcerpc_pipe *spoolss_pipe;
440
441         testuser = torture_create_testuser_max_pwlen(tctx, t->user.username,
442                                                      torture_setting_string(tctx, "workgroup", NULL),
443                                                      ACB_NORMAL,
444                                                      &testuser_passwd,
445                                                      32);
446         if (!testuser) {
447                 torture_fail(tctx, "Failed to create test user");
448         }
449
450         test_credentials = cli_credentials_init(tctx);
451         cli_credentials_set_workstation(test_credentials, "localhost", CRED_SPECIFIED);
452         cli_credentials_set_domain(test_credentials, lpcfg_workgroup(tctx->lp_ctx),
453                                    CRED_SPECIFIED);
454         cli_credentials_set_username(test_credentials, t->user.username, CRED_SPECIFIED);
455         cli_credentials_set_password(test_credentials, testuser_passwd, CRED_SPECIFIED);
456         test_sid = torture_join_user_sid(testuser);
457
458         if (t->user.num_builtin_memberships) {
459                 struct dcerpc_pipe *samr_pipe = torture_join_samr_pipe(testuser);
460
461                 torture_assert(tctx,
462                         spoolss_access_setup_membership(tctx, samr_pipe,
463                                                         t->user.num_builtin_memberships,
464                                                         t->user.builtin_memberships,
465                                                         test_sid),
466                         "failed to setup membership");
467         }
468
469         if (t->user.num_privs) {
470                 struct dcerpc_pipe *lsa_pipe;
471
472                 torture_assert_ntstatus_ok(tctx,
473                         torture_rpc_connection(tctx, &lsa_pipe, &ndr_table_lsarpc),
474                         "Error connecting to server");
475
476                 torture_assert(tctx,
477                         spoolss_access_setup_privs(tctx, lsa_pipe,
478                                                    t->user.num_privs,
479                                                    t->user.privs,
480                                                    test_sid,
481                                                    &t->user.privs_present),
482                         "failed to setup privs");
483                 talloc_free(lsa_pipe);
484         }
485
486         torture_assert_ntstatus_ok(tctx,
487                 torture_rpc_connection(tctx, &spoolss_pipe, &ndr_table_spoolss),
488                 "Error connecting to server");
489
490         torture_assert(tctx,
491                 test_EnumPrinters_findone(tctx, spoolss_pipe, &printername),
492                 "failed to enumerate printers");
493
494         if (t->user.sd && printername) {
495                 torture_assert(tctx,
496                         spoolss_access_setup_sd(tctx, spoolss_pipe,
497                                                 printername,
498                                                 test_sid,
499                                                 &t->sd_orig),
500                         "failed to setup sd");
501         }
502
503         talloc_free(spoolss_pipe);
504
505         torture_assert_ntstatus_ok(tctx,
506                 dcerpc_pipe_connect(tctx, &p, binding, &ndr_table_spoolss,
507                                     test_credentials, tctx->ev, tctx->lp_ctx),
508                 "Error connecting to server");
509
510         t->spoolss_pipe = p;
511         t->printername = printername;
512         t->user.testuser = testuser;
513
514         return true;
515 }
516
517 static bool torture_rpc_spoolss_access_setup(struct torture_context *tctx, void **data)
518 {
519         struct torture_access_context *t;
520
521         *data = t = talloc_zero(tctx, struct torture_access_context);
522
523         t->user.username = talloc_strdup(t, TORTURE_USER);
524
525         return torture_rpc_spoolss_access_setup_common(tctx, t);
526 }
527
528 static bool torture_rpc_spoolss_access_admin_setup(struct torture_context *tctx, void **data)
529 {
530         struct torture_access_context *t;
531
532         *data = t = talloc_zero(tctx, struct torture_access_context);
533
534         t->user.num_builtin_memberships = 1;
535         t->user.builtin_memberships = talloc_zero_array(t, uint32_t, t->user.num_builtin_memberships);
536         t->user.builtin_memberships[0] = BUILTIN_RID_ADMINISTRATORS;
537         t->user.username = talloc_strdup(t, TORTURE_USER_ADMINGROUP);
538         t->user.admin_rights = true;
539         t->user.system_security = true;
540
541         return torture_rpc_spoolss_access_setup_common(tctx, t);
542 }
543
544 static bool torture_rpc_spoolss_access_printop_setup(struct torture_context *tctx, void **data)
545 {
546         struct torture_access_context *t;
547
548         *data = t = talloc_zero(tctx, struct torture_access_context);
549
550         t->user.num_builtin_memberships = 1;
551         t->user.builtin_memberships = talloc_zero_array(t, uint32_t, t->user.num_builtin_memberships);
552         t->user.builtin_memberships[0] = BUILTIN_RID_PRINT_OPERATORS;
553         t->user.username = talloc_strdup(t, TORTURE_USER_PRINTOPGROUP);
554         t->user.admin_rights = true;
555
556         return torture_rpc_spoolss_access_setup_common(tctx, t);
557 }
558
559 static bool torture_rpc_spoolss_access_priv_setup(struct torture_context *tctx, void **data)
560 {
561         struct torture_access_context *t;
562
563         *data = t = talloc_zero(tctx, struct torture_access_context);
564
565         t->user.username = talloc_strdup(t, TORTURE_USER_PRINTOPPRIV);
566         t->user.num_privs = 1;
567         t->user.privs = talloc_zero_array(t, const char *, t->user.num_privs);
568         t->user.privs[0] = talloc_strdup(t, "SePrintOperatorPrivilege");
569         t->user.admin_rights = true;
570
571         return torture_rpc_spoolss_access_setup_common(tctx, t);
572 }
573
574 static bool torture_rpc_spoolss_access_sd_setup(struct torture_context *tctx, void **data)
575 {
576         struct torture_access_context *t;
577
578         *data = t = talloc_zero(tctx, struct torture_access_context);
579
580         t->user.username = talloc_strdup(t, TORTURE_USER_SD);
581         t->user.sd = true;
582         t->user.admin_rights = true;
583
584         return torture_rpc_spoolss_access_setup_common(tctx, t);
585 }
586
587 static bool torture_rpc_spoolss_access_teardown_common(struct torture_context *tctx, struct torture_access_context *t)
588 {
589         if (t->user.testuser) {
590                 torture_leave_domain(tctx, t->user.testuser);
591         }
592
593         /* remove membership ? */
594         if (t->user.num_builtin_memberships) {
595         }
596
597         /* remove privs ? */
598         if (t->user.num_privs) {
599         }
600
601         /* restore sd */
602         if (t->user.sd && t->printername) {
603                 struct policy_handle handle;
604                 struct spoolss_SetPrinterInfoCtr info_ctr;
605                 struct spoolss_SetPrinterInfo3 info3;
606                 struct spoolss_DevmodeContainer devmode_ctr;
607                 struct sec_desc_buf secdesc_ctr;
608                 struct dcerpc_pipe *spoolss_pipe;
609                 struct dcerpc_binding_handle *b;
610
611                 torture_assert_ntstatus_ok(tctx,
612                         torture_rpc_connection(tctx, &spoolss_pipe, &ndr_table_spoolss),
613                         "Error connecting to server");
614
615                 b = spoolss_pipe->binding_handle;
616
617                 ZERO_STRUCT(info_ctr);
618                 ZERO_STRUCT(info3);
619                 ZERO_STRUCT(devmode_ctr);
620                 ZERO_STRUCT(secdesc_ctr);
621
622                 info_ctr.level = 3;
623                 info_ctr.info.info3 = &info3;
624                 secdesc_ctr.sd = t->sd_orig;
625
626                 torture_assert(tctx,
627                         test_openprinter_handle(tctx, spoolss_pipe, "", t->printername, "", SEC_FLAG_MAXIMUM_ALLOWED, WERR_OK, &handle),
628                         "failed to open printer");
629
630                 torture_assert(tctx,
631                         test_SetPrinter(tctx, b, &handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
632                         "failed to set sd");
633
634                 talloc_free(spoolss_pipe);
635         }
636
637         return true;
638 }
639
640 static bool torture_rpc_spoolss_access_teardown(struct torture_context *tctx, void *data)
641 {
642         struct torture_access_context *t = talloc_get_type(data, struct torture_access_context);
643         bool ret;
644
645         ret = torture_rpc_spoolss_access_teardown_common(tctx, t);
646         talloc_free(t);
647
648         return ret;
649 }
650
651 static bool test_openprinter(struct torture_context *tctx,
652                              void *private_data)
653 {
654         struct torture_access_context *t =
655                 (struct torture_access_context *)talloc_get_type_abort(private_data, struct torture_access_context);
656         struct dcerpc_pipe *p = t->spoolss_pipe;
657         bool ret = true;
658         const char *username = t->user.username;
659         const char *servername_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
660         int i;
661
662         struct {
663                 const char *name;
664                 uint32_t access_mask;
665                 const char *printername;
666                 WERROR expected_result;
667         } checks[] = {
668
669                 /* printserver handle tests */
670
671                 {
672                         .name                   = "0",
673                         .access_mask            = 0,
674                         .printername            = servername_slash,
675                         .expected_result        = WERR_OK
676                 },
677                 {
678                         .name                   = "SEC_FLAG_MAXIMUM_ALLOWED",
679                         .access_mask            = SEC_FLAG_MAXIMUM_ALLOWED,
680                         .printername            = servername_slash,
681                         .expected_result        = WERR_OK
682                 },
683                 {
684                         .name                   = "SERVER_ACCESS_ENUMERATE",
685                         .access_mask            = SERVER_ACCESS_ENUMERATE,
686                         .printername            = servername_slash,
687                         .expected_result        = WERR_OK
688                 },
689                 {
690                         .name                   = "SERVER_ACCESS_ADMINISTER",
691                         .access_mask            = SERVER_ACCESS_ADMINISTER,
692                         .printername            = servername_slash,
693                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
694                 },
695                 {
696                         .name                   = "SERVER_READ",
697                         .access_mask            = SERVER_READ,
698                         .printername            = servername_slash,
699                         .expected_result        = WERR_OK
700                 },
701                 {
702                         .name                   = "SERVER_WRITE",
703                         .access_mask            = SERVER_WRITE,
704                         .printername            = servername_slash,
705                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
706                 },
707                 {
708                         .name                   = "SERVER_EXECUTE",
709                         .access_mask            = SERVER_EXECUTE,
710                         .printername            = servername_slash,
711                         .expected_result        = WERR_OK
712                 },
713                 {
714                         .name                   = "SERVER_ALL_ACCESS",
715                         .access_mask            = SERVER_ALL_ACCESS,
716                         .printername            = servername_slash,
717                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
718                 },
719
720                 /* printer handle tests */
721
722                 {
723                         .name                   = "0",
724                         .access_mask            = 0,
725                         .printername            = t->printername,
726                         .expected_result        = WERR_OK
727                 },
728                 {
729                         .name                   = "SEC_FLAG_MAXIMUM_ALLOWED",
730                         .access_mask            = SEC_FLAG_MAXIMUM_ALLOWED,
731                         .printername            = t->printername,
732                         .expected_result        = WERR_OK
733                 },
734                 {
735                         .name                   = "SEC_FLAG_SYSTEM_SECURITY",
736                         .access_mask            = SEC_FLAG_SYSTEM_SECURITY,
737                         .printername            = t->printername,
738                         .expected_result        = t->user.system_security ? WERR_OK : WERR_ACCESS_DENIED
739                 },
740                 {
741                         .name                   = "0x010e0000",
742                         .access_mask            = 0x010e0000,
743                         .printername            = t->printername,
744                         .expected_result        = t->user.system_security ? WERR_OK : WERR_ACCESS_DENIED
745                 },
746                 {
747                         .name                   = "PRINTER_ACCESS_USE",
748                         .access_mask            = PRINTER_ACCESS_USE,
749                         .printername            = t->printername,
750                         .expected_result        = WERR_OK
751                 },
752                 {
753                         .name                   = "SEC_STD_READ_CONTROL",
754                         .access_mask            = SEC_STD_READ_CONTROL,
755                         .printername            = t->printername,
756                         .expected_result        = WERR_OK
757                 },
758                 {
759                         .name                   = "PRINTER_ACCESS_ADMINISTER",
760                         .access_mask            = PRINTER_ACCESS_ADMINISTER,
761                         .printername            = t->printername,
762                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
763                 },
764                 {
765                         .name                   = "SEC_STD_WRITE_DAC",
766                         .access_mask            = SEC_STD_WRITE_DAC,
767                         .printername            = t->printername,
768                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
769                 },
770                 {
771                         .name                   = "SEC_STD_WRITE_OWNER",
772                         .access_mask            = SEC_STD_WRITE_OWNER,
773                         .printername            = t->printername,
774                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
775                 },
776                 {
777                         .name                   = "PRINTER_READ",
778                         .access_mask            = PRINTER_READ,
779                         .printername            = t->printername,
780                         .expected_result        = WERR_OK
781                 },
782                 {
783                         .name                   = "PRINTER_WRITE",
784                         .access_mask            = PRINTER_WRITE,
785                         .printername            = t->printername,
786                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
787                 },
788                 {
789                         .name                   = "PRINTER_EXECUTE",
790                         .access_mask            = PRINTER_EXECUTE,
791                         .printername            = t->printername,
792                         .expected_result        = WERR_OK
793                 },
794                 {
795                         .name                   = "PRINTER_ALL_ACCESS",
796                         .access_mask            = PRINTER_ALL_ACCESS,
797                         .printername            = t->printername,
798                         .expected_result        = t->user.admin_rights ? WERR_OK : WERR_ACCESS_DENIED
799                 }
800         };
801
802         if (t->user.num_privs && !t->user.privs_present) {
803                 torture_skip(tctx, "skipping test as not all required privileges are present on the server\n");
804         }
805
806         for (i=0; i < ARRAY_SIZE(checks); i++) {
807                 ret &= test_openprinter_access(tctx, p,
808                                                checks[i].name,
809                                                checks[i].printername,
810                                                username,
811                                                checks[i].access_mask,
812                                                checks[i].expected_result);
813         }
814
815         return ret;
816 }
817
818 static bool test_openprinter_wrap(struct torture_context *tctx,
819                                   struct dcerpc_pipe *p)
820 {
821         struct torture_access_context *t;
822         const char *printername;
823         bool ret = true;
824
825         t = talloc_zero(tctx, struct torture_access_context);
826
827         t->user.username = talloc_strdup(tctx, "dummy");
828         t->spoolss_pipe = p;
829
830         torture_assert(tctx,
831                 test_EnumPrinters_findone(tctx, p, &printername),
832                 "failed to enumerate printers");
833
834         t->printername = printername;
835
836         ret = test_openprinter(tctx, (void *)t);
837
838         talloc_free(t);
839
840         return true;
841 }
842
843 struct torture_suite *torture_rpc_spoolss_access(TALLOC_CTX *mem_ctx)
844 {
845         struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-ACCESS");
846         struct torture_tcase *tcase;
847         struct torture_rpc_tcase *rpc_tcase;
848
849         tcase = torture_suite_add_tcase(suite, "normaluser");
850
851         torture_tcase_set_fixture(tcase,
852                                   torture_rpc_spoolss_access_setup,
853                                   torture_rpc_spoolss_access_teardown);
854
855         torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
856
857         tcase = torture_suite_add_tcase(suite, "adminuser");
858
859         torture_tcase_set_fixture(tcase,
860                                   torture_rpc_spoolss_access_admin_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, "printopuser");
866
867         torture_tcase_set_fixture(tcase,
868                                   torture_rpc_spoolss_access_printop_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, "printopuserpriv");
874
875         torture_tcase_set_fixture(tcase,
876                                   torture_rpc_spoolss_access_priv_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, "normaluser_sd");
882
883         torture_tcase_set_fixture(tcase,
884                                   torture_rpc_spoolss_access_sd_setup,
885                                   torture_rpc_spoolss_access_teardown);
886
887         torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
888
889         rpc_tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "workstation",
890                                                                           &ndr_table_spoolss,
891                                                                           TORTURE_WORKSTATION);
892
893         torture_rpc_tcase_add_test(rpc_tcase, "openprinter", test_openprinter_wrap);
894
895         return suite;
896 }