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 2354 : struct torture_suite *torture_rpc_spoolss_access(TALLOC_CTX *mem_ctx)
853 : {
854 2354 : 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 2354 : tcase = torture_suite_add_tcase(suite, "normaluser");
859 :
860 2354 : torture_tcase_set_fixture(tcase,
861 : torture_rpc_spoolss_access_setup,
862 : torture_rpc_spoolss_access_teardown);
863 :
864 2354 : torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
865 :
866 2354 : tcase = torture_suite_add_tcase(suite, "adminuser");
867 :
868 2354 : torture_tcase_set_fixture(tcase,
869 : torture_rpc_spoolss_access_admin_setup,
870 : torture_rpc_spoolss_access_teardown);
871 :
872 2354 : torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
873 :
874 2354 : tcase = torture_suite_add_tcase(suite, "printopuser");
875 :
876 2354 : torture_tcase_set_fixture(tcase,
877 : torture_rpc_spoolss_access_printop_setup,
878 : torture_rpc_spoolss_access_teardown);
879 :
880 2354 : torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
881 :
882 2354 : tcase = torture_suite_add_tcase(suite, "printopuserpriv");
883 :
884 2354 : torture_tcase_set_fixture(tcase,
885 : torture_rpc_spoolss_access_priv_setup,
886 : torture_rpc_spoolss_access_teardown);
887 :
888 2354 : torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
889 :
890 2354 : tcase = torture_suite_add_tcase(suite, "normaluser_sd");
891 :
892 2354 : torture_tcase_set_fixture(tcase,
893 : torture_rpc_spoolss_access_sd_setup,
894 : torture_rpc_spoolss_access_teardown);
895 :
896 2354 : torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter);
897 :
898 2354 : rpc_tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "workstation",
899 : &ndr_table_spoolss,
900 : TORTURE_WORKSTATION);
901 :
902 2354 : torture_rpc_tcase_add_test(rpc_tcase, "openprinter", test_openprinter_wrap);
903 :
904 2354 : return suite;
905 : }
|