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
8 Copyright (C) Guenther Deschner 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "torture/torture.h"
26 #include "torture/rpc/rpc.h"
27 #include "librpc/gen_ndr/ndr_spoolss_c.h"
29 struct test_spoolss_context
{
30 /* print server handle */
31 struct policy_handle server_handle
;
34 uint32_t port_count
[3];
35 union spoolss_PortInfo
*ports
[3];
37 /* for EnumPrinterDrivers */
38 uint32_t driver_count
[7];
39 union spoolss_DriverInfo
*drivers
[7];
41 /* for EnumMonitors */
42 uint32_t monitor_count
[3];
43 union spoolss_MonitorInfo
*monitors
[3];
45 /* for EnumPrintProcessors */
46 uint32_t print_processor_count
[2];
47 union spoolss_PrintProcessorInfo
*print_processors
[2];
49 /* for EnumPrinters */
50 uint32_t printer_count
[6];
51 union spoolss_PrinterInfo
*printers
[6];
54 #define COMPARE_STRING(tctx, c,r,e) \
55 torture_assert_str_equal(tctx, c.e, r.e, "invalid value")
57 /* not every compiler supports __typeof__() */
59 #define _CHECK_FIELD_SIZE(c,r,e,type) do {\
60 if (sizeof(__typeof__(c.e)) != sizeof(type)) { \
61 torture_fail(tctx, #c "." #e "field is not " #type "\n"); \
63 if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
64 torture_fail(tctx, #r "." #e "field is not " #type "\n"); \
68 #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
71 #define COMPARE_UINT32(tctx, c, r, e) do {\
72 _CHECK_FIELD_SIZE(c, r, e, uint32_t); \
73 torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \
76 #define COMPARE_STRING_ARRAY(tctx, c,r,e)
78 static bool test_OpenPrinter_server(struct torture_context
*tctx
,
79 struct dcerpc_pipe
*p
,
80 struct policy_handle
*server_handle
)
83 struct spoolss_OpenPrinter op
;
85 op
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
86 op
.in
.datatype
= NULL
;
87 op
.in
.devmode_ctr
.devmode
= NULL
;
88 op
.in
.access_mask
= 0;
89 op
.out
.handle
= server_handle
;
91 torture_comment(tctx
, "Testing OpenPrinter(%s)\n", op
.in
.printername
);
93 status
= dcerpc_spoolss_OpenPrinter(p
, tctx
, &op
);
94 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_OpenPrinter failed");
95 torture_assert_werr_ok(tctx
, op
.out
.result
, "dcerpc_spoolss_OpenPrinter failed");
100 static bool test_EnumPorts(struct torture_context
*tctx
,
101 struct dcerpc_pipe
*p
,
102 struct test_spoolss_context
*ctx
)
105 struct spoolss_EnumPorts r
;
106 uint16_t levels
[] = { 1, 2 };
109 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
110 int level
= levels
[i
];
114 union spoolss_PortInfo
*info
;
116 r
.in
.servername
= "";
120 r
.out
.needed
= &needed
;
121 r
.out
.count
= &count
;
124 torture_comment(tctx
, "Testing EnumPorts level %u\n", r
.in
.level
);
126 status
= dcerpc_spoolss_EnumPorts(p
, ctx
, &r
);
127 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPorts failed");
128 if (W_ERROR_IS_OK(r
.out
.result
)) {
129 /* TODO: do some more checks here */
132 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
133 "EnumPorts unexpected return code");
135 blob
= data_blob_talloc(ctx
, NULL
, needed
);
136 data_blob_clear(&blob
);
138 r
.in
.offered
= needed
;
140 status
= dcerpc_spoolss_EnumPorts(p
, ctx
, &r
);
141 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPorts failed");
143 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPorts failed");
145 torture_assert(tctx
, info
, "EnumPorts returned no info");
147 ctx
->port_count
[level
] = count
;
148 ctx
->ports
[level
] = info
;
151 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
152 int level
= levels
[i
];
153 int old_level
= levels
[i
-1];
154 torture_assert_int_equal(tctx
, ctx
->port_count
[level
], ctx
->port_count
[old_level
],
155 "EnumPorts invalid value");
157 /* if the array sizes are not the same we would maybe segfault in the following code */
159 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
160 int level
= levels
[i
];
161 for (j
=0;j
<ctx
->port_count
[level
];j
++) {
162 union spoolss_PortInfo
*cur
= &ctx
->ports
[level
][j
];
163 union spoolss_PortInfo
*ref
= &ctx
->ports
[2][j
];
166 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, port_name
);
169 /* level 2 is our reference, and it makes no sense to compare it to itself */
178 static bool test_GetPrintProcessorDirectory(struct torture_context
*tctx
,
179 struct dcerpc_pipe
*p
,
180 struct test_spoolss_context
*ctx
)
183 struct spoolss_GetPrintProcessorDirectory r
;
198 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
201 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
207 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
208 int level
= levels
[i
].level
;
211 r
.in
.server
= levels
[i
].server
;
212 r
.in
.environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
216 r
.out
.needed
= &needed
;
218 torture_comment(tctx
, "Testing GetPrintProcessorDirectory level %u\n", r
.in
.level
);
220 status
= dcerpc_spoolss_GetPrintProcessorDirectory(p
, ctx
, &r
);
221 torture_assert_ntstatus_ok(tctx
, status
,
222 "dcerpc_spoolss_GetPrintProcessorDirectory failed");
223 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
224 "GetPrintProcessorDirectory unexpected return code");
226 blob
= data_blob_talloc(ctx
, NULL
, needed
);
227 data_blob_clear(&blob
);
229 r
.in
.offered
= needed
;
231 status
= dcerpc_spoolss_GetPrintProcessorDirectory(p
, ctx
, &r
);
232 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
234 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrintProcessorDirectory failed");
241 static bool test_GetPrinterDriverDirectory(struct torture_context
*tctx
,
242 struct dcerpc_pipe
*p
,
243 struct test_spoolss_context
*ctx
)
246 struct spoolss_GetPrinterDriverDirectory r
;
261 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
264 .server
= talloc_asprintf(ctx
, "\\\\%s", dcerpc_server_name(p
))
270 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
271 int level
= levels
[i
].level
;
274 r
.in
.server
= levels
[i
].server
;
275 r
.in
.environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
279 r
.out
.needed
= &needed
;
281 torture_comment(tctx
, "Testing GetPrinterDriverDirectory level %u\n", r
.in
.level
);
283 status
= dcerpc_spoolss_GetPrinterDriverDirectory(p
, ctx
, &r
);
284 torture_assert_ntstatus_ok(tctx
, status
,
285 "dcerpc_spoolss_GetPrinterDriverDirectory failed");
286 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
287 "GetPrinterDriverDirectory unexpected return code");
289 blob
= data_blob_talloc(ctx
, NULL
, needed
);
290 data_blob_clear(&blob
);
292 r
.in
.offered
= needed
;
294 status
= dcerpc_spoolss_GetPrinterDriverDirectory(p
, ctx
, &r
);
295 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_GetPrinterDriverDirectory failed");
297 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinterDriverDirectory failed");
303 static bool test_EnumPrinterDrivers(struct torture_context
*tctx
,
304 struct dcerpc_pipe
*p
,
305 struct test_spoolss_context
*ctx
)
308 struct spoolss_EnumPrinterDrivers r
;
309 uint16_t levels
[] = { 1, 2, 3, 4, 5, 6 };
311 const char *architectures
[] = {
312 SPOOLSS_ARCHITECTURE_NT_X86
,
313 SPOOLSS_ARCHITECTURE_ALL
316 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
317 for (a
=0;a
<ARRAY_SIZE(architectures
);a
++) {
318 int level
= levels
[i
];
322 union spoolss_DriverInfo
*info
;
324 /* FIXME: gd, come back and fix "" as server, and handle
325 * priority of returned error codes in torture test and samba 3
328 r
.in
.server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
329 r
.in
.environment
= architectures
[a
];
333 r
.out
.needed
= &needed
;
334 r
.out
.count
= &count
;
337 torture_comment(tctx
, "Testing EnumPrinterDrivers level %u (%s)\n", r
.in
.level
, r
.in
.environment
);
339 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, ctx
, &r
);
340 torture_assert_ntstatus_ok(tctx
, status
,
341 "dcerpc_spoolss_EnumPrinterDrivers failed");
342 if (W_ERROR_IS_OK(r
.out
.result
)) {
343 /* TODO: do some more checks here */
346 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
347 blob
= data_blob_talloc(ctx
, NULL
, needed
);
348 data_blob_clear(&blob
);
350 r
.in
.offered
= needed
;
352 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, ctx
, &r
);
353 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinterDrivers failed");
356 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinterDrivers failed");
358 /* don't do cross-architecture comparison */
359 if (strequal(r
.in
.environment
, SPOOLSS_ARCHITECTURE_ALL
)) {
363 ctx
->driver_count
[level
] = count
;
364 ctx
->drivers
[level
] = info
;
368 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
369 int level
= levels
[i
];
370 int old_level
= levels
[i
-1];
372 /* don't do cross-architecture comparison */
373 if (strequal(r
.in
.environment
, SPOOLSS_ARCHITECTURE_ALL
)) {
377 torture_assert_int_equal(tctx
, ctx
->driver_count
[level
], ctx
->driver_count
[old_level
],
378 "EnumPrinterDrivers invalid value");
381 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
382 int level
= levels
[i
];
384 /* don't do cross-architecture comparison */
385 if (strequal(r
.in
.environment
, SPOOLSS_ARCHITECTURE_ALL
)) {
389 for (j
=0;j
<ctx
->driver_count
[level
];j
++) {
390 union spoolss_DriverInfo
*cur
= &ctx
->drivers
[level
][j
];
391 union spoolss_DriverInfo
*ref
= &ctx
->drivers
[6][j
];
394 COMPARE_STRING(tctx
, cur
->info1
, ref
->info6
, driver_name
);
397 COMPARE_UINT32(tctx
, cur
->info2
, ref
->info6
, version
);
398 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, driver_name
);
399 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, architecture
);
400 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, driver_path
);
401 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, data_file
);
402 COMPARE_STRING(tctx
, cur
->info2
, ref
->info6
, config_file
);
405 COMPARE_UINT32(tctx
, cur
->info3
, ref
->info6
, version
);
406 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, driver_name
);
407 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, architecture
);
408 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, driver_path
);
409 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, data_file
);
410 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, config_file
);
411 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, help_file
);
412 COMPARE_STRING_ARRAY(tctx
, cur
->info3
, ref
->info6
, dependent_files
);
413 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, monitor_name
);
414 COMPARE_STRING(tctx
, cur
->info3
, ref
->info6
, default_datatype
);
417 COMPARE_UINT32(tctx
, cur
->info4
, ref
->info6
, version
);
418 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, driver_name
);
419 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, architecture
);
420 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, driver_path
);
421 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, data_file
);
422 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, config_file
);
423 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, help_file
);
424 COMPARE_STRING_ARRAY(tctx
, cur
->info4
, ref
->info6
, dependent_files
);
425 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, monitor_name
);
426 COMPARE_STRING(tctx
, cur
->info4
, ref
->info6
, default_datatype
);
427 COMPARE_STRING_ARRAY(tctx
, cur
->info4
, ref
->info6
, previous_names
);
430 COMPARE_UINT32(tctx
, cur
->info5
, ref
->info6
, version
);
431 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, driver_name
);
432 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, architecture
);
433 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, driver_path
);
434 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, data_file
);
435 COMPARE_STRING(tctx
, cur
->info5
, ref
->info6
, config_file
);
436 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_attributes);*/
437 /*COMPARE_UINT32(tctx, cur->info5, ref->info6, config_version);*/
438 /*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_version); */
441 /* level 6 is our reference, and it makes no sense to compare it to itself */
450 static bool test_EnumMonitors(struct torture_context
*tctx
,
451 struct dcerpc_pipe
*p
,
452 struct test_spoolss_context
*ctx
)
455 struct spoolss_EnumMonitors r
;
456 uint16_t levels
[] = { 1, 2 };
459 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
460 int level
= levels
[i
];
464 union spoolss_MonitorInfo
*info
;
466 r
.in
.servername
= "";
470 r
.out
.needed
= &needed
;
471 r
.out
.count
= &count
;
474 torture_comment(tctx
, "Testing EnumMonitors level %u\n", r
.in
.level
);
476 status
= dcerpc_spoolss_EnumMonitors(p
, ctx
, &r
);
477 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumMonitors failed");
478 if (W_ERROR_IS_OK(r
.out
.result
)) {
479 /* TODO: do some more checks here */
482 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
483 "EnumMonitors failed");
485 blob
= data_blob_talloc(ctx
, NULL
, needed
);
486 data_blob_clear(&blob
);
488 r
.in
.offered
= needed
;
490 status
= dcerpc_spoolss_EnumMonitors(p
, ctx
, &r
);
491 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumMonitors failed");
493 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumMonitors failed");
495 ctx
->monitor_count
[level
] = count
;
496 ctx
->monitors
[level
] = info
;
499 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
500 int level
= levels
[i
];
501 int old_level
= levels
[i
-1];
502 torture_assert_int_equal(tctx
, ctx
->monitor_count
[level
], ctx
->monitor_count
[old_level
],
503 "EnumMonitors invalid value");
506 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
507 int level
= levels
[i
];
508 for (j
=0;j
<ctx
->monitor_count
[level
];j
++) {
509 union spoolss_MonitorInfo
*cur
= &ctx
->monitors
[level
][j
];
510 union spoolss_MonitorInfo
*ref
= &ctx
->monitors
[2][j
];
513 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, monitor_name
);
516 /* level 2 is our reference, and it makes no sense to compare it to itself */
525 static bool test_EnumPrintProcessors(struct torture_context
*tctx
,
526 struct dcerpc_pipe
*p
,
527 struct test_spoolss_context
*ctx
)
530 struct spoolss_EnumPrintProcessors r
;
531 uint16_t levels
[] = { 1 };
534 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
535 int level
= levels
[i
];
539 union spoolss_PrintProcessorInfo
*info
;
541 r
.in
.servername
= "";
542 r
.in
.environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
546 r
.out
.needed
= &needed
;
547 r
.out
.count
= &count
;
550 torture_comment(tctx
, "Testing EnumPrintProcessors level %u\n", r
.in
.level
);
552 status
= dcerpc_spoolss_EnumPrintProcessors(p
, ctx
, &r
);
553 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcessors failed");
554 if (W_ERROR_IS_OK(r
.out
.result
)) {
555 /* TODO: do some more checks here */
558 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
559 "EnumPrintProcessors unexpected return code");
561 blob
= data_blob_talloc(ctx
, NULL
, needed
);
562 data_blob_clear(&blob
);
564 r
.in
.offered
= needed
;
566 status
= dcerpc_spoolss_EnumPrintProcessors(p
, ctx
, &r
);
567 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcessors failed");
569 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrintProcessors failed");
571 ctx
->print_processor_count
[level
] = count
;
572 ctx
->print_processors
[level
] = info
;
575 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
576 int level
= levels
[i
];
577 int old_level
= levels
[i
-1];
578 torture_assert_int_equal(tctx
, ctx
->print_processor_count
[level
], ctx
->print_processor_count
[old_level
],
579 "EnumPrintProcessors failed");
582 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
583 int level
= levels
[i
];
584 for (j
=0;j
<ctx
->print_processor_count
[level
];j
++) {
586 union spoolss_PrintProcessorInfo
*cur
= &ctx
->print_processors
[level
][j
];
587 union spoolss_PrintProcessorInfo
*ref
= &ctx
->print_processors
[1][j
];
591 /* level 1 is our reference, and it makes no sense to compare it to itself */
600 static bool test_EnumPrintProcDataTypes(struct torture_context
*tctx
,
601 struct dcerpc_pipe
*p
,
602 struct test_spoolss_context
*ctx
)
605 struct spoolss_EnumPrintProcDataTypes r
;
606 uint16_t levels
[] = { 1 };
609 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
610 int level
= levels
[i
];
614 union spoolss_PrintProcDataTypesInfo
*info
;
616 r
.in
.servername
= "";
617 r
.in
.print_processor_name
= "winprint";
621 r
.out
.needed
= &needed
;
622 r
.out
.count
= &count
;
625 torture_comment(tctx
, "Testing EnumPrintProcDataTypes level %u\n", r
.in
.level
);
627 status
= dcerpc_spoolss_EnumPrintProcDataTypes(p
, ctx
, &r
);
628 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcDataType failed");
629 if (W_ERROR_IS_OK(r
.out
.result
)) {
630 /* TODO: do some more checks here */
633 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
634 "EnumPrintProcDataTypes unexpected return code");
636 blob
= data_blob_talloc(ctx
, NULL
, needed
);
637 data_blob_clear(&blob
);
639 r
.in
.offered
= needed
;
641 status
= dcerpc_spoolss_EnumPrintProcDataTypes(p
, ctx
, &r
);
642 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrintProcDataTypes failed");
644 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrintProcDataTypes failed");
651 static bool test_EnumPrinters(struct torture_context
*tctx
,
652 struct dcerpc_pipe
*p
,
653 struct test_spoolss_context
*ctx
)
655 struct spoolss_EnumPrinters r
;
657 uint16_t levels
[] = { 0, 1, 2, 4, 5 };
660 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
661 int level
= levels
[i
];
665 union spoolss_PrinterInfo
*info
;
667 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
672 r
.out
.needed
= &needed
;
673 r
.out
.count
= &count
;
676 torture_comment(tctx
, "Testing EnumPrinters level %u\n", r
.in
.level
);
678 status
= dcerpc_spoolss_EnumPrinters(p
, ctx
, &r
);
679 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinters failed");
680 if (W_ERROR_IS_OK(r
.out
.result
)) {
681 /* TODO: do some more checks here */
684 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INSUFFICIENT_BUFFER
,
685 "EnumPrinters unexpected return code");
687 blob
= data_blob_talloc(ctx
, NULL
, needed
);
688 data_blob_clear(&blob
);
690 r
.in
.offered
= needed
;
692 status
= dcerpc_spoolss_EnumPrinters(p
, ctx
, &r
);
693 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EnumPrinters failed");
695 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinters failed");
697 ctx
->printer_count
[level
] = count
;
698 ctx
->printers
[level
] = info
;
701 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
702 int level
= levels
[i
];
703 int old_level
= levels
[i
-1];
704 torture_assert_int_equal(tctx
, ctx
->printer_count
[level
], ctx
->printer_count
[old_level
],
705 "EnumPrinters invalid value");
708 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
709 int level
= levels
[i
];
710 for (j
=0;j
<ctx
->printer_count
[level
];j
++) {
711 union spoolss_PrinterInfo
*cur
= &ctx
->printers
[level
][j
];
712 union spoolss_PrinterInfo
*ref
= &ctx
->printers
[2][j
];
715 COMPARE_STRING(tctx
, cur
->info0
, ref
->info2
, printername
);
716 COMPARE_STRING(tctx
, cur
->info0
, ref
->info2
, servername
);
717 COMPARE_UINT32(tctx
, cur
->info0
, ref
->info2
, cjobs
);
718 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs);
719 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_bytes);
720 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
721 COMPARE_UINT32(tctx, cur->info0, ref->info2, global_counter);
722 COMPARE_UINT32(tctx, cur->info0, ref->info2, total_pages);
723 COMPARE_UINT32(tctx, cur->info0, ref->info2, version);
724 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown10);
725 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown11);
726 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown12);
727 COMPARE_UINT32(tctx, cur->info0, ref->info2, session_counter);
728 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown14);
729 COMPARE_UINT32(tctx, cur->info0, ref->info2, printer_errors);
730 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown16);
731 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown17);
732 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown18);
733 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown19);
734 COMPARE_UINT32(tctx, cur->info0, ref->info2, change_id);
735 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown21);*/
736 COMPARE_UINT32(tctx
, cur
->info0
, ref
->info2
, status
);
737 /*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23);
738 COMPARE_UINT32(tctx, cur->info0, ref->info2, c_setprinter);
739 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
740 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
741 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown27);
742 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown28);
743 COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown29);*/
746 /*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/
747 /*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/
748 /*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/
749 COMPARE_STRING(tctx
, cur
->info1
, ref
->info2
, comment
);
752 /* level 2 is our reference, and it makes no sense to compare it to itself */
755 COMPARE_STRING(tctx
, cur
->info4
, ref
->info2
, printername
);
756 COMPARE_STRING(tctx
, cur
->info4
, ref
->info2
, servername
);
757 COMPARE_UINT32(tctx
, cur
->info4
, ref
->info2
, attributes
);
760 COMPARE_STRING(tctx
, cur
->info5
, ref
->info2
, printername
);
761 COMPARE_STRING(tctx
, cur
->info5
, ref
->info2
, portname
);
762 COMPARE_UINT32(tctx
, cur
->info5
, ref
->info2
, attributes
);
763 /*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout);
764 COMPARE_UINT32(tctx, cur->info5, ref->info2, transmission_retry_timeout);*/
771 * - verify that the port of a printer was in the list returned by EnumPorts
777 static bool test_GetPrinter(struct torture_context
*tctx
,
778 struct dcerpc_pipe
*p
,
779 struct policy_handle
*handle
)
782 struct spoolss_GetPrinter r
;
783 uint16_t levels
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
787 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
788 r
.in
.handle
= handle
;
789 r
.in
.level
= levels
[i
];
792 r
.out
.needed
= &needed
;
794 torture_comment(tctx
, "Testing GetPrinter level %u\n", r
.in
.level
);
796 status
= dcerpc_spoolss_GetPrinter(p
, tctx
, &r
);
797 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinter failed");
799 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
800 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
801 data_blob_clear(&blob
);
803 r
.in
.offered
= needed
;
804 status
= dcerpc_spoolss_GetPrinter(p
, tctx
, &r
);
807 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinter failed");
809 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinter failed");
815 static bool test_SetPrinter_errors(struct torture_context
*tctx
,
816 struct dcerpc_pipe
*p
,
817 struct policy_handle
*handle
)
819 struct spoolss_SetPrinter r
;
820 uint16_t levels
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
823 struct spoolss_SetPrinterInfoCtr info_ctr
;
824 struct spoolss_DevmodeContainer devmode_ctr
;
825 struct sec_desc_buf secdesc_ctr
;
828 info_ctr
.info
.info0
= NULL
;
830 ZERO_STRUCT(devmode_ctr
);
831 ZERO_STRUCT(secdesc_ctr
);
833 r
.in
.handle
= handle
;
834 r
.in
.info_ctr
= &info_ctr
;
835 r
.in
.devmode_ctr
= &devmode_ctr
;
836 r
.in
.secdesc_ctr
= &secdesc_ctr
;
839 torture_comment(tctx
, "Testing SetPrinter all zero\n");
841 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_SetPrinter(p
, tctx
, &r
),
842 "failed to call SetPrinter");
843 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
844 "failed to call SetPrinter");
847 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
849 struct spoolss_SetPrinterInfo0 info0
;
850 struct spoolss_SetPrinterInfo1 info1
;
851 struct spoolss_SetPrinterInfo2 info2
;
852 struct spoolss_SetPrinterInfo3 info3
;
853 struct spoolss_SetPrinterInfo4 info4
;
854 struct spoolss_SetPrinterInfo5 info5
;
855 struct spoolss_SetPrinterInfo6 info6
;
856 struct spoolss_SetPrinterInfo7 info7
;
857 struct spoolss_DeviceModeInfo info8
;
858 struct spoolss_DeviceModeInfo info9
;
861 info_ctr
.level
= levels
[i
];
865 info_ctr
.info
.info0
= &info0
;
869 info_ctr
.info
.info1
= &info1
;
873 info_ctr
.info
.info2
= &info2
;
877 info_ctr
.info
.info3
= &info3
;
881 info_ctr
.info
.info4
= &info4
;
885 info_ctr
.info
.info5
= &info5
;
889 info_ctr
.info
.info6
= &info6
;
893 info_ctr
.info
.info7
= &info7
;
897 info_ctr
.info
.info8
= &info8
;
901 info_ctr
.info
.info9
= &info9
;
905 torture_comment(tctx
, "Testing SetPrinter level %d, command %d\n",
906 info_ctr
.level
, r
.in
.command
);
908 torture_assert_ntstatus_ok(tctx
, dcerpc_spoolss_SetPrinter(p
, tctx
, &r
),
909 "failed to call SetPrinter");
911 switch (r
.in
.command
) {
912 case SPOOLSS_PRINTER_CONTROL_UNPAUSE
: /* 0 */
913 /* is ignored for all levels other then 0 */
914 if (info_ctr
.level
> 0) {
918 case SPOOLSS_PRINTER_CONTROL_PAUSE
: /* 1 */
919 case SPOOLSS_PRINTER_CONTROL_RESUME
: /* 2 */
920 case SPOOLSS_PRINTER_CONTROL_PURGE
: /* 3 */
921 if (info_ctr
.level
> 0) {
922 /* is invalid for all levels other then 0 */
923 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PRINTER_COMMAND
,
924 "unexpected error code returned");
927 torture_assert_werr_ok(tctx
, r
.out
.result
,
928 "failed to call SetPrinter with non 0 command");
933 case SPOOLSS_PRINTER_CONTROL_SET_STATUS
: /* 4 */
934 /* FIXME: gd needs further investigation */
936 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PRINTER_COMMAND
,
937 "unexpected error code returned");
941 switch (info_ctr
.level
) {
943 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
,
944 "unexpected error code returned");
947 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_PRINTER_DRIVER
,
948 "unexpected error code returned");
954 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
955 "unexpected error code returned");
958 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NOT_SUPPORTED
,
959 "unexpected error code returned");
962 torture_assert_werr_ok(tctx
, r
.out
.result
,
963 "failed to call SetPrinter");
968 if (r
.in
.command
< 5) {
976 static void clear_info2(struct spoolss_SetPrinterInfoCtr
*r
)
978 if ((r
->level
== 2) && (r
->info
.info2
)) {
979 r
->info
.info2
->secdesc
= NULL
;
980 r
->info
.info2
->devmode
= NULL
;
984 static bool test_PrinterInfo(struct torture_context
*tctx
,
985 struct dcerpc_pipe
*p
,
986 struct policy_handle
*handle
)
989 struct spoolss_SetPrinter s
;
990 struct spoolss_GetPrinter q
;
991 struct spoolss_GetPrinter q0
;
992 struct spoolss_SetPrinterInfoCtr info_ctr
;
993 union spoolss_PrinterInfo info
;
994 struct spoolss_DevmodeContainer devmode_ctr
;
995 struct sec_desc_buf secdesc_ctr
;
1000 uint32_t status_list
[] = {
1001 /* these do not stick
1002 PRINTER_STATUS_PAUSED,
1003 PRINTER_STATUS_ERROR,
1004 PRINTER_STATUS_PENDING_DELETION, */
1005 PRINTER_STATUS_PAPER_JAM
,
1006 PRINTER_STATUS_PAPER_OUT
,
1007 PRINTER_STATUS_MANUAL_FEED
,
1008 PRINTER_STATUS_PAPER_PROBLEM
,
1009 PRINTER_STATUS_OFFLINE
,
1010 PRINTER_STATUS_IO_ACTIVE
,
1011 PRINTER_STATUS_BUSY
,
1012 PRINTER_STATUS_PRINTING
,
1013 PRINTER_STATUS_OUTPUT_BIN_FULL
,
1014 PRINTER_STATUS_NOT_AVAILABLE
,
1015 PRINTER_STATUS_WAITING
,
1016 PRINTER_STATUS_PROCESSING
,
1017 PRINTER_STATUS_INITIALIZING
,
1018 PRINTER_STATUS_WARMING_UP
,
1019 PRINTER_STATUS_TONER_LOW
,
1020 PRINTER_STATUS_NO_TONER
,
1021 PRINTER_STATUS_PAGE_PUNT
,
1022 PRINTER_STATUS_USER_INTERVENTION
,
1023 PRINTER_STATUS_OUT_OF_MEMORY
,
1024 PRINTER_STATUS_DOOR_OPEN
,
1025 PRINTER_STATUS_SERVER_UNKNOWN
,
1026 PRINTER_STATUS_POWER_SAVE
,
1027 /* these do not stick
1036 uint32_t default_attribute
= PRINTER_ATTRIBUTE_LOCAL
;
1037 uint32_t attribute_list
[] = {
1038 PRINTER_ATTRIBUTE_QUEUED
,
1039 /* fails with WERR_INVALID_DATATYPE:
1040 PRINTER_ATTRIBUTE_DIRECT, */
1042 PRINTER_ATTRIBUTE_DEFAULT, */
1043 PRINTER_ATTRIBUTE_SHARED
,
1045 PRINTER_ATTRIBUTE_NETWORK, */
1046 PRINTER_ATTRIBUTE_HIDDEN
,
1047 PRINTER_ATTRIBUTE_LOCAL
,
1048 PRINTER_ATTRIBUTE_ENABLE_DEVQ
,
1049 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS
,
1050 PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST
,
1051 PRINTER_ATTRIBUTE_WORK_OFFLINE
,
1053 PRINTER_ATTRIBUTE_ENABLE_BIDI, */
1054 /* fails with WERR_INVALID_DATATYPE:
1055 PRINTER_ATTRIBUTE_RAW_ONLY, */
1056 /* these do not stick
1057 PRINTER_ATTRIBUTE_PUBLISHED,
1058 PRINTER_ATTRIBUTE_FAX,
1059 PRINTER_ATTRIBUTE_TS,
1078 ZERO_STRUCT(devmode_ctr
);
1079 ZERO_STRUCT(secdesc_ctr
);
1081 s
.in
.handle
= handle
;
1083 s
.in
.info_ctr
= &info_ctr
;
1084 s
.in
.devmode_ctr
= &devmode_ctr
;
1085 s
.in
.secdesc_ctr
= &secdesc_ctr
;
1087 q
.in
.handle
= handle
;
1091 #define TESTGETCALL(call, r) \
1092 r.in.buffer = NULL; \
1094 r.out.needed = &needed; \
1095 status = dcerpc_spoolss_ ##call(p, tctx, &r); \
1096 if (!NT_STATUS_IS_OK(status)) { \
1097 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1098 r.in.level, nt_errstr(status), __location__); \
1102 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\
1103 DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); \
1104 data_blob_clear(&blob); \
1105 r.in.buffer = &blob; \
1106 r.in.offered = needed; \
1108 status = dcerpc_spoolss_ ##call(p, tctx, &r); \
1109 if (!NT_STATUS_IS_OK(status)) { \
1110 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1111 r.in.level, nt_errstr(status), __location__); \
1115 if (!W_ERROR_IS_OK(r.out.result)) { \
1116 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1117 r.in.level, win_errstr(r.out.result), __location__); \
1123 #define TESTSETCALL_EXP(call, r, err) \
1124 clear_info2(&info_ctr);\
1125 status = dcerpc_spoolss_ ##call(p, tctx, &r); \
1126 if (!NT_STATUS_IS_OK(status)) { \
1127 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1128 r.in.info_ctr->level, nt_errstr(status), __location__); \
1132 if (!W_ERROR_IS_OK(err)) { \
1133 if (!W_ERROR_EQUAL(err, r.out.result)) { \
1134 torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \
1135 r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \
1140 if (!W_ERROR_IS_OK(r.out.result)) { \
1141 torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
1142 r.in.info_ctr->level, win_errstr(r.out.result), __location__); \
1147 #define TESTSETCALL(call, r) \
1148 TESTSETCALL_EXP(call, r, WERR_OK)
1150 #define STRING_EQUAL(s1, s2, field) \
1151 if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
1152 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1153 #field, s2, __location__); \
1158 #define MEM_EQUAL(s1, s2, length, field) \
1159 if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
1160 torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
1161 #field, (const char *)s2, __location__); \
1166 #define INT_EQUAL(i1, i2, field) \
1168 torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
1169 #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
1174 #define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \
1175 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1176 q.in.level = lvl1; \
1177 TESTGETCALL(GetPrinter, q) \
1178 info_ctr.level = lvl1; \
1179 info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
1180 info_ctr.info.info ## lvl1->field1 = value;\
1181 TESTSETCALL_EXP(SetPrinter, s, err) \
1182 info_ctr.info.info ## lvl1->field1 = ""; \
1183 TESTGETCALL(GetPrinter, q) \
1184 info_ctr.info.info ## lvl1->field1 = value; \
1185 STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \
1186 q.in.level = lvl2; \
1187 TESTGETCALL(GetPrinter, q) \
1188 info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
1189 STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \
1192 #define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \
1193 TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, WERR_OK); \
1196 #define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
1197 torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
1198 q.in.level = lvl1; \
1199 TESTGETCALL(GetPrinter, q) \
1200 info_ctr.level = lvl1; \
1201 info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
1202 info_ctr.info.info ## lvl1->field1 = value; \
1203 TESTSETCALL(SetPrinter, s) \
1204 info_ctr.info.info ## lvl1->field1 = 0; \
1205 TESTGETCALL(GetPrinter, q) \
1206 info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
1207 INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \
1208 q.in.level = lvl2; \
1209 TESTGETCALL(GetPrinter, q) \
1210 info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
1211 INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \
1214 #define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
1215 TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value); \
1219 do { TESTGETCALL(GetPrinter
, q0
) } while (0);
1221 TEST_PRINTERINFO_STRING(2, comment
, 1, comment
, "xx2-1 comment");
1222 TEST_PRINTERINFO_STRING(2, comment
, 2, comment
, "xx2-2 comment");
1224 /* level 0 printername does not stick */
1225 /* TEST_PRINTERINFO_STRING(2, printername, 0, printername, "xx2-0 printer"); */
1226 TEST_PRINTERINFO_STRING(2, printername
, 1, name
, "xx2-1 printer");
1227 TEST_PRINTERINFO_STRING(2, printername
, 2, printername
, "xx2-2 printer");
1228 TEST_PRINTERINFO_STRING(2, printername
, 4, printername
, "xx2-4 printer");
1229 TEST_PRINTERINFO_STRING(2, printername
, 5, printername
, "xx2-5 printer");
1230 /* TEST_PRINTERINFO_STRING(4, printername, 0, printername, "xx4-0 printer"); */
1231 TEST_PRINTERINFO_STRING(4, printername
, 1, name
, "xx4-1 printer");
1232 TEST_PRINTERINFO_STRING(4, printername
, 2, printername
, "xx4-2 printer");
1233 TEST_PRINTERINFO_STRING(4, printername
, 4, printername
, "xx4-4 printer");
1234 TEST_PRINTERINFO_STRING(4, printername
, 5, printername
, "xx4-5 printer");
1235 /* TEST_PRINTERINFO_STRING(5, printername, 0, printername, "xx5-0 printer"); */
1236 TEST_PRINTERINFO_STRING(5, printername
, 1, name
, "xx5-1 printer");
1237 TEST_PRINTERINFO_STRING(5, printername
, 2, printername
, "xx5-2 printer");
1238 TEST_PRINTERINFO_STRING(5, printername
, 4, printername
, "xx5-4 printer");
1239 TEST_PRINTERINFO_STRING(5, printername
, 5, printername
, "xx5-5 printer");
1241 /* servername can be set but does not stick
1242 TEST_PRINTERINFO_STRING(2, servername, 0, servername, "xx2-0 servername");
1243 TEST_PRINTERINFO_STRING(2, servername, 2, servername, "xx2-2 servername");
1244 TEST_PRINTERINFO_STRING(2, servername, 4, servername, "xx2-4 servername");
1247 /* passing an invalid port will result in WERR_UNKNOWN_PORT */
1248 TEST_PRINTERINFO_STRING_EXP_ERR(2, portname
, 2, portname
, "xx2-2 portname", WERR_UNKNOWN_PORT
);
1249 TEST_PRINTERINFO_STRING_EXP_ERR(2, portname
, 5, portname
, "xx2-5 portname", WERR_UNKNOWN_PORT
);
1250 TEST_PRINTERINFO_STRING_EXP_ERR(5, portname
, 2, portname
, "xx5-2 portname", WERR_UNKNOWN_PORT
);
1251 TEST_PRINTERINFO_STRING_EXP_ERR(5, portname
, 5, portname
, "xx5-5 portname", WERR_UNKNOWN_PORT
);
1253 TEST_PRINTERINFO_STRING(2, sharename
, 2, sharename
, "xx2-2 sharename");
1254 /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
1255 TEST_PRINTERINFO_STRING_EXP_ERR(2, drivername
, 2, drivername
, "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER
);
1256 TEST_PRINTERINFO_STRING(2, location
, 2, location
, "xx2-2 location");
1257 /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
1258 TEST_PRINTERINFO_STRING_EXP_ERR(2, sepfile
, 2, sepfile
, "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE
);
1259 /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
1260 TEST_PRINTERINFO_STRING_EXP_ERR(2, printprocessor
, 2, printprocessor
, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR
);
1261 TEST_PRINTERINFO_STRING(2, datatype
, 2, datatype
, "xx2-2 datatype");
1262 TEST_PRINTERINFO_STRING(2, parameters
, 2, parameters
, "xx2-2 parameters");
1264 for (i
=0; i
< ARRAY_SIZE(attribute_list
); i
++) {
1265 /* TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags,
1267 (attribute_list[i] | default_attribute)
1269 TEST_PRINTERINFO_INT_EXP(2, attributes
, 2, attributes
,
1271 (attribute_list
[i
] | default_attribute
)
1273 TEST_PRINTERINFO_INT_EXP(2, attributes
, 4, attributes
,
1275 (attribute_list
[i
] | default_attribute
)
1277 TEST_PRINTERINFO_INT_EXP(2, attributes
, 5, attributes
,
1279 (attribute_list
[i
] | default_attribute
)
1281 /* TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags,
1283 (attribute_list[i] | default_attribute)
1285 TEST_PRINTERINFO_INT_EXP(4, attributes
, 2, attributes
,
1287 (attribute_list
[i
] | default_attribute
)
1289 TEST_PRINTERINFO_INT_EXP(4, attributes
, 4, attributes
,
1291 (attribute_list
[i
] | default_attribute
)
1293 TEST_PRINTERINFO_INT_EXP(4, attributes
, 5, attributes
,
1295 (attribute_list
[i
] | default_attribute
)
1297 /* TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags,
1299 (attribute_list[i] | default_attribute)
1301 TEST_PRINTERINFO_INT_EXP(5, attributes
, 2, attributes
,
1303 (attribute_list
[i
] | default_attribute
)
1305 TEST_PRINTERINFO_INT_EXP(5, attributes
, 4, attributes
,
1307 (attribute_list
[i
] | default_attribute
)
1309 TEST_PRINTERINFO_INT_EXP(5, attributes
, 5, attributes
,
1311 (attribute_list
[i
] | default_attribute
)
1315 for (i
=0; i
< ARRAY_SIZE(status_list
); i
++) {
1316 /* level 2 sets do not stick
1317 TEST_PRINTERINFO_INT(2, status, 0, status, status_list[i]);
1318 TEST_PRINTERINFO_INT(2, status, 2, status, status_list[i]);
1319 TEST_PRINTERINFO_INT(2, status, 6, status, status_list[i]); */
1320 TEST_PRINTERINFO_INT(6, status
, 0, status
, status_list
[i
]);
1321 TEST_PRINTERINFO_INT(6, status
, 2, status
, status_list
[i
]);
1322 TEST_PRINTERINFO_INT(6, status
, 6, status
, status_list
[i
]);
1325 /* priorities need to be between 0 and 99
1326 passing an invalid priority will result in WERR_INVALID_PRIORITY */
1327 TEST_PRINTERINFO_INT(2, priority
, 2, priority
, 0);
1328 TEST_PRINTERINFO_INT(2, priority
, 2, priority
, 1);
1329 TEST_PRINTERINFO_INT(2, priority
, 2, priority
, 99);
1330 /* TEST_PRINTERINFO_INT(2, priority, 2, priority, 100); */
1331 TEST_PRINTERINFO_INT(2, defaultpriority
,2, defaultpriority
, 0);
1332 TEST_PRINTERINFO_INT(2, defaultpriority
,2, defaultpriority
, 1);
1333 TEST_PRINTERINFO_INT(2, defaultpriority
,2, defaultpriority
, 99);
1334 /* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */
1336 TEST_PRINTERINFO_INT(2, starttime
, 2, starttime
, __LINE__
);
1337 TEST_PRINTERINFO_INT(2, untiltime
, 2, untiltime
, __LINE__
);
1340 TEST_PRINTERINFO_INT(2, cjobs, 2, cjobs, __LINE__);
1341 TEST_PRINTERINFO_INT(2, averageppm, 2, averageppm, __LINE__); */
1344 TEST_PRINTERINFO_INT(5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__);
1345 TEST_PRINTERINFO_INT(5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */
1347 /* FIXME: gd also test devmode and secdesc behavior */
1350 /* verify composition of level 1 description field */
1351 const char *description
;
1355 do { TESTGETCALL(GetPrinter
, q0
) } while (0);
1357 description
= talloc_strdup(tctx
, q0
.out
.info
->info1
.description
);
1360 do { TESTGETCALL(GetPrinter
, q0
) } while (0);
1362 tmp
= talloc_asprintf(tctx
, "%s,%s,%s",
1363 q0
.out
.info
->info2
.printername
,
1364 q0
.out
.info
->info2
.drivername
,
1365 q0
.out
.info
->info2
.location
);
1367 do { STRING_EQUAL(description
, tmp
, "description")} while (0);
1374 static bool test_ClosePrinter(struct torture_context
*tctx
,
1375 struct dcerpc_pipe
*p
,
1376 struct policy_handle
*handle
)
1379 struct spoolss_ClosePrinter r
;
1381 r
.in
.handle
= handle
;
1382 r
.out
.handle
= handle
;
1384 torture_comment(tctx
, "Testing ClosePrinter\n");
1386 status
= dcerpc_spoolss_ClosePrinter(p
, tctx
, &r
);
1387 torture_assert_ntstatus_ok(tctx
, status
, "ClosePrinter failed");
1392 static bool test_GetForm(struct torture_context
*tctx
,
1393 struct dcerpc_pipe
*p
,
1394 struct policy_handle
*handle
,
1395 const char *form_name
,
1399 struct spoolss_GetForm r
;
1402 r
.in
.handle
= handle
;
1403 r
.in
.form_name
= form_name
;
1407 r
.out
.needed
= &needed
;
1409 torture_comment(tctx
, "Testing GetForm level %d\n", r
.in
.level
);
1411 status
= dcerpc_spoolss_GetForm(p
, tctx
, &r
);
1412 torture_assert_ntstatus_ok(tctx
, status
, "GetForm failed");
1414 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1415 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1416 data_blob_clear(&blob
);
1417 r
.in
.buffer
= &blob
;
1418 r
.in
.offered
= needed
;
1419 status
= dcerpc_spoolss_GetForm(p
, tctx
, &r
);
1420 torture_assert_ntstatus_ok(tctx
, status
, "GetForm failed");
1422 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetForm failed");
1424 torture_assert(tctx
, r
.out
.info
, "No form info returned");
1427 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetForm failed");
1432 static bool test_EnumForms(struct torture_context
*tctx
,
1433 struct dcerpc_pipe
*p
,
1434 struct policy_handle
*handle
, bool print_server
)
1437 struct spoolss_EnumForms r
;
1441 uint32_t levels
[] = { 1, 2 };
1444 for (i
=0; i
<ARRAY_SIZE(levels
); i
++) {
1446 union spoolss_FormInfo
*info
;
1448 r
.in
.handle
= handle
;
1449 r
.in
.level
= levels
[i
];
1452 r
.out
.needed
= &needed
;
1453 r
.out
.count
= &count
;
1456 torture_comment(tctx
, "Testing EnumForms level %d\n", levels
[i
]);
1458 status
= dcerpc_spoolss_EnumForms(p
, tctx
, &r
);
1459 torture_assert_ntstatus_ok(tctx
, status
, "EnumForms failed");
1461 if ((r
.in
.level
== 2) && (W_ERROR_EQUAL(r
.out
.result
, WERR_UNKNOWN_LEVEL
))) {
1465 if (print_server
&& W_ERROR_EQUAL(r
.out
.result
, WERR_BADFID
))
1466 torture_fail(tctx
, "EnumForms on the PrintServer isn't supported by test server (NT4)");
1468 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1470 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1471 data_blob_clear(&blob
);
1472 r
.in
.buffer
= &blob
;
1473 r
.in
.offered
= needed
;
1475 status
= dcerpc_spoolss_EnumForms(p
, tctx
, &r
);
1477 torture_assert(tctx
, info
, "No forms returned");
1479 for (j
= 0; j
< count
; j
++) {
1481 ret
&= test_GetForm(tctx
, p
, handle
, info
[j
].info1
.form_name
, levels
[i
]);
1485 torture_assert_ntstatus_ok(tctx
, status
, "EnumForms failed");
1487 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumForms failed");
1493 static bool test_DeleteForm(struct torture_context
*tctx
,
1494 struct dcerpc_pipe
*p
,
1495 struct policy_handle
*handle
,
1496 const char *form_name
)
1499 struct spoolss_DeleteForm r
;
1501 r
.in
.handle
= handle
;
1502 r
.in
.form_name
= form_name
;
1504 status
= dcerpc_spoolss_DeleteForm(p
, tctx
, &r
);
1506 torture_assert_ntstatus_ok(tctx
, status
, "DeleteForm failed");
1508 torture_assert_werr_ok(tctx
, r
.out
.result
, "DeleteForm failed");
1513 static bool test_AddForm(struct torture_context
*tctx
,
1514 struct dcerpc_pipe
*p
,
1515 struct policy_handle
*handle
, bool print_server
)
1517 struct spoolss_AddForm r
;
1518 struct spoolss_AddFormInfo1 addform
;
1519 const char *form_name
= "testform3";
1523 r
.in
.handle
= handle
;
1525 r
.in
.info
.info1
= &addform
;
1526 addform
.flags
= SPOOLSS_FORM_USER
;
1527 addform
.form_name
= form_name
;
1528 addform
.size
.width
= 50;
1529 addform
.size
.height
= 25;
1530 addform
.area
.left
= 5;
1531 addform
.area
.top
= 10;
1532 addform
.area
.right
= 45;
1533 addform
.area
.bottom
= 15;
1535 status
= dcerpc_spoolss_AddForm(p
, tctx
, &r
);
1537 torture_assert_ntstatus_ok(tctx
, status
, "AddForm failed");
1539 torture_assert_werr_ok(tctx
, r
.out
.result
, "AddForm failed");
1541 if (!print_server
) ret
&= test_GetForm(tctx
, p
, handle
, form_name
, 1);
1544 struct spoolss_SetForm sf
;
1545 struct spoolss_AddFormInfo1 setform
;
1547 sf
.in
.handle
= handle
;
1548 sf
.in
.form_name
= form_name
;
1550 sf
.in
.info
.info1
= &setform
;
1551 setform
.flags
= addform
.flags
;
1552 setform
.form_name
= addform
.form_name
;
1553 setform
.size
= addform
.size
;
1554 setform
.area
= addform
.area
;
1556 setform
.size
.width
= 1234;
1558 status
= dcerpc_spoolss_SetForm(p
, tctx
, &sf
);
1560 torture_assert_ntstatus_ok(tctx
, status
, "SetForm failed");
1562 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetForm failed");
1565 if (!print_server
) ret
&= test_GetForm(tctx
, p
, handle
, form_name
, 1);
1568 struct spoolss_EnumForms e
;
1569 union spoolss_FormInfo
*info
;
1574 e
.in
.handle
= handle
;
1578 e
.out
.needed
= &needed
;
1579 e
.out
.count
= &count
;
1582 torture_comment(tctx
, "Testing EnumForms level 1\n");
1584 status
= dcerpc_spoolss_EnumForms(p
, tctx
, &e
);
1585 torture_assert_ntstatus_ok(tctx
, status
, "EnumForms failed");
1587 if (print_server
&& W_ERROR_EQUAL(e
.out
.result
, WERR_BADFID
))
1588 torture_fail(tctx
, "EnumForms on the PrintServer isn't supported by test server (NT4)");
1590 if (W_ERROR_EQUAL(e
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1592 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1593 data_blob_clear(&blob
);
1594 e
.in
.buffer
= &blob
;
1595 e
.in
.offered
= needed
;
1597 status
= dcerpc_spoolss_EnumForms(p
, tctx
, &e
);
1599 torture_assert(tctx
, info
, "No forms returned");
1601 for (j
= 0; j
< count
; j
++) {
1602 if (strequal(form_name
, info
[j
].info1
.form_name
)) {
1608 torture_assert(tctx
, found
, "Newly added form not found in enum call");
1611 if (!test_DeleteForm(tctx
, p
, handle
, form_name
)) {
1618 static bool test_EnumPorts_old(struct torture_context
*tctx
,
1619 struct dcerpc_pipe
*p
)
1622 struct spoolss_EnumPorts r
;
1625 union spoolss_PortInfo
*info
;
1627 r
.in
.servername
= talloc_asprintf(tctx
, "\\\\%s",
1628 dcerpc_server_name(p
));
1632 r
.out
.needed
= &needed
;
1633 r
.out
.count
= &count
;
1636 torture_comment(tctx
, "Testing EnumPorts\n");
1638 status
= dcerpc_spoolss_EnumPorts(p
, tctx
, &r
);
1640 torture_assert_ntstatus_ok(tctx
, status
, "EnumPorts failed");
1642 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1643 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1644 data_blob_clear(&blob
);
1645 r
.in
.buffer
= &blob
;
1646 r
.in
.offered
= needed
;
1648 status
= dcerpc_spoolss_EnumPorts(p
, tctx
, &r
);
1649 torture_assert_ntstatus_ok(tctx
, status
, "EnumPorts failed");
1651 torture_assert(tctx
, info
, "No ports returned");
1657 static bool test_AddPort(struct torture_context
*tctx
,
1658 struct dcerpc_pipe
*p
)
1661 struct spoolss_AddPort r
;
1663 r
.in
.server_name
= talloc_asprintf(tctx
, "\\\\%s",
1664 dcerpc_server_name(p
));
1666 r
.in
.monitor_name
= "foo";
1668 torture_comment(tctx
, "Testing AddPort\n");
1670 status
= dcerpc_spoolss_AddPort(p
, tctx
, &r
);
1672 torture_assert_ntstatus_ok(tctx
, status
, "AddPort failed");
1674 /* win2k3 returns WERR_NOT_SUPPORTED */
1678 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1679 printf("AddPort failed - %s\n", win_errstr(r
.out
.result
));
1688 static bool test_GetJob(struct torture_context
*tctx
,
1689 struct dcerpc_pipe
*p
,
1690 struct policy_handle
*handle
, uint32_t job_id
)
1693 struct spoolss_GetJob r
;
1694 union spoolss_JobInfo info
;
1696 uint32_t levels
[] = {1, 2 /* 3, 4 */};
1699 r
.in
.handle
= handle
;
1700 r
.in
.job_id
= job_id
;
1704 r
.out
.needed
= &needed
;
1707 torture_comment(tctx
, "Testing GetJob level %d\n", r
.in
.level
);
1709 status
= dcerpc_spoolss_GetJob(p
, tctx
, &r
);
1710 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
, "Unexpected return code");
1712 for (i
= 0; i
< ARRAY_SIZE(levels
); i
++) {
1714 torture_comment(tctx
, "Testing GetJob level %d\n", r
.in
.level
);
1718 r
.in
.level
= levels
[i
];
1722 status
= dcerpc_spoolss_GetJob(p
, tctx
, &r
);
1723 torture_assert_ntstatus_ok(tctx
, status
, "GetJob failed");
1725 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1726 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1727 data_blob_clear(&blob
);
1728 r
.in
.buffer
= &blob
;
1729 r
.in
.offered
= needed
;
1731 status
= dcerpc_spoolss_GetJob(p
, tctx
, &r
);
1732 torture_assert_ntstatus_ok(tctx
, status
, "GetJob failed");
1735 torture_assert(tctx
, r
.out
.info
, "No job info returned");
1736 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetJob failed");
1742 static bool test_SetJob(struct torture_context
*tctx
,
1743 struct dcerpc_pipe
*p
,
1744 struct policy_handle
*handle
, uint32_t job_id
,
1745 enum spoolss_JobControl command
)
1748 struct spoolss_SetJob r
;
1750 r
.in
.handle
= handle
;
1751 r
.in
.job_id
= job_id
;
1753 r
.in
.command
= command
;
1756 case SPOOLSS_JOB_CONTROL_PAUSE
:
1757 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_PAUSE\n");
1759 case SPOOLSS_JOB_CONTROL_RESUME
:
1760 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_RESUME\n");
1762 case SPOOLSS_JOB_CONTROL_CANCEL
:
1763 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_CANCEL\n");
1765 case SPOOLSS_JOB_CONTROL_RESTART
:
1766 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_RESTART\n");
1768 case SPOOLSS_JOB_CONTROL_DELETE
:
1769 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_DELETE\n");
1771 case SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER
:
1772 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER\n");
1774 case SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED
:
1775 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED\n");
1777 case SPOOLSS_JOB_CONTROL_RETAIN
:
1778 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_RETAIN\n");
1780 case SPOOLSS_JOB_CONTROL_RELEASE
:
1781 torture_comment(tctx
, "Testing SetJob: SPOOLSS_JOB_CONTROL_RELEASE\n");
1784 torture_comment(tctx
, "Testing SetJob\n");
1788 status
= dcerpc_spoolss_SetJob(p
, tctx
, &r
);
1789 torture_assert_ntstatus_ok(tctx
, status
, "SetJob failed");
1790 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetJob failed");
1795 static bool test_AddJob(struct torture_context
*tctx
,
1796 struct dcerpc_pipe
*p
,
1797 struct policy_handle
*handle
)
1800 struct spoolss_AddJob r
;
1804 r
.in
.handle
= handle
;
1806 r
.out
.needed
= &needed
;
1807 r
.in
.buffer
= r
.out
.buffer
= NULL
;
1809 torture_comment(tctx
, "Testing AddJob\n");
1811 status
= dcerpc_spoolss_AddJob(p
, tctx
, &r
);
1812 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_UNKNOWN_LEVEL
, "AddJob failed");
1816 status
= dcerpc_spoolss_AddJob(p
, tctx
, &r
);
1817 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
, "AddJob failed");
1823 static bool test_EnumJobs(struct torture_context
*tctx
,
1824 struct dcerpc_pipe
*p
,
1825 struct policy_handle
*handle
)
1828 struct spoolss_EnumJobs r
;
1831 union spoolss_JobInfo
*info
;
1833 r
.in
.handle
= handle
;
1835 r
.in
.numjobs
= 0xffffffff;
1839 r
.out
.needed
= &needed
;
1840 r
.out
.count
= &count
;
1843 torture_comment(tctx
, "Testing EnumJobs\n");
1845 status
= dcerpc_spoolss_EnumJobs(p
, tctx
, &r
);
1847 torture_assert_ntstatus_ok(tctx
, status
, "EnumJobs failed");
1849 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1851 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
1852 data_blob_clear(&blob
);
1853 r
.in
.buffer
= &blob
;
1854 r
.in
.offered
= needed
;
1856 status
= dcerpc_spoolss_EnumJobs(p
, tctx
, &r
);
1858 torture_assert(tctx
, info
, "No jobs returned");
1860 for (j
= 0; j
< count
; j
++) {
1862 test_GetJob(tctx
, p
, handle
, info
[j
].info1
.job_id
);
1865 if (!torture_setting_bool(tctx
, "samba3", false)) {
1866 test_SetJob(tctx
, p
, handle
, info
[j
].info1
.job_id
, SPOOLSS_JOB_CONTROL_PAUSE
);
1867 test_SetJob(tctx
, p
, handle
, info
[j
].info1
.job_id
, SPOOLSS_JOB_CONTROL_RESUME
);
1872 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumJobs failed");
1878 static bool test_DoPrintTest(struct torture_context
*tctx
,
1879 struct dcerpc_pipe
*p
,
1880 struct policy_handle
*handle
)
1884 struct spoolss_StartDocPrinter s
;
1885 struct spoolss_DocumentInfo1 info1
;
1886 struct spoolss_StartPagePrinter sp
;
1887 struct spoolss_WritePrinter w
;
1888 struct spoolss_EndPagePrinter ep
;
1889 struct spoolss_EndDocPrinter e
;
1892 uint32_t num_written
;
1894 torture_comment(tctx
, "Testing StartDocPrinter\n");
1896 s
.in
.handle
= handle
;
1898 s
.in
.info
.info1
= &info1
;
1899 s
.out
.job_id
= &job_id
;
1900 info1
.document_name
= "TorturePrintJob";
1901 info1
.output_file
= NULL
;
1902 info1
.datatype
= "RAW";
1904 status
= dcerpc_spoolss_StartDocPrinter(p
, tctx
, &s
);
1905 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_StartDocPrinter failed");
1906 torture_assert_werr_ok(tctx
, s
.out
.result
, "StartDocPrinter failed");
1908 for (i
=1; i
< 4; i
++) {
1909 torture_comment(tctx
, "Testing StartPagePrinter: Page[%d]\n", i
);
1911 sp
.in
.handle
= handle
;
1913 status
= dcerpc_spoolss_StartPagePrinter(p
, tctx
, &sp
);
1914 torture_assert_ntstatus_ok(tctx
, status
,
1915 "dcerpc_spoolss_StartPagePrinter failed");
1916 torture_assert_werr_ok(tctx
, sp
.out
.result
, "StartPagePrinter failed");
1918 torture_comment(tctx
, "Testing WritePrinter: Page[%d]\n", i
);
1920 w
.in
.handle
= handle
;
1921 w
.in
.data
= data_blob_string_const(talloc_asprintf(tctx
,"TortureTestPage: %d\nData\n",i
));
1922 w
.out
.num_written
= &num_written
;
1924 status
= dcerpc_spoolss_WritePrinter(p
, tctx
, &w
);
1925 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_WritePrinter failed");
1926 torture_assert_werr_ok(tctx
, w
.out
.result
, "WritePrinter failed");
1928 torture_comment(tctx
, "Testing EndPagePrinter: Page[%d]\n", i
);
1930 ep
.in
.handle
= handle
;
1932 status
= dcerpc_spoolss_EndPagePrinter(p
, tctx
, &ep
);
1933 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EndPagePrinter failed");
1934 torture_assert_werr_ok(tctx
, ep
.out
.result
, "EndPagePrinter failed");
1937 torture_comment(tctx
, "Testing EndDocPrinter\n");
1939 e
.in
.handle
= handle
;
1941 status
= dcerpc_spoolss_EndDocPrinter(p
, tctx
, &e
);
1942 torture_assert_ntstatus_ok(tctx
, status
, "dcerpc_spoolss_EndDocPrinter failed");
1943 torture_assert_werr_ok(tctx
, e
.out
.result
, "EndDocPrinter failed");
1945 ret
&= test_AddJob(tctx
, p
, handle
);
1946 ret
&= test_EnumJobs(tctx
, p
, handle
);
1948 ret
&= test_SetJob(tctx
, p
, handle
, job_id
, SPOOLSS_JOB_CONTROL_DELETE
);
1953 static bool test_PausePrinter(struct torture_context
*tctx
,
1954 struct dcerpc_pipe
*p
,
1955 struct policy_handle
*handle
)
1958 struct spoolss_SetPrinter r
;
1959 struct spoolss_SetPrinterInfoCtr info_ctr
;
1960 struct spoolss_DevmodeContainer devmode_ctr
;
1961 struct sec_desc_buf secdesc_ctr
;
1964 info_ctr
.info
.info0
= NULL
;
1966 ZERO_STRUCT(devmode_ctr
);
1967 ZERO_STRUCT(secdesc_ctr
);
1969 r
.in
.handle
= handle
;
1970 r
.in
.info_ctr
= &info_ctr
;
1971 r
.in
.devmode_ctr
= &devmode_ctr
;
1972 r
.in
.secdesc_ctr
= &secdesc_ctr
;
1973 r
.in
.command
= SPOOLSS_PRINTER_CONTROL_PAUSE
;
1975 torture_comment(tctx
, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1977 status
= dcerpc_spoolss_SetPrinter(p
, tctx
, &r
);
1979 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinter failed");
1981 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetPrinter failed");
1986 static bool test_ResumePrinter(struct torture_context
*tctx
,
1987 struct dcerpc_pipe
*p
,
1988 struct policy_handle
*handle
)
1991 struct spoolss_SetPrinter r
;
1992 struct spoolss_SetPrinterInfoCtr info_ctr
;
1993 struct spoolss_DevmodeContainer devmode_ctr
;
1994 struct sec_desc_buf secdesc_ctr
;
1997 info_ctr
.info
.info0
= NULL
;
1999 ZERO_STRUCT(devmode_ctr
);
2000 ZERO_STRUCT(secdesc_ctr
);
2002 r
.in
.handle
= handle
;
2003 r
.in
.info_ctr
= &info_ctr
;
2004 r
.in
.devmode_ctr
= &devmode_ctr
;
2005 r
.in
.secdesc_ctr
= &secdesc_ctr
;
2006 r
.in
.command
= SPOOLSS_PRINTER_CONTROL_RESUME
;
2008 torture_comment(tctx
, "Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
2010 status
= dcerpc_spoolss_SetPrinter(p
, tctx
, &r
);
2012 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinter failed");
2014 torture_assert_werr_ok(tctx
, r
.out
.result
, "SetPrinter failed");
2019 static bool test_GetPrinterData(struct torture_context
*tctx
,
2020 struct dcerpc_pipe
*p
,
2021 struct policy_handle
*handle
,
2022 const char *value_name
)
2025 struct spoolss_GetPrinterData r
;
2027 enum winreg_Type type
;
2028 union spoolss_PrinterData data
;
2030 r
.in
.handle
= handle
;
2031 r
.in
.value_name
= value_name
;
2033 r
.out
.needed
= &needed
;
2037 torture_comment(tctx
, "Testing GetPrinterData\n");
2039 status
= dcerpc_spoolss_GetPrinterData(p
, tctx
, &r
);
2040 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterData failed");
2042 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
2043 r
.in
.offered
= needed
;
2045 status
= dcerpc_spoolss_GetPrinterData(p
, tctx
, &r
);
2046 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterData failed");
2048 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinterData failed");
2054 static bool test_GetPrinterDataEx(struct torture_context
*tctx
,
2055 struct dcerpc_pipe
*p
,
2056 struct policy_handle
*handle
,
2057 const char *key_name
,
2058 const char *value_name
)
2061 struct spoolss_GetPrinterDataEx r
;
2062 enum winreg_Type type
;
2065 r
.in
.handle
= handle
;
2066 r
.in
.key_name
= key_name
;
2067 r
.in
.value_name
= value_name
;
2070 r
.out
.needed
= &needed
;
2071 r
.out
.buffer
= NULL
;
2073 torture_comment(tctx
, "Testing GetPrinterDataEx\n");
2075 status
= dcerpc_spoolss_GetPrinterDataEx(p
, tctx
, &r
);
2076 if (!NT_STATUS_IS_OK(status
)) {
2077 if (NT_STATUS_EQUAL(status
,NT_STATUS_NET_WRITE_FAULT
) &&
2078 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
2079 torture_skip(tctx
, "GetPrinterDataEx not supported by server\n");
2081 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterDataEx failed");
2084 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
2085 r
.in
.offered
= needed
;
2086 r
.out
.buffer
= talloc_array(tctx
, uint8_t, needed
);
2088 status
= dcerpc_spoolss_GetPrinterDataEx(p
, tctx
, &r
);
2089 torture_assert_ntstatus_ok(tctx
, status
, "GetPrinterDataEx failed");
2091 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetPrinterDataEx failed");
2097 static bool test_EnumPrinterData(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
2098 struct policy_handle
*handle
)
2101 struct spoolss_EnumPrinterData r
;
2104 r
.in
.handle
= handle
;
2105 r
.in
.enum_index
= 0;
2108 uint32_t value_size
= 0;
2109 uint32_t data_size
= 0;
2110 enum winreg_Type type
= 0;
2112 r
.in
.value_offered
= value_size
;
2113 r
.out
.value_needed
= &value_size
;
2114 r
.in
.data_offered
= data_size
;
2115 r
.out
.data_needed
= &data_size
;
2118 r
.out
.data
= talloc_zero_array(tctx
, uint8_t, 0);
2120 torture_comment(tctx
, "Testing EnumPrinterData\n");
2122 status
= dcerpc_spoolss_EnumPrinterData(p
, tctx
, &r
);
2124 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterData failed");
2126 r
.in
.value_offered
= value_size
;
2127 r
.out
.value_name
= talloc_zero_array(tctx
, const char, value_size
);
2128 r
.in
.data_offered
= data_size
;
2129 r
.out
.data
= talloc_zero_array(tctx
, uint8_t, data_size
);
2131 status
= dcerpc_spoolss_EnumPrinterData(p
, tctx
, &r
);
2133 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterData failed");
2135 test_GetPrinterData(tctx
, p
, handle
, r
.out
.value_name
);
2137 test_GetPrinterDataEx(tctx
,
2138 p
, handle
, "PrinterDriverData",
2143 } while (W_ERROR_IS_OK(r
.out
.result
));
2148 static bool test_EnumPrinterDataEx(struct torture_context
*tctx
,
2149 struct dcerpc_pipe
*p
,
2150 struct policy_handle
*handle
)
2153 struct spoolss_EnumPrinterDataEx r
;
2154 struct spoolss_PrinterEnumValues
*info
;
2158 r
.in
.handle
= handle
;
2159 r
.in
.key_name
= "PrinterDriverData";
2161 r
.out
.needed
= &needed
;
2162 r
.out
.count
= &count
;
2165 torture_comment(tctx
, "Testing EnumPrinterDataEx\n");
2167 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, tctx
, &r
);
2168 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDataEx failed");
2170 r
.in
.offered
= needed
;
2172 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, tctx
, &r
);
2174 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDataEx failed");
2180 static bool test_DeletePrinterData(struct torture_context
*tctx
,
2181 struct dcerpc_pipe
*p
,
2182 struct policy_handle
*handle
,
2183 const char *value_name
)
2186 struct spoolss_DeletePrinterData r
;
2188 r
.in
.handle
= handle
;
2189 r
.in
.value_name
= value_name
;
2191 torture_comment(tctx
, "Testing DeletePrinterData\n");
2193 status
= dcerpc_spoolss_DeletePrinterData(p
, tctx
, &r
);
2195 torture_assert_ntstatus_ok(tctx
, status
, "DeletePrinterData failed");
2200 static bool test_SetPrinterData(struct torture_context
*tctx
,
2201 struct dcerpc_pipe
*p
,
2202 struct policy_handle
*handle
)
2205 struct spoolss_SetPrinterData r
;
2206 const char *value_name
= "spottyfoot";
2208 r
.in
.handle
= handle
;
2209 r
.in
.value_name
= value_name
;
2211 r
.in
.data
.string
= "dog";
2213 torture_comment(tctx
, "Testing SetPrinterData\n");
2215 status
= dcerpc_spoolss_SetPrinterData(p
, tctx
, &r
);
2217 torture_assert_ntstatus_ok(tctx
, status
, "SetPrinterData failed");
2219 if (!test_GetPrinterData(tctx
, p
, handle
, value_name
)) {
2223 if (!test_DeletePrinterData(tctx
, p
, handle
, value_name
)) {
2230 static bool test_SecondaryClosePrinter(struct torture_context
*tctx
,
2231 struct dcerpc_pipe
*p
,
2232 struct policy_handle
*handle
)
2235 struct dcerpc_binding
*b
;
2236 struct dcerpc_pipe
*p2
;
2237 struct spoolss_ClosePrinter cp
;
2239 /* only makes sense on SMB */
2240 if (p
->conn
->transport
.transport
!= NCACN_NP
) {
2244 torture_comment(tctx
, "testing close on secondary pipe\n");
2246 status
= dcerpc_parse_binding(tctx
, p
->conn
->binding_string
, &b
);
2247 torture_assert_ntstatus_ok(tctx
, status
, "Failed to parse dcerpc binding");
2249 status
= dcerpc_secondary_connection(p
, &p2
, b
);
2250 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create secondary connection");
2252 status
= dcerpc_bind_auth_none(p2
, &ndr_table_spoolss
);
2253 torture_assert_ntstatus_ok(tctx
, status
, "Failed to create bind on secondary connection");
2255 cp
.in
.handle
= handle
;
2256 cp
.out
.handle
= handle
;
2258 status
= dcerpc_spoolss_ClosePrinter(p2
, tctx
, &cp
);
2259 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_NET_WRITE_FAULT
,
2260 "ERROR: Allowed close on secondary connection");
2262 torture_assert_int_equal(tctx
, p2
->last_fault_code
, DCERPC_FAULT_CONTEXT_MISMATCH
,
2263 "Unexpected fault code");
2270 static bool test_OpenPrinter_badname(struct torture_context
*tctx
,
2271 struct dcerpc_pipe
*p
, const char *name
)
2274 struct spoolss_OpenPrinter op
;
2275 struct spoolss_OpenPrinterEx opEx
;
2276 struct policy_handle handle
;
2279 op
.in
.printername
= name
;
2280 op
.in
.datatype
= NULL
;
2281 op
.in
.devmode_ctr
.devmode
= NULL
;
2282 op
.in
.access_mask
= 0;
2283 op
.out
.handle
= &handle
;
2285 torture_comment(tctx
, "\nTesting OpenPrinter(%s) with bad name\n", op
.in
.printername
);
2287 status
= dcerpc_spoolss_OpenPrinter(p
, tctx
, &op
);
2288 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinter failed");
2289 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,op
.out
.result
)) {
2290 torture_comment(tctx
, "OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
2291 name
, win_errstr(op
.out
.result
));
2294 if (W_ERROR_IS_OK(op
.out
.result
)) {
2295 ret
&=test_ClosePrinter(tctx
, p
, &handle
);
2298 opEx
.in
.printername
= name
;
2299 opEx
.in
.datatype
= NULL
;
2300 opEx
.in
.devmode_ctr
.devmode
= NULL
;
2301 opEx
.in
.access_mask
= 0;
2303 opEx
.in
.userlevel
.level1
= NULL
;
2304 opEx
.out
.handle
= &handle
;
2306 torture_comment(tctx
, "Testing OpenPrinterEx(%s) with bad name\n", opEx
.in
.printername
);
2308 status
= dcerpc_spoolss_OpenPrinterEx(p
, tctx
, &opEx
);
2309 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinterEx failed");
2310 if (!W_ERROR_EQUAL(WERR_INVALID_PARAM
,opEx
.out
.result
)) {
2311 torture_comment(tctx
, "OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PARAM\n",
2312 name
, win_errstr(opEx
.out
.result
));
2315 if (W_ERROR_IS_OK(opEx
.out
.result
)) {
2316 ret
&=test_ClosePrinter(tctx
, p
, &handle
);
2322 static bool test_OpenPrinter(struct torture_context
*tctx
,
2323 struct dcerpc_pipe
*p
,
2327 struct spoolss_OpenPrinter r
;
2328 struct policy_handle handle
;
2331 r
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s\\%s", dcerpc_server_name(p
), name
);
2332 r
.in
.datatype
= NULL
;
2333 r
.in
.devmode_ctr
.devmode
= NULL
;
2334 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2335 r
.out
.handle
= &handle
;
2337 torture_comment(tctx
, "Testing OpenPrinter(%s)\n", r
.in
.printername
);
2339 status
= dcerpc_spoolss_OpenPrinter(p
, tctx
, &r
);
2341 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinter failed");
2343 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenPrinter failed");
2345 if (!test_GetPrinter(tctx
, p
, &handle
)) {
2349 if (!torture_setting_bool(tctx
, "samba3", false)) {
2350 if (!test_SecondaryClosePrinter(tctx
, p
, &handle
)) {
2355 if (!test_ClosePrinter(tctx
, p
, &handle
)) {
2362 static bool call_OpenPrinterEx(struct torture_context
*tctx
,
2363 struct dcerpc_pipe
*p
,
2364 const char *name
, struct policy_handle
*handle
)
2366 struct spoolss_OpenPrinterEx r
;
2367 struct spoolss_UserLevel1 userlevel1
;
2370 if (name
&& name
[0]) {
2371 r
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s\\%s",
2372 dcerpc_server_name(p
), name
);
2374 r
.in
.printername
= talloc_asprintf(tctx
, "\\\\%s",
2375 dcerpc_server_name(p
));
2378 r
.in
.datatype
= NULL
;
2379 r
.in
.devmode_ctr
.devmode
= NULL
;
2380 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2382 r
.in
.userlevel
.level1
= &userlevel1
;
2383 r
.out
.handle
= handle
;
2385 userlevel1
.size
= 1234;
2386 userlevel1
.client
= "hello";
2387 userlevel1
.user
= "spottyfoot!";
2388 userlevel1
.build
= 1;
2389 userlevel1
.major
= 2;
2390 userlevel1
.minor
= 3;
2391 userlevel1
.processor
= 4;
2393 torture_comment(tctx
, "Testing OpenPrinterEx(%s)\n", r
.in
.printername
);
2395 status
= dcerpc_spoolss_OpenPrinterEx(p
, tctx
, &r
);
2397 torture_assert_ntstatus_ok(tctx
, status
, "OpenPrinterEx failed");
2399 torture_assert_werr_ok(tctx
, r
.out
.result
, "OpenPrinterEx failed");
2404 static bool test_OpenPrinterEx(struct torture_context
*tctx
,
2405 struct dcerpc_pipe
*p
,
2408 struct policy_handle handle
;
2411 if (!call_OpenPrinterEx(tctx
, p
, name
, &handle
)) {
2415 if (!test_GetPrinter(tctx
, p
, &handle
)) {
2419 if (!test_EnumForms(tctx
, p
, &handle
, false)) {
2423 if (!test_AddForm(tctx
, p
, &handle
, false)) {
2427 if (!test_EnumPrinterData(tctx
, p
, &handle
)) {
2431 if (!test_EnumPrinterDataEx(tctx
, p
, &handle
)) {
2435 if (!test_PausePrinter(tctx
, p
, &handle
)) {
2439 if (!test_DoPrintTest(tctx
, p
, &handle
)) {
2443 if (!test_ResumePrinter(tctx
, p
, &handle
)) {
2447 if (!test_SetPrinterData(tctx
, p
, &handle
)) {
2451 if (!torture_setting_bool(tctx
, "samba3", false)) {
2452 if (!test_SecondaryClosePrinter(tctx
, p
, &handle
)) {
2457 if (!test_ClosePrinter(tctx
, p
, &handle
)) {
2464 static bool test_EnumPrinters_old(struct torture_context
*tctx
, struct dcerpc_pipe
*p
)
2466 struct spoolss_EnumPrinters r
;
2468 uint16_t levels
[] = {1, 2, 4, 5};
2472 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
2473 union spoolss_PrinterInfo
*info
;
2478 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
2480 r
.in
.level
= levels
[i
];
2483 r
.out
.needed
= &needed
;
2484 r
.out
.count
= &count
;
2487 torture_comment(tctx
, "Testing EnumPrinters level %u\n", r
.in
.level
);
2489 status
= dcerpc_spoolss_EnumPrinters(p
, tctx
, &r
);
2490 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinters failed");
2492 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2493 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
2494 data_blob_clear(&blob
);
2495 r
.in
.buffer
= &blob
;
2496 r
.in
.offered
= needed
;
2497 status
= dcerpc_spoolss_EnumPrinters(p
, tctx
, &r
);
2500 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinters failed");
2502 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinters failed");
2505 torture_comment(tctx
, "No printers returned\n");
2509 for (j
=0;j
<count
;j
++) {
2510 if (r
.in
.level
== 1) {
2511 char *unc
= talloc_strdup(tctx
, info
[j
].info1
.name
);
2514 if (unc
[0] == '\\' && unc
[1] == '\\') {
2517 slash
= strchr(unc
, '\\');
2522 if (!test_OpenPrinter(tctx
, p
, name
)) {
2525 if (!test_OpenPrinterEx(tctx
, p
, name
)) {
2536 static bool test_GetPrinterDriver2(struct dcerpc_pipe
*p
,
2537 struct policy_handle
*handle
,
2538 const char *driver_name
)
2541 struct spoolss_GetPrinterDriver2 r
;
2543 uint32_t server_major_version
;
2544 uint32_t server_minor_version
;
2546 r
.in
.handle
= handle
;
2547 r
.in
.architecture
= "W32X86";
2551 r
.in
.client_major_version
= 0;
2552 r
.in
.client_minor_version
= 0;
2553 r
.out
.needed
= &needed
;
2554 r
.out
.server_major_version
= &server_major_version
;
2555 r
.out
.server_minor_version
= &server_minor_version
;
2557 printf("Testing GetPrinterDriver2\n");
2559 status
= dcerpc_spoolss_GetPrinterDriver2(p
, tctx
, &r
);
2560 if (!NT_STATUS_IS_OK(status
)) {
2561 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status
));
2565 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2566 r
.in
.offered
= needed
;
2567 status
= dcerpc_spoolss_GetPrinterDriver2(p
, tctx
, &r
);
2570 if (!NT_STATUS_IS_OK(status
)) {
2571 printf("GetPrinterDriver2 failed - %s\n",
2576 if (!W_ERROR_IS_OK(r
.out
.result
)) {
2577 printf("GetPrinterDriver2 failed - %s\n",
2578 win_errstr(r
.out
.result
));
2586 static bool test_EnumPrinterDrivers_old(struct torture_context
*tctx
,
2587 struct dcerpc_pipe
*p
)
2589 struct spoolss_EnumPrinterDrivers r
;
2591 uint16_t levels
[] = {1, 2, 3, 4, 5, 6};
2594 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
2598 union spoolss_DriverInfo
*info
;
2600 r
.in
.server
= talloc_asprintf(tctx
, "\\\\%s", dcerpc_server_name(p
));
2601 r
.in
.environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
2602 r
.in
.level
= levels
[i
];
2605 r
.out
.needed
= &needed
;
2606 r
.out
.count
= &count
;
2609 torture_comment(tctx
, "Testing EnumPrinterDrivers level %u\n", r
.in
.level
);
2611 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, tctx
, &r
);
2613 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDrivers failed");
2615 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
2616 DATA_BLOB blob
= data_blob_talloc(tctx
, NULL
, needed
);
2617 data_blob_clear(&blob
);
2618 r
.in
.buffer
= &blob
;
2619 r
.in
.offered
= needed
;
2620 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, tctx
, &r
);
2623 torture_assert_ntstatus_ok(tctx
, status
, "EnumPrinterDrivers failed");
2625 torture_assert_werr_ok(tctx
, r
.out
.result
, "EnumPrinterDrivers failed");
2628 torture_comment(tctx
, "No printer drivers returned\n");
2636 bool torture_rpc_spoolss(struct torture_context
*torture
)
2639 struct dcerpc_pipe
*p
;
2641 struct test_spoolss_context
*ctx
;
2643 status
= torture_rpc_connection(torture
, &p
, &ndr_table_spoolss
);
2644 if (!NT_STATUS_IS_OK(status
)) {
2648 ctx
= talloc_zero(torture
, struct test_spoolss_context
);
2650 ret
&= test_OpenPrinter_server(torture
, p
, &ctx
->server_handle
);
2652 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "W3SvcInstalled");
2653 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "BeepEnabled");
2654 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "EventLog");
2655 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "NetPopup");
2656 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "NetPopupToComputer");
2657 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "MajorVersion");
2658 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "MinorVersion");
2659 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "DefaultSpoolDirectory");
2660 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "Architecture");
2661 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "DsPresent");
2662 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "OSVersion");
2663 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "OSVersionEx");
2664 ret
&= test_GetPrinterData(torture
, p
, &ctx
->server_handle
, "DNSMachineName");
2665 ret
&= test_EnumForms(torture
, p
, &ctx
->server_handle
, true);
2666 ret
&= test_AddForm(torture
, p
, &ctx
->server_handle
, true);
2667 ret
&= test_EnumPorts(torture
, p
, ctx
);
2668 ret
&= test_GetPrinterDriverDirectory(torture
, p
, ctx
);
2669 ret
&= test_GetPrintProcessorDirectory(torture
, p
, ctx
);
2670 ret
&= test_EnumPrinterDrivers(torture
, p
, ctx
);
2671 ret
&= test_EnumMonitors(torture
, p
, ctx
);
2672 ret
&= test_EnumPrintProcessors(torture
, p
, ctx
);
2673 ret
&= test_EnumPrintProcDataTypes(torture
, p
, ctx
);
2674 ret
&= test_EnumPrinters(torture
, p
, ctx
);
2675 ret
&= test_OpenPrinter_badname(torture
, p
, "__INVALID_PRINTER__");
2676 ret
&= test_OpenPrinter_badname(torture
, p
, "\\\\__INVALID_HOST__");
2677 ret
&= test_OpenPrinter_badname(torture
, p
, "");
2678 ret
&= test_OpenPrinter_badname(torture
, p
, "\\\\\\");
2679 ret
&= test_OpenPrinter_badname(torture
, p
, "\\\\\\__INVALID_PRINTER__");
2680 ret
&= test_OpenPrinter_badname(torture
, p
, talloc_asprintf(torture
, "\\\\%s\\", dcerpc_server_name(p
)));
2681 ret
&= test_OpenPrinter_badname(torture
, p
,
2682 talloc_asprintf(torture
, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p
)));
2685 ret
&= test_AddPort(torture
, p
);
2686 ret
&= test_EnumPorts_old(torture
, p
);
2687 ret
&= test_EnumPrinters_old(torture
, p
);
2688 ret
&= test_EnumPrinterDrivers_old(torture
, p
);