2 Unix SMB/CIFS implementation.
3 test suite for spoolss rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Stefan Metzmacher 2005
7 Copyright (C) Jelmer Vernooij 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "torture/torture.h"
25 #include "torture/rpc/rpc.h"
26 #include "librpc/gen_ndr/ndr_spoolss_c.h"
28 struct test_spoolss_context
{
29 /* print server handle */
30 struct policy_handle server_handle
;
33 uint32_t port_count
[3];
34 union spoolss_PortInfo
*ports
[3];
36 /* for EnumPrinterDrivers */
37 uint32_t driver_count
[7];
38 union spoolss_DriverInfo
*drivers
[7];
40 /* for EnumMonitors */
41 uint32_t monitor_count
[3];
42 union spoolss_MonitorInfo
*monitors
[3];
44 /* for EnumPrintProcessors */
45 uint32_t print_processor_count
[2];
46 union spoolss_PrintProcessorInfo
*print_processors
[2];
48 /* for EnumPrinters */
49 uint32_t printer_count
[6];
50 union spoolss_PrinterInfo
*printers
[6];
53 #define COMPARE_STRING(tctx, c,r,e) \
54 torture_assert_str_equal(tctx, c.e, r.e, "invalid value")
56 /* not every compiler supports __typeof__() */
58 #define _CHECK_FIELD_SIZE(c,r,e,type) do {\
59 if (sizeof(__typeof__(c.e)) != sizeof(type)) { \
60 torture_fail(tctx, #c "." #e "field is not " #type "\n"); \
62 if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
63 torture_fail(tctx, #r "." #e "field is not " #type "\n"); \
67 #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
70 #define COMPARE_UINT32(tctx, c, r, e) do {\
71 _CHECK_FIELD_SIZE(c, r, e, uint32_t); \
72 torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
75 #define COMPARE_STRING_ARRAY(tctx, c,r,e)
77 static bool test_OpenPrinter_server(struct torture_context
*tctx
, struct dcerpc_pipe
*p
, struct test_spoolss_context
*ctx
)
80 struct spoolss_OpenPrinter op
;
82 op
.in
.printername
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
));
83 op
.in
.datatype
= NULL
;
84 op
.in
.devmode_ctr
.devmode
= NULL
;
85 op
.in
.access_mask
= 0;
86 op
.out
.handle
= &ctx
->server_handle
;
88 torture_comment(tctx
, "Testing OpenPrinter(%s)\n", op
.in
.printername
);
90 status
= dcerpc_spoolss_OpenPrinter(p
, ctx
, &op
);
91 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_OpenPrinter failed");
92 torture_assert_werr_ok(tctx
, op
.out
.result
, "dcerpc_spoolss_OpenPrinter failed");
97 static bool test_EnumPorts(struct torture_context
*tctx
,
98 struct dcerpc_pipe
*p
,
99 struct test_spoolss_context
*ctx
)
102 struct spoolss_EnumPorts r
;
103 uint16_t levels
[] = { 1, 2 };
106 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
107 int level
= levels
[i
];
111 union spoolss_PortInfo
*info
;
113 r
.in
.servername
= "";
117 r
.out
.needed
= &needed
;
118 r
.out
.count
= &count
;
121 torture_comment(tctx
, "Testing EnumPorts level %u\n", r
.in
.level
);
123 status
= dcerpc_spoolss_EnumPorts(p
, ctx
, &r
);
124 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPorts failed");
125 if (W_ERROR_IS_OK(r
.out
.result
)) {
126 /* TODO: do some more checks here */
129 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
130 "EnumPorts unexpected return code");
132 blob
= data_blob_talloc(ctx
, NULL
, needed
);
133 data_blob_clear(&blob
);
135 r
.in
.offered
= needed
;
137 status
= dcerpc_spoolss_EnumPorts(p
, ctx
, &r
);
138 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPorts failed");
140 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPorts failed");
142 torture_assert(tctx
, info
, "EnumPorts returned no info");
144 ctx
->port_count
[level
] = count
;
145 ctx
->ports
[level
] = info
;
148 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
149 int level
= levels
[i
];
150 int old_level
= levels
[i
-1];
151 torture_assert_int_equal(tctx
, ctx
->port_count
[level
], ctx
->port_count
[old_level
],
152 "EnumPorts invalid value");
154 /* if the array sizes are not the same we would maybe segfault in the following code */
156 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
157 int level
= levels
[i
];
158 for (j
=0;j
<ctx
->port_count
[level
];j
++) {
159 union spoolss_PortInfo
*cur
= &ctx
->ports
[level
][j
];
160 union spoolss_PortInfo
*ref
= &ctx
->ports
[2][j
];
163 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, port_name
);
166 /* level 2 is our reference, and it makes no sense to compare it to itself */
175 static bool test_GetPrintProcessorDirectory(struct torture_context
*tctx
,
176 struct dcerpc_pipe
*p
,
177 struct test_spoolss_context
*ctx
)
180 struct spoolss_GetPrintProcessorDirectory r
;
195 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
198 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
204 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
205 int level
= levels
[i
].level
;
208 r
.in
.server
= levels
[i
].server
;
209 r
.in
.environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
213 r
.out
.needed
= &needed
;
215 torture_comment(tctx
, "Testing GetPrintProcessorDirectory level %u\n", r
.in
.level
);
217 status
= dcerpc_spoolss_GetPrintProcessorDirectory(p
, ctx
, &r
);
218 torture_assert_ntstatus_ok(tctx
, status
,
219 "dcerpc_spoolss_GetPrintProcessorDirectory failed");
220 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
221 "GetPrintProcessorDirectory unexpected return code");
223 blob
= data_blob_talloc(ctx
, NULL
, needed
);
224 data_blob_clear(&blob
);
226 r
.in
.offered
= needed
;
228 status
= dcerpc_spoolss_GetPrintProcessorDirectory(p
, ctx
, &r
);
229 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
231 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrintProcessorDirectory failed");
238 static bool test_GetPrinterDriverDirectory(struct torture_context
*tctx
,
239 struct dcerpc_pipe
*p
,
240 struct test_spoolss_context
*ctx
)
243 struct spoolss_GetPrinterDriverDirectory r
;
258 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
261 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
267 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
268 int level
= levels
[i
].level
;
271 r
.in
.server
= levels
[i
].server
;
272 r
.in
.environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
276 r
.out
.needed
= &needed
;
278 torture_comment(tctx
, "Testing GetPrinterDriverDirectory level %u\n", r
.in
.level
);
280 status
= dcerpc_spoolss_GetPrinterDriverDirectory(p
, ctx
, &r
);
281 torture_assert_ntstatus_ok(tctx
, status
,
282 "dcerpc_spoolss_GetPrinterDriverDirectory failed");
283 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
284 "GetPrinterDriverDirectory unexpected return code");
286 blob
= data_blob_talloc(ctx
, NULL
, needed
);
287 data_blob_clear(&blob
);
289 r
.in
.offered
= needed
;
291 status
= dcerpc_spoolss_GetPrinterDriverDirectory(p
, ctx
, &r
);
292 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
294 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinterDriverDirectory failed");
300 static bool test_EnumPrinterDrivers(struct torture_context
*tctx
,
301 struct dcerpc_pipe
*p
,
302 struct test_spoolss_context
*ctx
)
305 struct spoolss_EnumPrinterDrivers r
;
306 uint16_t levels
[] = { 1, 2, 3, 4, 5, 6 };
309 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
310 int level
= levels
[i
];
314 union spoolss_DriverInfo
*info
;
317 r
.in
.environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
321 r
.out
.needed
= &needed
;
322 r
.out
.count
= &count
;
325 torture_comment(tctx
, "Testing EnumPrinterDrivers level %u\n", r
.in
.level
);
327 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, ctx
, &r
);
328 torture_assert_ntstatus_ok(tctx
, status
,
329 "dcerpc_spoolss_EnumPrinterDrivers failed");
330 if (W_ERROR_IS_OK(r
.out
.result
)) {
331 /* TODO: do some more checks here */
334 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
335 "EnumPrinterDrivers failed");
337 blob
= data_blob_talloc(ctx
, NULL
, needed
);
338 data_blob_clear(&blob
);
340 r
.in
.offered
= needed
;
342 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, ctx
, &r
);
343 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinterDrivers failed");
345 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinterDrivers failed");
347 ctx
->driver_count
[level
] = count
;
348 ctx
->drivers
[level
] = info
;
351 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
352 int level
= levels
[i
];
353 int old_level
= levels
[i
-1];
354 torture_assert_int_equal(tctx
, ctx
->driver_count
[level
], ctx
->driver_count
[old_level
],
355 "EnumPrinterDrivers invalid value");
358 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
359 int level
= levels
[i
];
360 for (j
=0;j
<ctx
->driver_count
[level
];j
++) {
361 union spoolss_DriverInfo
*cur
= &ctx
->drivers
[level
][j
];
362 union spoolss_DriverInfo
*ref
= &ctx
->drivers
[6][j
];
365 COMPARE_STRING(tctx
, cur
->info1
, ref
->info6
, driver_name
);
368 COMPARE_UINT32(tctx
, cur
->info2
, ref
->info6
, version
);
369 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, driver_name
);
370 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, architecture
);
371 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, driver_path
);
372 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, data_file
);
373 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, config_file
);
376 COMPARE_UINT32(tctx
, cur
->info3
, ref
->info6
, version
);
377 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, driver_name
);
378 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, architecture
);
379 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, driver_path
);
380 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, data_file
);
381 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, config_file
);
382 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, help_file
);
383 COMPARE_STRING_ARRAY(tctx
, cur
->info3
, ref
->info6
, dependent_files
);
384 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, monitor_name
);
385 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, default_datatype
);
388 COMPARE_UINT32(tctx
, cur
->info4
, ref
->info6
, version
);
389 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, driver_name
);
390 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, architecture
);
391 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, driver_path
);
392 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, data_file
);
393 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, config_file
);
394 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, help_file
);
395 COMPARE_STRING_ARRAY(tctx
, cur
->info4
, ref
->info6
, dependent_files
);
396 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, monitor_name
);
397 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, default_datatype
);
398 COMPARE_STRING_ARRAY(tctx
, cur
->info4
, ref
->info6
, previous_names
);
401 COMPARE_UINT32(tctx
, cur
->info5
, ref
->info6
, version
);
402 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, driver_name
);
403 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, architecture
);
404 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, driver_path
);
405 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, data_file
);
406 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, config_file
);
407 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_attributes);*/
408 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, config_version);*/
409 /*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_version); */
412 /* level 6 is our reference, and it makes no sense to compare it to itself */
421 static bool test_EnumMonitors(struct torture_context
*tctx
,
422 struct dcerpc_pipe
*p
,
423 struct test_spoolss_context
*ctx
)
426 struct spoolss_EnumMonitors r
;
427 uint16_t levels
[] = { 1, 2 };
430 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
431 int level
= levels
[i
];
435 union spoolss_MonitorInfo
*info
;
437 r
.in
.servername
= "";
441 r
.out
.needed
= &needed
;
442 r
.out
.count
= &count
;
445 torture_comment(tctx
, "Testing EnumMonitors level %u\n", r
.in
.level
);
447 status
= dcerpc_spoolss_EnumMonitors(p
, ctx
, &r
);
448 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumMonitors failed");
449 if (W_ERROR_IS_OK(r
.out
.result
)) {
450 /* TODO: do some more checks here */
453 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
454 "EnumMonitors failed");
456 blob
= data_blob_talloc(ctx
, NULL
, needed
);
457 data_blob_clear(&blob
);
459 r
.in
.offered
= needed
;
461 status
= dcerpc_spoolss_EnumMonitors(p
, ctx
, &r
);
462 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumMonitors failed");
464 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumMonitors failed");
466 ctx
->monitor_count
[level
] = count
;
467 ctx
->monitors
[level
] = info
;
470 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
471 int level
= levels
[i
];
472 int old_level
= levels
[i
-1];
473 torture_assert_int_equal(tctx
, ctx
->monitor_count
[level
], ctx
->monitor_count
[old_level
],
474 "EnumMonitors invalid value");
477 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
478 int level
= levels
[i
];
479 for (j
=0;j
<ctx
->monitor_count
[level
];j
++) {
480 union spoolss_MonitorInfo
*cur
= &ctx
->monitors
[level
][j
];
481 union spoolss_MonitorInfo
*ref
= &ctx
->monitors
[2][j
];
484 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, monitor_name
);
487 /* level 2 is our reference, and it makes no sense to compare it to itself */
496 static bool test_EnumPrintProcessors(struct torture_context
*tctx
,
497 struct dcerpc_pipe
*p
,
498 struct test_spoolss_context
*ctx
)
501 struct spoolss_EnumPrintProcessors r
;
502 uint16_t levels
[] = { 1 };
505 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
506 int level
= levels
[i
];
510 union spoolss_PrintProcessorInfo
*info
;
512 r
.in
.servername
= "";
513 r
.in
.environment
= "Windows NT x86";
517 r
.out
.needed
= &needed
;
518 r
.out
.count
= &count
;
521 torture_comment(tctx
, "Testing EnumPrintProcessors level %u\n", r
.in
.level
);
523 status
= dcerpc_spoolss_EnumPrintProcessors(p
, ctx
, &r
);
524 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcessors failed");
525 if (W_ERROR_IS_OK(r
.out
.result
)) {
526 /* TODO: do some more checks here */
529 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
530 "EnumPrintProcessors unexpected return code");
532 blob
= data_blob_talloc(ctx
, NULL
, needed
);
533 data_blob_clear(&blob
);
535 r
.in
.offered
= needed
;
537 status
= dcerpc_spoolss_EnumPrintProcessors(p
, ctx
, &r
);
538 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcessors failed");
540 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrintProcessors failed");
542 ctx
->print_processor_count
[level
] = count
;
543 ctx
->print_processors
[level
] = info
;
546 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
547 int level
= levels
[i
];
548 int old_level
= levels
[i
-1];
549 torture_assert_int_equal(tctx
, ctx
->print_processor_count
[level
], ctx
->print_processor_count
[old_level
],
550 "EnumPrintProcessors failed");
553 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
554 int level
= levels
[i
];
555 for (j
=0;j
<ctx
->print_processor_count
[level
];j
++) {
557 union spoolss_PrintProcessorInfo
*cur
= &ctx
->print_processors
[level
][j
];
558 union spoolss_PrintProcessorInfo
*ref
= &ctx
->print_processors
[1][j
];
562 /* level 1 is our reference, and it makes no sense to compare it to itself */
571 static bool test_EnumPrintProcDataTypes(struct torture_context
*tctx
,
572 struct dcerpc_pipe
*p
,
573 struct test_spoolss_context
*ctx
)
576 struct spoolss_EnumPrintProcDataTypes r
;
577 uint16_t levels
[] = { 1 };
580 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
581 int level
= levels
[i
];
585 union spoolss_PrintProcDataTypesInfo
*info
;
587 r
.in
.servername
= "";
588 r
.in
.print_processor_name
= "winprint";
592 r
.out
.needed
= &needed
;
593 r
.out
.count
= &count
;
596 torture_comment(tctx
, "Testing EnumPrintProcDataTypes level %u\n", r
.in
.level
);
598 status
= dcerpc_spoolss_EnumPrintProcDataTypes(p
, ctx
, &r
);
599 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcDataType failed");
600 if (W_ERROR_IS_OK(r
.out
.result
)) {
601 /* TODO: do some more checks here */
604 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
605 "EnumPrintProcDataTypes unexpected return code");
607 blob
= data_blob_talloc(ctx
, NULL
, needed
);
608 data_blob_clear(&blob
);
610 r
.in
.offered
= needed
;
612 status
= dcerpc_spoolss_EnumPrintProcDataTypes(p
, ctx
, &r
);
613 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcDataTypes failed");
615 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrintProcDataTypes failed");
622 static bool test_EnumPrinters(struct torture_context
*tctx
,
623 struct dcerpc_pipe
*p
,
624 struct test_spoolss_context
*ctx
)
626 struct spoolss_EnumPrinters r
;
628 uint16_t levels
[] = { 0, 1, 2, 4, 5 };
631 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
632 int level
= levels
[i
];
636 union spoolss_PrinterInfo
*info
;
638 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
643 r
.out
.needed
= &needed
;
644 r
.out
.count
= &count
;
647 torture_comment(tctx
, "Testing EnumPrinters level %u\n", r
.in
.level
);
649 status
= dcerpc_spoolss_EnumPrinters(p
, ctx
, &r
);
650 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinters failed");
651 if (W_ERROR_IS_OK(r
.out
.result
)) {
652 /* TODO: do some more checks here */
655 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
656 "EnumPrinters unexpected return code");
658 blob
= data_blob_talloc(ctx
, NULL
, needed
);
659 data_blob_clear(&blob
);
661 r
.in
.offered
= needed
;
663 status
= dcerpc_spoolss_EnumPrinters(p
, ctx
, &r
);
664 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinters failed");
666 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinters failed");
668 ctx
->printer_count
[level
] = count
;
669 ctx
->printers
[level
] = info
;
672 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
673 int level
= levels
[i
];
674 int old_level
= levels
[i
-1];
675 torture_assert_int_equal(tctx
, ctx
->printer_count
[level
], ctx
->printer_count
[old_level
],
676 "EnumPrinters invalid value");
679 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
680 int level
= levels
[i
];
681 for (j
=0;j
<ctx
->printer_count
[level
];j
++) {
682 union spoolss_PrinterInfo
*cur
= &ctx
->printers
[level
][j
];
683 union spoolss_PrinterInfo
*ref
= &ctx
->printers
[2][j
];
686 COMPARE_STRING(tctx
, cur
->info0
, ref
->info2
, printername
);
687 COMPARE_STRING(tctx
, cur
->info0
, ref
->info2
, servername
);
688 COMPARE_UINT32(tctx
, cur
->info0
, ref
->info2
, cjobs
);
689 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs);
690 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_bytes);
691 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
692 COMPARE_UINT32(tctx, cur->info0, ref->info2, global_counter);
693 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_pages);
694 COMPARE_UINT32(tctx, cur->info0, ref->info2, version);
695 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown10);
696 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown11);
697 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown12);
698 COMPARE_UINT32(tctx, cur->info0, ref->info2, session_counter);
699 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown14);
700 COMPARE_UINT32(tctx, cur->info0, ref->info2, printer_errors);
701 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown16);
702 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown17);
703 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown18);
704 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown19);
705 COMPARE_UINT32(tctx, cur->info0, ref->info2, change_id);
706 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown21);*/
707 COMPARE_UINT32(tctx
, cur
->info0
, ref
->info2
, status
);
708 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23);
709 COMPARE_UINT32(tctx, cur->info0, ref->info2, c_setprinter);
710 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
711 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
712 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown27);
713 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown28);
714 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown29);*/
717 /*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/
718 /*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/
719 /*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/
720 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, comment
);
723 /* level 2 is our reference, and it makes no sense to compare it to itself */
726 COMPARE_STRING(tctx
, cur
->info4
, ref
->info2
, printername
);
727 COMPARE_STRING(tctx
, cur
->info4
, ref
->info2
, servername
);
728 COMPARE_UINT32(tctx
, cur
->info4
, ref
->info2
, attributes
);
731 COMPARE_STRING(tctx
, cur
->info5
, ref
->info2
, printername
);
732 COMPARE_STRING(tctx
, cur
->info5
, ref
->info2
, portname
);
733 COMPARE_UINT32(tctx
, cur
->info5
, ref
->info2
, attributes
);
734 /*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout);
735 COMPARE_UINT32(tctx, cur->info5, ref->info2, transmission_retry_timeout);*/
742 * - verify that the port of a printer was in the list returned by EnumPorts
748 static bool test_GetPrinter(struct torture_context
*tctx
,
749 struct dcerpc_pipe
*p
,
750 struct policy_handle
*handle
)
753 struct spoolss_GetPrinter r
;
754 uint16_t levels
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
758 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
759 r
.in
.handle
= handle
;
760 r
.in
.level
= levels
[i
];
763 r
.out
.needed
= &needed
;
765 torture_comment(tctx
, "Testing GetPrinter level %u\n", r
.in
.level
);
767 status
= dcerpc_spoolss_GetPrinter(p
, tctx
, &r
);
768 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinter failed");
770 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
771 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
772 data_blob_clear(&blob
);
774 r
.in
.offered
= needed
;
775 status
= dcerpc_spoolss_GetPrinter(p
, tctx
, &r
);
778 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinter failed");
780 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinter failed");
787 static bool test_ClosePrinter(struct torture_context
*tctx
,
788 struct dcerpc_pipe
*p
,
789 struct policy_handle
*handle
)
792 struct spoolss_ClosePrinter r
;
794 r
.in
.handle
= handle
;
795 r
.out
.handle
= handle
;
797 torture_comment(tctx
, "Testing ClosePrinter\n");
799 status
= dcerpc_spoolss_ClosePrinter(p
, tctx
, &r
);
800 torture_assert_ntstatus_ok(tctx
, status
, "ClosePrinter failed");
805 static bool test_GetForm(struct torture_context
*tctx
,
806 struct dcerpc_pipe
*p
,
807 struct policy_handle
*handle
,
808 const char *form_name
,
812 struct spoolss_GetForm r
;
815 r
.in
.handle
= handle
;
816 r
.in
.form_name
= form_name
;
820 r
.out
.needed
= &needed
;
822 torture_comment(tctx
, "Testing GetForm level %d\n", r
.in
.level
);
824 status
= dcerpc_spoolss_GetForm(p
, tctx
, &r
);
825 torture_assert_ntstatus_ok(tctx
, status
, "GetForm failed");
827 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
828 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
829 data_blob_clear(&blob
);
831 r
.in
.offered
= needed
;
832 status
= dcerpc_spoolss_GetForm(p
, tctx
, &r
);
833 torture_assert_ntstatus_ok(tctx
, status
, "GetForm failed");
835 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetForm failed");
837 torture_assert(tctx
, r
.out
.info
, "No form info returned");
840 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetForm failed");
845 static bool test_EnumForms(struct torture_context
*tctx
,
846 struct dcerpc_pipe
*p
,
847 struct policy_handle
*handle
, bool print_server
)
850 struct spoolss_EnumForms r
;
854 uint32_t levels
[] = { 1, 2 };
857 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
859 union spoolss_FormInfo
*info
;
861 r
.in
.handle
= handle
;
862 r
.in
.level
= levels
[i
];
865 r
.out
.needed
= &needed
;
866 r
.out
.count
= &count
;
869 torture_comment(tctx
, "Testing EnumForms level %d\n", levels
[i
]);
871 status
= dcerpc_spoolss_EnumForms(p
, tctx
, &r
);
872 torture_assert_ntstatus_ok(tctx
, status
, "EnumForms failed");
874 if ((r
.in
.level
== 2) && (W_ERROR_EQUAL(r
.out
.result
, WERR_UNKNOWN_LEVEL
))) {
878 if (print_server
&& W_ERROR_EQUAL(r
.out
.result
, WERR_BADFID
))
879 torture_fail(tctx
, "EnumForms on the PrintServer isn't supported by test server (NT4)");
881 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
883 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
884 data_blob_clear(&blob
);
886 r
.in
.offered
= needed
;
888 status
= dcerpc_spoolss_EnumForms(p
, tctx
, &r
);
890 torture_assert(tctx
, info
, "No forms returned");
892 for (j
= 0; j
< count
; j
++) {
894 ret
&= test_GetForm(tctx
, p
, handle
, info
[j
].info1
.form_name
, levels
[i
]);
898 torture_assert_ntstatus_ok(tctx
, status
, "EnumForms failed");
900 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumForms failed");
906 static bool test_DeleteForm(struct torture_context
*tctx
,
907 struct dcerpc_pipe
*p
,
908 struct policy_handle
*handle
,
909 const char *form_name
)
912 struct spoolss_DeleteForm r
;
914 r
.in
.handle
= handle
;
915 r
.in
.form_name
= form_name
;
917 status
= dcerpc_spoolss_DeleteForm(p
, tctx
, &r
);
919 torture_assert_ntstatus_ok(tctx
, status
, "DeleteForm failed");
921 torture_assert_werr_ok(tctx
, r
.out
.result
, "DeleteForm failed");
926 static bool test_AddForm(struct torture_context
*tctx
,
927 struct dcerpc_pipe
*p
,
928 struct policy_handle
*handle
, bool print_server
)
930 struct spoolss_AddForm r
;
931 struct spoolss_AddFormInfo1 addform
;
932 const char *form_name
= "testform3";
936 r
.in
.handle
= handle
;
938 r
.in
.info
.info1
= &addform
;
939 addform
.flags
= SPOOLSS_FORM_USER
;
940 addform
.form_name
= form_name
;
941 addform
.size
.width
= 50;
942 addform
.size
.height
= 25;
943 addform
.area
.left
= 5;
944 addform
.area
.top
= 10;
945 addform
.area
.right
= 45;
946 addform
.area
.bottom
= 15;
948 status
= dcerpc_spoolss_AddForm(p
, tctx
, &r
);
950 torture_assert_ntstatus_ok(tctx
, status
, "AddForm failed");
952 torture_assert_werr_ok(tctx
, r
.out
.result
, "AddForm failed");
954 if (!print_server
) ret
&= test_GetForm(tctx
, p
, handle
, form_name
, 1);
957 struct spoolss_SetForm sf
;
958 struct spoolss_AddFormInfo1 setform
;
960 sf
.in
.handle
= handle
;
961 sf
.in
.form_name
= form_name
;
963 sf
.in
.info
.info1
= &setform
;
964 setform
.flags
= addform
.flags
;
965 setform
.form_name
= addform
.form_name
;
966 setform
.size
= addform
.size
;
967 setform
.area
= addform
.area
;
969 setform
.size
.width
= 1234;
971 status
= dcerpc_spoolss_SetForm(p
, tctx
, &sf
);
973 torture_assert_ntstatus_ok(tctx
, status
, "SetForm failed");
975 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetForm failed");
978 if (!print_server
) ret
&= test_GetForm(tctx
, p
, handle
, form_name
, 1);
980 if (!test_DeleteForm(tctx
, p
, handle
, form_name
)) {
987 static bool test_EnumPorts_old(struct torture_context
*tctx
,
988 struct dcerpc_pipe
*p
)
991 struct spoolss_EnumPorts r
;
994 union spoolss_PortInfo
*info
;
996 r
.in
.servername
= talloc_asprintf(tctx
, "\\\\%s",
997 dcerpc_server_name(p
));
1001 r
.out
.needed
= &needed
;
1002 r
.out
.count
= &count
;
1005 torture_comment(tctx
, "Testing EnumPorts\n");
1007 status
= dcerpc_spoolss_EnumPorts(p
, tctx
, &r
);
1009 torture_assert_ntstatus_ok(tctx
, status
, "EnumPorts failed");
1011 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1012 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1013 data_blob_clear(&blob
);
1014 r
.in
.buffer
= &blob
;
1015 r
.in
.offered
= needed
;
1017 status
= dcerpc_spoolss_EnumPorts(p
, tctx
, &r
);
1018 torture_assert_ntstatus_ok(tctx
, status
, "EnumPorts failed");
1020 torture_assert(tctx
, info
, "No ports returned");
1026 static bool test_AddPort(struct torture_context
*tctx
,
1027 struct dcerpc_pipe
*p
)
1030 struct spoolss_AddPort r
;
1032 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s",
1033 dcerpc_server_name(p
));
1035 r
.in
.monitor_name
= "foo";
1037 torture_comment(tctx
, "Testing AddPort\n");
1039 status
= dcerpc_spoolss_AddPort(p
, tctx
, &r
);
1041 torture_assert_ntstatus_ok(tctx
, status
, "AddPort failed");
1043 /* win2k3 returns WERR_NOT_SUPPORTED */
1047 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1048 printf("AddPort failed - %s\n", win_errstr(r
.out
.result
));
1057 static bool test_GetJob(struct torture_context
*tctx
,
1058 struct dcerpc_pipe
*p
,
1059 struct policy_handle
*handle
, uint32_t job_id
)
1062 struct spoolss_GetJob r
;
1065 r
.in
.handle
= handle
;
1066 r
.in
.job_id
= job_id
;
1070 r
.out
.needed
= &needed
;
1072 torture_comment(tctx
, "Testing GetJob\n");
1074 status
= dcerpc_spoolss_GetJob(p
, tctx
, &r
);
1075 torture_assert_ntstatus_ok(tctx
, status
, "GetJob failed");
1077 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1078 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1079 data_blob_clear(&blob
);
1080 r
.in
.buffer
= &blob
;
1081 r
.in
.offered
= needed
;
1083 status
= dcerpc_spoolss_GetJob(p
, tctx
, &r
);
1085 torture_assert(tctx
, r
.out
.info
, "No job info returned");
1091 static bool test_SetJob(struct torture_context
*tctx
,
1092 struct dcerpc_pipe
*p
,
1093 struct policy_handle
*handle
, uint32_t job_id
,
1094 enum spoolss_JobControl command
)
1097 struct spoolss_SetJob r
;
1099 r
.in
.handle
= handle
;
1100 r
.in
.job_id
= job_id
;
1102 r
.in
.command
= command
;
1104 torture_comment(tctx
, "Testing SetJob\n");
1106 status
= dcerpc_spoolss_SetJob(p
, tctx
, &r
);
1107 torture_assert_ntstatus_ok(tctx
, status
, "SetJob failed");
1108 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetJob failed");
1113 static bool test_AddJob(struct torture_context
*tctx
,
1114 struct dcerpc_pipe
*p
,
1115 struct policy_handle
*handle
)
1118 struct spoolss_AddJob r
;
1122 r
.in
.handle
= handle
;
1124 r
.out
.needed
= &needed
;
1126 torture_comment(tctx
, "Testing AddJob\n");
1128 status
= dcerpc_spoolss_AddJob(p
, tctx
, &r
);
1129 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
, "AddJob failed");
1133 status
= dcerpc_spoolss_AddJob(p
, tctx
, &r
);
1134 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
, "AddJob failed");
1140 static bool test_EnumJobs(struct torture_context
*tctx
,
1141 struct dcerpc_pipe
*p
,
1142 struct policy_handle
*handle
)
1145 struct spoolss_EnumJobs r
;
1148 union spoolss_JobInfo
*info
;
1150 r
.in
.handle
= handle
;
1152 r
.in
.numjobs
= 0xffffffff;
1156 r
.out
.needed
= &needed
;
1157 r
.out
.count
= &count
;
1160 torture_comment(tctx
, "Testing EnumJobs\n");
1162 status
= dcerpc_spoolss_EnumJobs(p
, tctx
, &r
);
1164 torture_assert_ntstatus_ok(tctx
, status
, "EnumJobs failed");
1166 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1168 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1169 data_blob_clear(&blob
);
1170 r
.in
.buffer
= &blob
;
1171 r
.in
.offered
= needed
;
1173 status
= dcerpc_spoolss_EnumJobs(p
, tctx
, &r
);
1175 torture_assert(tctx
, info
, "No jobs returned");
1177 for (j
= 0; j
< count
; j
++) {
1179 test_GetJob(tctx
, p
, handle
, info
[j
].info1
.job_id
);
1180 test_SetJob(tctx
, p
, handle
, info
[j
].info1
.job_id
, SPOOLSS_JOB_CONTROL_PAUSE
);
1181 test_SetJob(tctx
, p
, handle
, info
[j
].info1
.job_id
, SPOOLSS_JOB_CONTROL_RESUME
);
1185 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumJobs failed");
1191 static bool test_DoPrintTest(struct torture_context
*tctx
,
1192 struct dcerpc_pipe
*p
,
1193 struct policy_handle
*handle
)
1197 struct spoolss_StartDocPrinter s
;
1198 struct spoolss_DocumentInfo1 info1
;
1199 struct spoolss_StartPagePrinter sp
;
1200 struct spoolss_WritePrinter w
;
1201 struct spoolss_EndPagePrinter ep
;
1202 struct spoolss_EndDocPrinter e
;
1205 uint32_t num_written
;
1207 torture_comment(tctx
, "Testing StartDocPrinter\n");
1209 s
.in
.handle
= handle
;
1211 s
.in
.info
.info1
= &info1
;
1212 s
.out
.job_id
= &job_id
;
1213 info1
.document_name
= "TorturePrintJob";
1214 info1
.output_file
= NULL
;
1215 info1
.datatype
= "RAW";
1217 status
= dcerpc_spoolss_StartDocPrinter(p
, tctx
, &s
);
1218 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_StartDocPrinter failed");
1219 torture_assert_werr_ok(tctx
, s
.out
.result
, "StartDocPrinter failed");
1221 for (i
=1; i
< 4; i
++) {
1222 torture_comment(tctx
, "Testing StartPagePrinter: Page[%d]\n", i
);
1224 sp
.in
.handle
= handle
;
1226 status
= dcerpc_spoolss_StartPagePrinter(p
, tctx
, &sp
);
1227 torture_assert_ntstatus_ok(tctx
, status
,
1228 "dcerpc_spoolss_StartPagePrinter failed");
1229 torture_assert_werr_ok(tctx
, sp
.out
.result
, "StartPagePrinter failed");
1231 torture_comment(tctx
, "Testing WritePrinter: Page[%d]\n", i
);
1233 w
.in
.handle
= handle
;
1234 w
.in
.data
= data_blob_string_const(talloc_asprintf(tctx
,"TortureTestPage: %d\nData\n",i
));
1235 w
.out
.num_written
= &num_written
;
1237 status
= dcerpc_spoolss_WritePrinter(p
, tctx
, &w
);
1238 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_WritePrinter failed");
1239 torture_assert_werr_ok(tctx
, w
.out
.result
, "WritePrinter failed");
1241 torture_comment(tctx
, "Testing EndPagePrinter: Page[%d]\n", i
);
1243 ep
.in
.handle
= handle
;
1245 status
= dcerpc_spoolss_EndPagePrinter(p
, tctx
, &ep
);
1246 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EndPagePrinter failed");
1247 torture_assert_werr_ok(tctx
, ep
.out
.result
, "EndPagePrinter failed");
1250 torture_comment(tctx
, "Testing EndDocPrinter\n");
1252 e
.in
.handle
= handle
;
1254 status
= dcerpc_spoolss_EndDocPrinter(p
, tctx
, &e
);
1255 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EndDocPrinter failed");
1256 torture_assert_werr_ok(tctx
, e
.out
.result
, "EndDocPrinter failed");
1258 ret
&= test_AddJob(tctx
, p
, handle
);
1259 ret
&= test_EnumJobs(tctx
, p
, handle
);
1261 ret
&= test_SetJob(tctx
, p
, handle
, job_id
, SPOOLSS_JOB_CONTROL_DELETE
);
1266 static bool test_PausePrinter(struct torture_context
*tctx
,
1267 struct dcerpc_pipe
*p
,
1268 struct policy_handle
*handle
)
1271 struct spoolss_SetPrinter r
;
1272 struct spoolss_SetPrinterInfoCtr info_ctr
;
1273 struct spoolss_DevmodeContainer devmode_ctr
;
1274 struct sec_desc_buf secdesc_ctr
;
1277 info_ctr
.info
.info0
= NULL
;
1279 ZERO_STRUCT(devmode_ctr
);
1280 ZERO_STRUCT(secdesc_ctr
);
1282 r
.in
.handle
= handle
;
1283 r
.in
.info_ctr
= &info_ctr
;
1284 r
.in
.devmode_ctr
= &devmode_ctr
;
1285 r
.in
.secdesc_ctr
= &secdesc_ctr
;
1286 r
.in
.command
= SPOOLSS_PRINTER_CONTROL_PAUSE
;
1288 torture_comment(tctx
, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1290 status
= dcerpc_spoolss_SetPrinter(p
, tctx
, &r
);
1292 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinter failed");
1294 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetPrinter failed");
1299 static bool test_ResumePrinter(struct torture_context
*tctx
,
1300 struct dcerpc_pipe
*p
,
1301 struct policy_handle
*handle
)
1304 struct spoolss_SetPrinter r
;
1305 struct spoolss_SetPrinterInfoCtr info_ctr
;
1306 struct spoolss_DevmodeContainer devmode_ctr
;
1307 struct sec_desc_buf secdesc_ctr
;
1310 info_ctr
.info
.info0
= NULL
;
1312 ZERO_STRUCT(devmode_ctr
);
1313 ZERO_STRUCT(secdesc_ctr
);
1315 r
.in
.handle
= handle
;
1316 r
.in
.info_ctr
= &info_ctr
;
1317 r
.in
.devmode_ctr
= &devmode_ctr
;
1318 r
.in
.secdesc_ctr
= &secdesc_ctr
;
1319 r
.in
.command
= SPOOLSS_PRINTER_CONTROL_RESUME
;
1321 torture_comment(tctx
, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1323 status
= dcerpc_spoolss_SetPrinter(p
, tctx
, &r
);
1325 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinter failed");
1327 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetPrinter failed");
1332 static bool test_GetPrinterData(struct torture_context
*tctx
,
1333 struct dcerpc_pipe
*p
,
1334 struct policy_handle
*handle
,
1335 const char *value_name
)
1338 struct spoolss_GetPrinterData r
;
1340 enum spoolss_PrinterDataType type
;
1342 r
.in
.handle
= handle
;
1343 r
.in
.value_name
= value_name
;
1345 r
.out
.needed
= &needed
;
1348 torture_comment(tctx
, "Testing GetPrinterData\n");
1350 status
= dcerpc_spoolss_GetPrinterData(p
, tctx
, &r
);
1351 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterData failed");
1353 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
1354 r
.in
.offered
= needed
;
1356 status
= dcerpc_spoolss_GetPrinterData(p
, tctx
, &r
);
1357 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterData failed");
1359 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinterData failed");
1365 static bool test_GetPrinterDataEx(struct torture_context
*tctx
,
1366 struct dcerpc_pipe
*p
,
1367 struct policy_handle
*handle
,
1368 const char *key_name
,
1369 const char *value_name
)
1372 struct spoolss_GetPrinterDataEx r
;
1376 r
.in
.handle
= handle
;
1377 r
.in
.key_name
= key_name
;
1378 r
.in
.value_name
= value_name
;
1381 r
.out
.needed
= &needed
;
1383 torture_comment(tctx
, "Testing GetPrinterDataEx\n");
1385 status
= dcerpc_spoolss_GetPrinterDataEx(p
, tctx
, &r
);
1386 if (!NT_STATUS_IS_OK(status
)) {
1387 if (NT_STATUS_EQUAL(status
,NT_STATUS_NET_WRITE_FAULT
) &&
1388 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
1389 torture_skip(tctx
, "GetPrinterDataEx not supported by server\n");
1391 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterDataEx failed");
1394 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
1395 r
.in
.offered
= needed
;
1396 r
.out
.buffer
= talloc_array(tctx
, uint8_t, needed
);
1398 status
= dcerpc_spoolss_GetPrinterDataEx(p
, tctx
, &r
);
1399 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterDataEx failed");
1401 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinterDataEx failed");
1407 static bool test_EnumPrinterData(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
1408 struct policy_handle
*handle
)
1411 struct spoolss_EnumPrinterData r
;
1414 r
.in
.handle
= handle
;
1415 r
.in
.enum_index
= 0;
1418 uint32_t value_size
= 0;
1419 uint32_t data_size
= 0;
1420 uint32_t printerdata_type
= 0;
1421 DATA_BLOB data
= data_blob(NULL
,0);
1423 r
.in
.value_offered
= value_size
;
1424 r
.out
.value_needed
= &value_size
;
1425 r
.in
.data_offered
= data_size
;
1426 r
.out
.data_needed
= &data_size
;
1428 r
.out
.printerdata_type
= &printerdata_type
;
1429 r
.out
.buffer
= &data
;
1431 torture_comment(tctx
, "Testing EnumPrinterData\n");
1433 status
= dcerpc_spoolss_EnumPrinterData(p
, tctx
, &r
);
1435 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterData failed");
1437 r
.in
.value_offered
= value_size
;
1438 r
.in
.data_offered
= data_size
;
1440 status
= dcerpc_spoolss_EnumPrinterData(p
, tctx
, &r
);
1442 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterData failed");
1444 test_GetPrinterData(tctx
, p
, handle
, r
.out
.value_name
);
1446 test_GetPrinterDataEx(tctx
,
1447 p
, handle
, "PrinterDriverData",
1452 } while (W_ERROR_IS_OK(r
.out
.result
));
1457 static bool test_EnumPrinterDataEx(struct torture_context
*tctx
,
1458 struct dcerpc_pipe
*p
,
1459 struct policy_handle
*handle
)
1462 struct spoolss_EnumPrinterDataEx r
;
1466 r
.in
.handle
= handle
;
1467 r
.in
.key_name
= "PrinterDriverData";
1469 r
.out
.needed
= &needed
;
1470 r
.out
.count
= &count
;
1472 torture_comment(tctx
, "Testing EnumPrinterDataEx\n");
1474 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, tctx
, &r
);
1475 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDataEx failed");
1477 r
.in
.offered
= needed
;
1478 r
.out
.buffer
= talloc_array(tctx
, uint8_t, needed
);
1480 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, tctx
, &r
);
1482 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDataEx failed");
1488 static bool test_DeletePrinterData(struct torture_context
*tctx
,
1489 struct dcerpc_pipe
*p
,
1490 struct policy_handle
*handle
,
1491 const char *value_name
)
1494 struct spoolss_DeletePrinterData r
;
1496 r
.in
.handle
= handle
;
1497 r
.in
.value_name
= value_name
;
1499 torture_comment(tctx
, "Testing DeletePrinterData\n");
1501 status
= dcerpc_spoolss_DeletePrinterData(p
, tctx
, &r
);
1503 torture_assert_ntstatus_ok(tctx
, status
, "DeletePrinterData failed");
1508 static bool test_SetPrinterData(struct torture_context
*tctx
,
1509 struct dcerpc_pipe
*p
,
1510 struct policy_handle
*handle
)
1513 struct spoolss_SetPrinterData r
;
1514 const char *value_name
= "spottyfoot";
1516 r
.in
.handle
= handle
;
1517 r
.in
.value_name
= value_name
;
1518 r
.in
.type
= SPOOLSS_PRINTER_DATA_TYPE_STRING
;
1519 r
.in
.data
.string
= "dog";
1521 torture_comment(tctx
, "Testing SetPrinterData\n");
1523 status
= dcerpc_spoolss_SetPrinterData(p
, tctx
, &r
);
1525 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinterData failed");
1527 if (!test_GetPrinterData(tctx
, p
, handle
, value_name
)) {
1531 if (!test_DeletePrinterData(tctx
, p
, handle
, value_name
)) {
1538 static bool test_SecondaryClosePrinter(struct torture_context
*tctx
,
1539 struct dcerpc_pipe
*p
,
1540 struct policy_handle
*handle
)
1543 struct dcerpc_binding
*b
;
1544 struct dcerpc_pipe
*p2
;
1545 struct spoolss_ClosePrinter cp
;
1547 /* only makes sense on SMB */
1548 if (p
->conn
->transport
.transport
!= NCACN_NP
) {
1552 torture_comment(tctx
, "testing close on secondary pipe\n");
1554 status
= dcerpc_parse_binding(tctx
, p
->conn
->binding_string
, &b
);
1555 torture_assert_ntstatus_ok(tctx
, status
, "Failed to parse dcerpc binding");
1557 status
= dcerpc_secondary_connection(p
, &p2
, b
);
1558 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
1560 status
= dcerpc_bind_auth_none(p2
, &ndr_table_spoolss
);
1561 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create bind on secondary connection");
1563 cp
.in
.handle
= handle
;
1564 cp
.out
.handle
= handle
;
1566 status
= dcerpc_spoolss_ClosePrinter(p2
, tctx
, &cp
);
1567 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NET_WRITE_FAULT
,
1568 "ERROR: Allowed close on secondary connection");
1570 torture_assert_int_equal(tctx
, p2
->last_fault_code
, DCERPC_FAULT_CONTEXT_MISMATCH
,
1571 "Unexpected fault code");
1578 static bool test_OpenPrinter_badname(struct torture_context
*tctx
,
1579 struct dcerpc_pipe
*p
, const char *name
)
1582 struct spoolss_OpenPrinter op
;
1583 struct spoolss_OpenPrinterEx opEx
;
1584 struct policy_handle handle
;
1587 op
.in
.printername
= name
;
1588 op
.in
.datatype
= NULL
;
1589 op
.in
.devmode_ctr
.devmode
= NULL
;
1590 op
.in
.access_mask
= 0;
1591 op
.out
.handle
= &handle
;
1593 torture_comment(tctx
, "\nTesting OpenPrinter(%s) with bad name\n", op
.in
.printername
);
1595 status
= dcerpc_spoolss_OpenPrinter(p
, tctx
, &op
);
1596 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinter failed");
1597 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,op
.out
.result
)) {
1598 torture_comment(tctx
, "OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1599 name
, win_errstr(op
.out
.result
));
1602 if (W_ERROR_IS_OK(op
.out
.result
)) {
1603 ret
&=test_ClosePrinter(tctx
, p
, &handle
);
1606 opEx
.in
.printername
= name
;
1607 opEx
.in
.datatype
= NULL
;
1608 opEx
.in
.devmode_ctr
.devmode
= NULL
;
1609 opEx
.in
.access_mask
= 0;
1611 opEx
.in
.userlevel
.level1
= NULL
;
1612 opEx
.out
.handle
= &handle
;
1614 torture_comment(tctx
, "Testing OpenPrinterEx(%s) with bad name\n", opEx
.in
.printername
);
1616 status
= dcerpc_spoolss_OpenPrinterEx(p
, tctx
, &opEx
);
1617 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinterEx failed");
1618 if (!W_ERROR_EQUAL(WERR_INVALID_PARAM
,opEx
.out
.result
)) {
1619 torture_comment(tctx
, "OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PARAM\n",
1620 name
, win_errstr(opEx
.out
.result
));
1623 if (W_ERROR_IS_OK(opEx
.out
.result
)) {
1624 ret
&=test_ClosePrinter(tctx
, p
, &handle
);
1630 static bool test_OpenPrinter(struct torture_context
*tctx
,
1631 struct dcerpc_pipe
*p
,
1635 struct spoolss_OpenPrinter r
;
1636 struct policy_handle handle
;
1639 r
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s\\%s", dcerpc_server_name(p
), name
);
1640 r
.in
.datatype
= NULL
;
1641 r
.in
.devmode_ctr
.devmode
= NULL
;
1642 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1643 r
.out
.handle
= &handle
;
1645 torture_comment(tctx
, "Testing OpenPrinter(%s)\n", r
.in
.printername
);
1647 status
= dcerpc_spoolss_OpenPrinter(p
, tctx
, &r
);
1649 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinter failed");
1651 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenPrinter failed");
1653 if (!test_GetPrinter(tctx
, p
, &handle
)) {
1657 if (!test_SecondaryClosePrinter(tctx
, p
, &handle
)) {
1661 if (!test_ClosePrinter(tctx
, p
, &handle
)) {
1668 static bool call_OpenPrinterEx(struct torture_context
*tctx
,
1669 struct dcerpc_pipe
*p
,
1670 const char *name
, struct policy_handle
*handle
)
1672 struct spoolss_OpenPrinterEx r
;
1673 struct spoolss_UserLevel1 userlevel1
;
1676 if (name
&& name
[0]) {
1677 r
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s\\%s",
1678 dcerpc_server_name(p
), name
);
1680 r
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s",
1681 dcerpc_server_name(p
));
1684 r
.in
.datatype
= NULL
;
1685 r
.in
.devmode_ctr
.devmode
= NULL
;
1686 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1688 r
.in
.userlevel
.level1
= &userlevel1
;
1689 r
.out
.handle
= handle
;
1691 userlevel1
.size
= 1234;
1692 userlevel1
.client
= "hello";
1693 userlevel1
.user
= "spottyfoot!";
1694 userlevel1
.build
= 1;
1695 userlevel1
.major
= 2;
1696 userlevel1
.minor
= 3;
1697 userlevel1
.processor
= 4;
1699 torture_comment(tctx
, "Testing OpenPrinterEx(%s)\n", r
.in
.printername
);
1701 status
= dcerpc_spoolss_OpenPrinterEx(p
, tctx
, &r
);
1703 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinterEx failed");
1705 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenPrinterEx failed");
1710 static bool test_OpenPrinterEx(struct torture_context
*tctx
,
1711 struct dcerpc_pipe
*p
,
1714 struct policy_handle handle
;
1717 if (!call_OpenPrinterEx(tctx
, p
, name
, &handle
)) {
1721 if (!test_GetPrinter(tctx
, p
, &handle
)) {
1725 if (!test_EnumForms(tctx
, p
, &handle
, false)) {
1729 if (!test_AddForm(tctx
, p
, &handle
, false)) {
1733 if (!test_EnumPrinterData(tctx
, p
, &handle
)) {
1737 if (!test_EnumPrinterDataEx(tctx
, p
, &handle
)) {
1741 if (!test_PausePrinter(tctx
, p
, &handle
)) {
1745 if (!test_DoPrintTest(tctx
, p
, &handle
)) {
1749 if (!test_ResumePrinter(tctx
, p
, &handle
)) {
1753 if (!test_SetPrinterData(tctx
, p
, &handle
)) {
1757 if (!test_SecondaryClosePrinter(tctx
, p
, &handle
)) {
1761 if (!test_ClosePrinter(tctx
, p
, &handle
)) {
1768 static bool test_EnumPrinters_old(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
1770 struct spoolss_EnumPrinters r
;
1772 uint16_t levels
[] = {1, 2, 4, 5};
1776 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1777 union spoolss_PrinterInfo
*info
;
1782 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
1784 r
.in
.level
= levels
[i
];
1787 r
.out
.needed
= &needed
;
1788 r
.out
.count
= &count
;
1791 torture_comment(tctx
, "Testing EnumPrinters level %u\n", r
.in
.level
);
1793 status
= dcerpc_spoolss_EnumPrinters(p
, tctx
, &r
);
1794 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinters failed");
1796 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1797 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1798 data_blob_clear(&blob
);
1799 r
.in
.buffer
= &blob
;
1800 r
.in
.offered
= needed
;
1801 status
= dcerpc_spoolss_EnumPrinters(p
, tctx
, &r
);
1804 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinters failed");
1806 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinters failed");
1809 torture_comment(tctx
, "No printers returned\n");
1813 for (j
=0;j
<count
;j
++) {
1814 if (r
.in
.level
== 1) {
1815 /* the names appear to be comma-separated name lists? */
1816 char *name
= talloc_strdup(tctx
, info
[j
].info1
.name
);
1817 char *comma
= strchr(name
, ',');
1818 if (comma
) *comma
= 0;
1819 if (!test_OpenPrinter(tctx
, p
, name
)) {
1822 if (!test_OpenPrinterEx(tctx
, p
, name
)) {
1833 static bool test_GetPrinterDriver2(struct dcerpc_pipe
*p
,
1834 struct policy_handle
*handle
,
1835 const char *driver_name
)
1838 struct spoolss_GetPrinterDriver2 r
;
1840 uint32_t server_major_version
;
1841 uint32_t server_minor_version
;
1843 r
.in
.handle
= handle
;
1844 r
.in
.architecture
= "W32X86";
1848 r
.in
.client_major_version
= 0;
1849 r
.in
.client_minor_version
= 0;
1850 r
.out
.needed
= &needed
;
1851 r
.out
.server_major_version
= &server_major_version
;
1852 r
.out
.server_minor_version
= &server_minor_version
;
1854 printf("Testing GetPrinterDriver2\n");
1856 status
= dcerpc_spoolss_GetPrinterDriver2(p
, tctx
, &r
);
1857 if (!NT_STATUS_IS_OK(status
)) {
1858 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status
));
1862 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1863 r
.in
.offered
= needed
;
1864 status
= dcerpc_spoolss_GetPrinterDriver2(p
, tctx
, &r
);
1867 if (!NT_STATUS_IS_OK(status
)) {
1868 printf("GetPrinterDriver2 failed - %s\n",
1873 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1874 printf("GetPrinterDriver2 failed - %s\n",
1875 win_errstr(r
.out
.result
));
1883 static bool test_EnumPrinterDrivers_old(struct torture_context
*tctx
,
1884 struct dcerpc_pipe
*p
)
1886 struct spoolss_EnumPrinterDrivers r
;
1888 uint16_t levels
[] = {1, 2, 3, 4, 5, 6};
1891 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1895 union spoolss_DriverInfo
*info
;
1897 r
.in
.server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
1898 r
.in
.environment
= "Windows NT x86";
1899 r
.in
.level
= levels
[i
];
1902 r
.out
.needed
= &needed
;
1903 r
.out
.count
= &count
;
1906 torture_comment(tctx
, "Testing EnumPrinterDrivers level %u\n", r
.in
.level
);
1908 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, tctx
, &r
);
1910 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDrivers failed");
1912 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1913 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1914 data_blob_clear(&blob
);
1915 r
.in
.buffer
= &blob
;
1916 r
.in
.offered
= needed
;
1917 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, tctx
, &r
);
1920 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDrivers failed");
1922 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinterDrivers failed");
1925 torture_comment(tctx
, "No printer drivers returned\n");
1933 /** Test that makes sure that calling ReplyOpenPrinter()
1934 * on Samba 4 will cause an irpc broadcast call.
1936 static bool test_ReplyOpenPrinter(struct torture_context
*tctx
,
1937 struct dcerpc_pipe
*pipe
)
1939 struct spoolss_ReplyOpenPrinter r
;
1940 struct spoolss_ReplyClosePrinter s
;
1941 struct policy_handle h
;
1943 r
.in
.server_name
= "earth";
1944 r
.in
.printer_local
= 2;
1945 r
.in
.type
= REG_DWORD
;
1950 torture_assert_ntstatus_ok(tctx
,
1951 dcerpc_spoolss_ReplyOpenPrinter(pipe
, tctx
, &r
),
1952 "spoolss_ReplyOpenPrinter call failed");
1954 torture_assert_werr_ok(tctx
, r
.out
.result
, "error return code");
1959 torture_assert_ntstatus_ok(tctx
,
1960 dcerpc_spoolss_ReplyClosePrinter(pipe
, tctx
, &s
),
1961 "spoolss_ReplyClosePrinter call failed");
1963 torture_assert_werr_ok(tctx
, r
.out
.result
, "error return code");
1968 bool torture_rpc_spoolss(struct torture_context
*torture
)
1971 struct dcerpc_pipe
*p
;
1973 struct test_spoolss_context
*ctx
;
1975 status
= torture_rpc_connection(torture
, &p
, &ndr_table_spoolss
);
1976 if (!NT_STATUS_IS_OK(status
)) {
1980 ctx
= talloc_zero(torture
, struct test_spoolss_context
);
1982 ret
&= test_OpenPrinter_server(torture
, p
, ctx
);
1984 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "W3SvcInstalled");
1985 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "BeepEnabled");
1986 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "EventLog");
1987 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "NetPopup");
1988 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "NetPopupToComputer");
1989 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "MajorVersion");
1990 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "MinorVersion");
1991 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "DefaultSpoolDirectory");
1992 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "Architecture");
1993 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "DsPresent");
1994 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "OSVersion");
1995 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "OSVersionEx");
1996 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "DNSMachineName");
1997 ret
&= test_EnumForms(torture
, p
, &ctx
->server_handle
, true);
1998 ret
&= test_AddForm(torture
, p
, &ctx
->server_handle
, true);
1999 ret
&= test_EnumPorts(torture
, p
, ctx
);
2000 ret
&= test_GetPrinterDriverDirectory(torture
, p
, ctx
);
2001 ret
&= test_GetPrintProcessorDirectory(torture
, p
, ctx
);
2002 ret
&= test_EnumPrinterDrivers(torture
, p
, ctx
);
2003 ret
&= test_EnumMonitors(torture
, p
, ctx
);
2004 ret
&= test_EnumPrintProcessors(torture
, p
, ctx
);
2005 ret
&= test_EnumPrintProcDataTypes(torture
, p
, ctx
);
2006 ret
&= test_EnumPrinters(torture
, p
, ctx
);
2007 ret
&= test_OpenPrinter_badname(torture
, p
, "__INVALID_PRINTER__");
2008 ret
&= test_OpenPrinter_badname(torture
, p
, "\\\\__INVALID_HOST__");
2009 ret
&= test_OpenPrinter_badname(torture
, p
, "");
2010 ret
&= test_OpenPrinter_badname(torture
, p
, "\\\\\\");
2011 ret
&= test_OpenPrinter_badname(torture
, p
, "\\\\\\__INVALID_PRINTER__");
2012 ret
&= test_OpenPrinter_badname(torture
, p
, talloc_asprintf(torture
, "\\\\%s\\", dcerpc_server_name(p
)));
2013 ret
&= test_OpenPrinter_badname(torture
, p
,
2014 talloc_asprintf(torture
, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p
)));
2017 ret
&= test_AddPort(torture
, p
);
2018 ret
&= test_EnumPorts_old(torture
, p
);
2019 ret
&= test_EnumPrinters_old(torture
, p
);
2020 ret
&= test_EnumPrinterDrivers_old(torture
, p
);
2021 ret
&= test_ReplyOpenPrinter(torture
, p
);