2 Unix SMB/CIFS implementation.
3 test suite for spoolss rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Stefan Metzmacher 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "librpc/gen_ndr/ndr_spoolss.h"
26 struct test_spoolss_context {
27 struct dcerpc_pipe *p;
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(c,r,e) do {\
55 if (c.e && !r.e) _ok = False;\
56 if (!c.e && r.e) _ok = False;\
57 if (c.e && r.e && strcmp_safe(c.e, r.e) != 0) _ok = False;\
59 printf("%s: " #c "." #e " [%s] doesn't match " #r "." #e " [%s]\n",\
60 __location__, c.e, r.e);\
65 #define COMPARE_UINT16(c,r,e) do {\
67 printf("%s: " #c "." #e " 0x%08X (%u) doesn't match " #r "." #e " 0x%08X (%u)\n",\
68 __location__, c.e, c.e, r.e, r.e);\
73 #define COMPARE_UINT32(c,r,e) do {\
75 printf("%s: " #c "." #e " 0x%04X (%u) doesn't match " #r "." #e " 0x%04X (%u)\n",\
76 __location__, c.e, c.e, r.e, r.e);\
81 #define COMPARE_UINT64(c,r,e) do {\
83 printf("%s: " #c "." #e " 0x%016llX (%llu) doesn't match " #r "." #e " 0x%016llX (%llu)\n",\
84 __location__, c.e, c.e, r.e, r.e);\
90 #define COMPARE_SEC_DESC(c,r,e)
91 #define COMPARE_SPOOLSS_TIME(c,r,e)
92 #define COMPARE_STRING_ARRAY(c,r,e)
94 static BOOL test_OpenPrinter_server(struct test_spoolss_context *ctx)
97 struct spoolss_OpenPrinter op;
100 op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p));
101 op.in.datatype = NULL;
102 op.in.devmode_ctr.devmode= NULL;
103 op.in.access_mask = 0;
104 op.out.handle = &ctx->server_handle;
106 printf("\nTesting OpenPrinter(%s)\n", op.in.printername);
108 status = dcerpc_spoolss_OpenPrinter(ctx->p, ctx, &op);
109 if (!NT_STATUS_IS_OK(status)) {
110 printf("dcerpc_spoolss_OpenPrinter failed - %s\n", nt_errstr(status));
113 if (!W_ERROR_IS_OK(op.out.result)) {
114 printf("OpenPrinter(%s) failed - %s\n",
115 op.in.printername, win_errstr(op.out.result));
122 static BOOL test_EnumPorts(struct test_spoolss_context *ctx)
125 struct spoolss_EnumPorts r;
126 uint16_t levels[] = { 1, 2 };
130 for (i=0;i<ARRAY_SIZE(levels);i++) {
131 int level = levels[i];
134 r.in.servername = "";
139 printf("Testing EnumPorts level %u\n", r.in.level);
141 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
142 if (!NT_STATUS_IS_OK(status)) {
143 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
147 if (W_ERROR_IS_OK(r.out.result)) {
148 /* TODO: do some more checks here */
151 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
152 printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
153 win_errstr(r.out.result));
158 blob = data_blob_talloc(ctx, NULL, r.out.needed);
159 data_blob_clear(&blob);
161 r.in.offered = r.out.needed;
163 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
164 if (!NT_STATUS_IS_OK(status)) {
165 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
170 if (!W_ERROR_IS_OK(r.out.result)) {
171 printf("EnumPorts failed - %s\n",
172 win_errstr(r.out.result));
177 ctx->port_count[level] = r.out.count;
178 ctx->ports[level] = r.out.info;
181 for (i=1;i<ARRAY_SIZE(levels);i++) {
182 int level = levels[i];
183 int old_level = levels[i-1];
184 if (ctx->port_count[level] != ctx->port_count[old_level]) {
185 printf("EnumPorts level[%d] returns [%u] ports, but level[%d] returns [%u]\n",
186 level, ctx->port_count[level], old_level, ctx->port_count[old_level]);
190 /* if the array sizes are not the same we would maybe segfault in the following code */
191 if (!ret) return ret;
193 for (i=0;i<ARRAY_SIZE(levels);i++) {
194 int level = levels[i];
195 for (j=0;j<ctx->port_count[level];j++) {
196 union spoolss_PortInfo *cur = &ctx->ports[level][j];
197 union spoolss_PortInfo *ref = &ctx->ports[2][j];
200 COMPARE_STRING(cur->info1, ref->info2, port_name);
203 /* level 2 is our reference, and it makes no sense to compare it to itself */
212 static BOOL test_GetPrinterDriverDirectory(struct test_spoolss_context *ctx)
215 struct spoolss_GetPrinterDriverDirectory r;
230 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
233 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
239 for (i=0;i<ARRAY_SIZE(levels);i++) {
240 int level = levels[i].level;
243 r.in.server = levels[i].server;
244 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
249 printf("Testing GetPrinterDriverDirectory level %u\n", r.in.level);
251 status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
252 if (!NT_STATUS_IS_OK(status)) {
253 printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
257 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
258 printf("GetPrinterDriverDirectory unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
259 win_errstr(r.out.result));
264 blob = data_blob_talloc(ctx, NULL, r.out.needed);
265 data_blob_clear(&blob);
267 r.in.offered = r.out.needed;
269 status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
270 if (!NT_STATUS_IS_OK(status)) {
271 printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
276 if (!W_ERROR_IS_OK(r.out.result)) {
277 printf("GetPrinterDriverDirectory failed - %s\n",
278 win_errstr(r.out.result));
287 static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
290 struct spoolss_EnumPrinterDrivers r;
291 uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
295 for (i=0;i<ARRAY_SIZE(levels);i++) {
296 int level = levels[i];
300 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
305 printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
307 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
308 if (!NT_STATUS_IS_OK(status)) {
309 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
313 if (W_ERROR_IS_OK(r.out.result)) {
314 /* TODO: do some more checks here */
317 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
318 printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
319 win_errstr(r.out.result));
324 blob = data_blob_talloc(ctx, NULL, r.out.needed);
325 data_blob_clear(&blob);
327 r.in.offered = r.out.needed;
329 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
330 if (!NT_STATUS_IS_OK(status)) {
331 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
336 if (!W_ERROR_IS_OK(r.out.result)) {
337 printf("EnumPrinterDrivers failed - %s\n",
338 win_errstr(r.out.result));
343 ctx->driver_count[level] = r.out.count;
344 ctx->drivers[level] = r.out.info;
347 for (i=1;i<ARRAY_SIZE(levels);i++) {
348 int level = levels[i];
349 int old_level = levels[i-1];
350 if (ctx->driver_count[level] != ctx->driver_count[old_level]) {
351 printf("EnumPrinterDrivers level[%d] returns [%u] drivers, but level[%d] returns [%u]\n",
352 level, ctx->driver_count[level], old_level, ctx->driver_count[old_level]);
356 /* if the array sizes are not the same we would maybe segfault in the following code */
357 if (!ret) return ret;
359 for (i=0;i<ARRAY_SIZE(levels);i++) {
360 int level = levels[i];
361 for (j=0;j<ctx->driver_count[level];j++) {
362 union spoolss_DriverInfo *cur = &ctx->drivers[level][j];
363 union spoolss_DriverInfo *ref = &ctx->drivers[6][j];
366 COMPARE_STRING(cur->info1, ref->info6, driver_name);
369 COMPARE_UINT32(cur->info2, ref->info6, version);
370 COMPARE_STRING(cur->info2, ref->info6, driver_name);
371 COMPARE_STRING(cur->info2, ref->info6, architecture);
372 COMPARE_STRING(cur->info2, ref->info6, driver_path);
373 COMPARE_STRING(cur->info2, ref->info6, data_file);
374 COMPARE_STRING(cur->info2, ref->info6, config_file);
377 COMPARE_UINT32(cur->info3, ref->info6, version);
378 COMPARE_STRING(cur->info3, ref->info6, driver_name);
379 COMPARE_STRING(cur->info3, ref->info6, architecture);
380 COMPARE_STRING(cur->info3, ref->info6, driver_path);
381 COMPARE_STRING(cur->info3, ref->info6, data_file);
382 COMPARE_STRING(cur->info3, ref->info6, config_file);
383 COMPARE_STRING(cur->info3, ref->info6, help_file);
384 COMPARE_STRING_ARRAY(cur->info3, ref->info6, dependent_files);
385 COMPARE_STRING(cur->info3, ref->info6, monitor_name);
386 COMPARE_STRING(cur->info3, ref->info6, default_datatype);
389 COMPARE_UINT32(cur->info4, ref->info6, version);
390 COMPARE_STRING(cur->info4, ref->info6, driver_name);
391 COMPARE_STRING(cur->info4, ref->info6, architecture);
392 COMPARE_STRING(cur->info4, ref->info6, driver_path);
393 COMPARE_STRING(cur->info4, ref->info6, data_file);
394 COMPARE_STRING(cur->info4, ref->info6, config_file);
395 COMPARE_STRING(cur->info4, ref->info6, help_file);
396 COMPARE_STRING_ARRAY(cur->info4, ref->info6, dependent_files);
397 COMPARE_STRING(cur->info4, ref->info6, monitor_name);
398 COMPARE_STRING(cur->info4, ref->info6, default_datatype);
399 COMPARE_STRING_ARRAY(cur->info4, ref->info6, previous_names);
402 COMPARE_UINT32(cur->info5, ref->info6, version);
403 COMPARE_STRING(cur->info5, ref->info6, driver_name);
404 COMPARE_STRING(cur->info5, ref->info6, architecture);
405 COMPARE_STRING(cur->info5, ref->info6, driver_path);
406 COMPARE_STRING(cur->info5, ref->info6, data_file);
407 COMPARE_STRING(cur->info5, ref->info6, config_file);
408 /*COMPARE_UINT32(cur->info5, ref->info6, driver_attributes);*/
409 /*COMPARE_UINT32(cur->info5, ref->info6, config_version);*/
410 /*TODO: ! COMPARE_UINT32(cur->info5, ref->info6, driver_version); */
413 /* level 6 is our reference, and it makes no sense to compare it to itself */
422 static BOOL test_EnumMonitors(struct test_spoolss_context *ctx)
425 struct spoolss_EnumMonitors r;
426 uint16_t levels[] = { 1, 2 };
430 for (i=0;i<ARRAY_SIZE(levels);i++) {
431 int level = levels[i];
434 r.in.servername = "";
439 printf("Testing EnumMonitors level %u\n", r.in.level);
441 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
442 if (!NT_STATUS_IS_OK(status)) {
443 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
447 if (W_ERROR_IS_OK(r.out.result)) {
448 /* TODO: do some more checks here */
451 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
452 printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
453 win_errstr(r.out.result));
458 blob = data_blob_talloc(ctx, NULL, r.out.needed);
459 data_blob_clear(&blob);
461 r.in.offered = r.out.needed;
463 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
464 if (!NT_STATUS_IS_OK(status)) {
465 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
470 if (!W_ERROR_IS_OK(r.out.result)) {
471 printf("EnumMonitors failed - %s\n",
472 win_errstr(r.out.result));
477 ctx->monitor_count[level] = r.out.count;
478 ctx->monitors[level] = r.out.info;
481 for (i=1;i<ARRAY_SIZE(levels);i++) {
482 int level = levels[i];
483 int old_level = levels[i-1];
484 if (ctx->monitor_count[level] != ctx->monitor_count[old_level]) {
485 printf("EnumMonitors level[%d] returns [%u] monitors, but level[%d] returns [%u]\n",
486 level, ctx->monitor_count[level], old_level, ctx->monitor_count[old_level]);
490 /* if the array sizes are not the same we would maybe segfault in the following code */
491 if (!ret) return ret;
493 for (i=0;i<ARRAY_SIZE(levels);i++) {
494 int level = levels[i];
495 for (j=0;j<ctx->monitor_count[level];j++) {
496 union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
497 union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
500 COMPARE_STRING(cur->info1, ref->info2, monitor_name);
503 /* level 2 is our reference, and it makes no sense to compare it to itself */
512 static BOOL test_EnumPrintProcessors(struct test_spoolss_context *ctx)
515 struct spoolss_EnumPrintProcessors r;
516 uint16_t levels[] = { 1 };
520 for (i=0;i<ARRAY_SIZE(levels);i++) {
521 int level = levels[i];
524 r.in.servername = "";
525 r.in.environment = "Windows NT x86";
530 printf("Testing EnumPrintProcessors level %u\n", r.in.level);
532 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
533 if (!NT_STATUS_IS_OK(status)) {
534 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
538 if (W_ERROR_IS_OK(r.out.result)) {
539 /* TODO: do some more checks here */
542 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
543 printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
544 win_errstr(r.out.result));
549 blob = data_blob_talloc(ctx, NULL, r.out.needed);
550 data_blob_clear(&blob);
552 r.in.offered = r.out.needed;
554 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
555 if (!NT_STATUS_IS_OK(status)) {
556 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
561 if (!W_ERROR_IS_OK(r.out.result)) {
562 printf("EnumPrintProcessors failed - %s\n",
563 win_errstr(r.out.result));
568 ctx->print_processor_count[level] = r.out.count;
569 ctx->print_processors[level] = r.out.info;
572 for (i=1;i<ARRAY_SIZE(levels);i++) {
573 int level = levels[i];
574 int old_level = levels[i-1];
575 if (ctx->print_processor_count[level] != ctx->print_processor_count[old_level]) {
576 printf("EnumPrintProcessors level[%d] returns [%u] print_processors, but level[%d] returns [%u]\n",
577 level, ctx->print_processor_count[level], old_level, ctx->print_processor_count[old_level]);
581 /* if the array sizes are not the same we would maybe segfault in the following code */
582 if (!ret) return ret;
584 for (i=0;i<ARRAY_SIZE(levels);i++) {
585 int level = levels[i];
586 for (j=0;j<ctx->print_processor_count[level];j++) {
588 union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][j];
589 union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][j];
593 /* level 1 is our reference, and it makes no sense to compare it to itself */
602 static BOOL test_EnumPrinters(struct test_spoolss_context *ctx)
604 struct spoolss_EnumPrinters r;
606 uint16_t levels[] = { 0, 1, 2, 4, 5 };
610 for (i=0;i<ARRAY_SIZE(levels);i++) {
611 int level = levels[i];
614 r.in.flags = PRINTER_ENUM_LOCAL;
620 printf("\nTesting EnumPrinters level %u\n", r.in.level);
622 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
623 if (!NT_STATUS_IS_OK(status)) {
624 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
628 if (W_ERROR_IS_OK(r.out.result)) {
629 /* TODO: do some more checks here */
632 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
633 printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
634 win_errstr(r.out.result));
639 blob = data_blob_talloc(ctx, NULL, r.out.needed);
640 data_blob_clear(&blob);
642 r.in.offered = r.out.needed;
644 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
645 if (!NT_STATUS_IS_OK(status)) {
646 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
651 if (!W_ERROR_IS_OK(r.out.result)) {
652 printf("EnumPrinters failed - %s\n",
653 win_errstr(r.out.result));
657 ctx->printer_count[level] = r.out.count;
658 ctx->printers[level] = r.out.info;
661 for (i=1;i<ARRAY_SIZE(levels);i++) {
662 int level = levels[i];
663 int old_level = levels[i-1];
664 if (ctx->printer_count[level] != ctx->printer_count[old_level]) {
665 printf("EnumPrinters level[%d] returns [%u] printers, but level[%d] returns [%u]\n",
666 level, ctx->printer_count[level], old_level, ctx->printer_count[old_level]);
670 /* if the array sizes are not the same we would maybe segfault in the following code */
671 if (!ret) return ret;
673 for (i=0;i<ARRAY_SIZE(levels);i++) {
674 int level = levels[i];
675 for (j=0;j<ctx->printer_count[level];j++) {
676 union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
677 union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
680 COMPARE_STRING(cur->info0, ref->info2, printername);
681 COMPARE_STRING(cur->info0, ref->info2, servername);
682 COMPARE_UINT32(cur->info0, ref->info2, cjobs);
683 /*COMPARE_UINT32(cur->info0, ref->info2, total_jobs);
684 COMPARE_UINT32(cur->info0, ref->info2, total_bytes);
685 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
686 COMPARE_UINT32(cur->info0, ref->info2, global_counter);
687 COMPARE_UINT32(cur->info0, ref->info2, total_pages);
688 COMPARE_UINT32(cur->info0, ref->info2, version);
689 COMPARE_UINT32(cur->info0, ref->info2, unknown10);
690 COMPARE_UINT32(cur->info0, ref->info2, unknown11);
691 COMPARE_UINT32(cur->info0, ref->info2, unknown12);
692 COMPARE_UINT32(cur->info0, ref->info2, session_counter);
693 COMPARE_UINT32(cur->info0, ref->info2, unknown14);
694 COMPARE_UINT32(cur->info0, ref->info2, printer_errors);
695 COMPARE_UINT32(cur->info0, ref->info2, unknown16);
696 COMPARE_UINT32(cur->info0, ref->info2, unknown17);
697 COMPARE_UINT32(cur->info0, ref->info2, unknown18);
698 COMPARE_UINT32(cur->info0, ref->info2, unknown19);
699 COMPARE_UINT32(cur->info0, ref->info2, change_id);
700 COMPARE_UINT32(cur->info0, ref->info2, unknown21);*/
701 COMPARE_UINT32(cur->info0, ref->info2, status);
702 /*COMPARE_UINT32(cur->info0, ref->info2, unknown23);
703 COMPARE_UINT32(cur->info0, ref->info2, c_setprinter);
704 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
705 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
706 COMPARE_UINT32(cur->info0, ref->info2, unknown27);
707 COMPARE_UINT32(cur->info0, ref->info2, unknown28);
708 COMPARE_UINT32(cur->info0, ref->info2, unknown29);*/
711 /*COMPARE_UINT32(cur->info1, ref->info2, flags);*/
712 /*COMPARE_STRING(cur->info1, ref->info2, name);*/
713 /*COMPARE_STRING(cur->info1, ref->info2, description);*/
714 COMPARE_STRING(cur->info1, ref->info2, comment);
717 /* level 2 is our reference, and it makes no sense to compare it to itself */
720 COMPARE_STRING(cur->info4, ref->info2, printername);
721 COMPARE_STRING(cur->info4, ref->info2, servername);
722 COMPARE_UINT32(cur->info4, ref->info2, attributes);
725 COMPARE_STRING(cur->info5, ref->info2, printername);
726 COMPARE_STRING(cur->info5, ref->info2, portname);
727 COMPARE_UINT32(cur->info5, ref->info2, attributes);
728 /*COMPARE_UINT32(cur->info5, ref->info2, device_not_selected_timeout);
729 COMPARE_UINT32(cur->info5, ref->info2, transmission_retry_timeout);*/
736 * - verify that the port of a printer was in the list returned by EnumPorts
742 static BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
743 struct policy_handle *handle)
746 struct spoolss_GetPrinter r;
747 uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
751 for (i=0;i<ARRAY_SIZE(levels);i++) {
752 r.in.handle = handle;
753 r.in.level = levels[i];
757 printf("Testing GetPrinter level %u\n", r.in.level);
759 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
760 if (!NT_STATUS_IS_OK(status)) {
761 printf("GetPrinter failed - %s\n", nt_errstr(status));
766 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
767 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
768 data_blob_clear(&blob);
770 r.in.offered = r.out.needed;
771 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("GetPrinter failed - %s\n", nt_errstr(status));
780 if (!W_ERROR_IS_OK(r.out.result)) {
781 printf("GetPrinter failed - %s\n",
782 win_errstr(r.out.result));
792 static BOOL test_ClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
793 struct policy_handle *handle)
796 struct spoolss_ClosePrinter r;
798 r.in.handle = handle;
799 r.out.handle = handle;
801 printf("Testing ClosePrinter\n");
803 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("ClosePrinter failed - %s\n", nt_errstr(status));
812 static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
813 struct policy_handle *handle,
814 const char *form_name)
817 struct spoolss_GetForm r;
819 r.in.handle = handle;
820 r.in.form_name = form_name;
825 printf("Testing GetForm\n");
827 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
828 if (!NT_STATUS_IS_OK(status)) {
829 printf("GetForm failed - %s\n", nt_errstr(status));
833 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
834 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
835 data_blob_clear(&blob);
837 r.in.offered = r.out.needed;
838 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
839 if (!NT_STATUS_IS_OK(status)) {
840 printf("GetForm failed - %s\n",
845 if (!W_ERROR_IS_OK(r.out.result)) {
846 printf("GetForm failed - %s\n",
847 win_errstr(r.out.result));
852 printf("No form info returned\n");
858 if (!W_ERROR_IS_OK(r.out.result)) {
859 printf("GetForm failed - %s\n",
860 win_errstr(r.out.result));
867 static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
868 struct policy_handle *handle, BOOL print_server)
871 struct spoolss_EnumForms r;
874 r.in.handle = handle;
879 printf("Testing EnumForms\n");
881 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
882 if (!NT_STATUS_IS_OK(status)) {
883 printf("EnumForms failed - %s\n", nt_errstr(status));
887 if (print_server && W_ERROR_EQUAL(r.out.result,WERR_BADFID)) {
888 printf("EnumForms on the PrintServer isn't supported by test server (NT4)\n");
892 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
893 union spoolss_FormInfo *info;
895 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
896 data_blob_clear(&blob);
898 r.in.offered = r.out.needed;
900 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
903 printf("No forms returned\n");
909 for (j = 0; j < r.out.count; j++) {
910 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, info[j].info1.form_name);
914 if (!NT_STATUS_IS_OK(status)) {
915 printf("EnumForms failed - %s\n", nt_errstr(status));
919 if (!W_ERROR_IS_OK(r.out.result)) {
920 printf("EnumForms failed - %s\n", win_errstr(r.out.result));
927 static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
928 struct policy_handle *handle,
929 const char *form_name)
932 struct spoolss_DeleteForm r;
934 r.in.handle = handle;
935 r.in.form_name = form_name;
937 status = dcerpc_spoolss_DeleteForm(p, mem_ctx, &r);
939 if (!NT_STATUS_IS_OK(status)) {
940 printf("DeleteForm failed - %s\n", nt_errstr(status));
944 if (!W_ERROR_IS_OK(r.out.result)) {
945 printf("DeleteForm failed - %s\n", win_errstr(r.out.result));
952 static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
953 struct policy_handle *handle, BOOL print_server)
955 struct spoolss_AddForm r;
956 struct spoolss_AddFormInfo1 addform;
957 const char *form_name = "testform3";
961 r.in.handle = handle;
963 r.in.info.info1 = &addform;
964 addform.flags = SPOOLSS_FORM_USER;
965 addform.form_name = form_name;
966 addform.size.width = 50;
967 addform.size.height = 25;
968 addform.area.left = 5;
969 addform.area.top = 10;
970 addform.area.right = 45;
971 addform.area.bottom = 15;
973 status = dcerpc_spoolss_AddForm(p, mem_ctx, &r);
975 if (!NT_STATUS_IS_OK(status)) {
976 printf("AddForm failed - %s\n", nt_errstr(status));
980 if (!W_ERROR_IS_OK(r.out.result)) {
981 printf("AddForm failed - %s\n", win_errstr(r.out.result));
985 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
988 struct spoolss_SetForm sf;
989 struct spoolss_AddFormInfo1 setform;
991 sf.in.handle = handle;
992 sf.in.form_name = form_name;
994 sf.in.info.info1= &setform;
995 setform.flags = addform.flags;
996 setform.form_name = addform.form_name;
997 setform.size = addform.size;
998 setform.area = addform.area;
1000 setform.size.width = 1234;
1002 status = dcerpc_spoolss_SetForm(p, mem_ctx, &sf);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("SetForm failed - %s\n", nt_errstr(status));
1010 if (!W_ERROR_IS_OK(r.out.result)) {
1011 printf("SetForm failed - %s\n",
1012 win_errstr(r.out.result));
1018 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
1021 if (!test_DeleteForm(p, mem_ctx, handle, form_name)) {
1022 printf("DeleteForm failed\n");
1029 static BOOL test_EnumPorts_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1032 struct spoolss_EnumPorts r;
1034 r.in.servername = talloc_asprintf(mem_ctx, "\\\\%s",
1035 dcerpc_server_name(p));
1040 printf("Testing EnumPorts\n");
1042 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1044 if (!NT_STATUS_IS_OK(status)) {
1045 printf("EnumPorts failed - %s\n", nt_errstr(status));
1049 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1050 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1051 data_blob_clear(&blob);
1052 r.in.buffer = &blob;
1053 r.in.offered = r.out.needed;
1055 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1056 if (!NT_STATUS_IS_OK(status)) {
1057 printf("EnumPorts failed - %s\n", nt_errstr(status));
1062 printf("No ports returned\n");
1070 static BOOL test_AddPort(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1073 struct spoolss_AddPort r;
1075 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
1076 dcerpc_server_name(p));
1078 r.in.monitor_name = "foo";
1080 printf ("Testing AddPort\n");
1082 status = dcerpc_spoolss_AddPort(p, mem_ctx, &r);
1084 if (!NT_STATUS_IS_OK(status)) {
1085 printf("AddPort failed - %s\n", nt_errstr(status));
1089 /* win2k3 returns WERR_NOT_SUPPORTED */
1093 if (!W_ERROR_IS_OK(r.out.result)) {
1094 printf("AddPort failed - %s\n", win_errstr(r.out.result));
1103 static BOOL test_GetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1104 struct policy_handle *handle, uint32_t job_id)
1107 struct spoolss_GetJob r;
1109 r.in.handle = handle;
1110 r.in.job_id = job_id;
1115 printf("Testing GetJob\n");
1117 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 printf("GetJob failed - %s\n", nt_errstr(status));
1123 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1124 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1125 data_blob_clear(&blob);
1126 r.in.buffer = &blob;
1127 r.in.offered = r.out.needed;
1129 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1132 printf("No job info returned\n");
1140 static BOOL test_SetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1141 struct policy_handle *handle, uint32_t job_id, enum spoolss_JobControl command)
1144 struct spoolss_SetJob r;
1146 r.in.handle = handle;
1147 r.in.job_id = job_id;
1149 r.in.command = command;
1151 printf("Testing SetJob\n");
1153 status = dcerpc_spoolss_SetJob(p, mem_ctx, &r);
1154 if (!NT_STATUS_IS_OK(status)) {
1155 printf("SetJob failed - %s\n", nt_errstr(status));
1158 if (!W_ERROR_IS_OK(r.out.result)) {
1159 printf("SetJob failed - %s\n", win_errstr(r.out.result));
1166 static BOOL test_EnumJobs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1167 struct policy_handle *handle)
1170 struct spoolss_EnumJobs r;
1172 r.in.handle = handle;
1174 r.in.numjobs = 0xffffffff;
1179 printf("Testing EnumJobs\n");
1181 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1183 if (!NT_STATUS_IS_OK(status)) {
1184 printf("EnumJobs failed - %s\n", nt_errstr(status));
1188 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1189 union spoolss_JobInfo *info;
1191 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1192 data_blob_clear(&blob);
1193 r.in.buffer = &blob;
1194 r.in.offered = r.out.needed;
1196 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1199 printf("No jobs returned\n");
1205 for (j = 0; j < r.out.count; j++) {
1206 test_GetJob(p, mem_ctx, handle, info[j].info1.job_id);
1207 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
1208 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
1211 } else if (!W_ERROR_IS_OK(r.out.result)) {
1212 printf("EnumJobs failed - %s\n", win_errstr(r.out.result));
1219 static BOOL test_DoPrintTest(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1220 struct policy_handle *handle)
1224 struct spoolss_StartDocPrinter s;
1225 struct spoolss_DocumentInfo1 info1;
1226 struct spoolss_StartPagePrinter sp;
1227 struct spoolss_WritePrinter w;
1228 struct spoolss_EndPagePrinter ep;
1229 struct spoolss_EndDocPrinter e;
1233 printf("Testing StartDocPrinter\n");
1235 s.in.handle = handle;
1237 s.in.info.info1 = &info1;
1238 info1.document_name = "TorturePrintJob";
1239 info1.output_file = NULL;
1240 info1.datatype = "RAW";
1242 status = dcerpc_spoolss_StartDocPrinter(p, mem_ctx, &s);
1243 if (!NT_STATUS_IS_OK(status)) {
1244 printf("dcerpc_spoolss_StartDocPrinter failed - %s\n", nt_errstr(status));
1247 if (!W_ERROR_IS_OK(s.out.result)) {
1248 printf("StartDocPrinter failed - %s\n", win_errstr(s.out.result));
1252 job_id = s.out.job_id;
1254 for (i=1; i < 4; i++) {
1255 printf("Testing StartPagePrinter: Page[%d]\n", i);
1257 sp.in.handle = handle;
1259 status = dcerpc_spoolss_StartPagePrinter(p, mem_ctx, &sp);
1260 if (!NT_STATUS_IS_OK(status)) {
1261 printf("dcerpc_spoolss_StartPagePrinter failed - %s\n", nt_errstr(status));
1264 if (!W_ERROR_IS_OK(sp.out.result)) {
1265 printf("StartPagePrinter failed - %s\n", win_errstr(sp.out.result));
1269 printf("Testing WritePrinter: Page[%d]\n", i);
1271 w.in.handle = handle;
1272 w.in.data = data_blob_string_const(talloc_asprintf(mem_ctx,"TortureTestPage: %d\nData\n",i));
1274 status = dcerpc_spoolss_WritePrinter(p, mem_ctx, &w);
1275 if (!NT_STATUS_IS_OK(status)) {
1276 printf("dcerpc_spoolss_WritePrinter failed - %s\n", nt_errstr(status));
1279 if (!W_ERROR_IS_OK(w.out.result)) {
1280 printf("WritePrinter failed - %s\n", win_errstr(w.out.result));
1284 printf("Testing EndPagePrinter: Page[%d]\n", i);
1286 ep.in.handle = handle;
1288 status = dcerpc_spoolss_EndPagePrinter(p, mem_ctx, &ep);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 printf("dcerpc_spoolss_EndPagePrinter failed - %s\n", nt_errstr(status));
1293 if (!W_ERROR_IS_OK(ep.out.result)) {
1294 printf("EndPagePrinter failed - %s\n", win_errstr(ep.out.result));
1299 printf("Testing EndDocPrinter\n");
1301 e.in.handle = handle;
1303 status = dcerpc_spoolss_EndDocPrinter(p, mem_ctx, &e);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 printf("dcerpc_spoolss_EndDocPrinter failed - %s\n", nt_errstr(status));
1308 if (!W_ERROR_IS_OK(e.out.result)) {
1309 printf("EndDocPrinter failed - %s\n", win_errstr(e.out.result));
1313 ret &= test_EnumJobs(p, mem_ctx, handle);
1315 ret &= test_SetJob(p, mem_ctx, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
1320 static BOOL test_PausePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1321 struct policy_handle *handle)
1324 struct spoolss_SetPrinter r;
1326 r.in.handle = handle;
1328 r.in.info.info1 = NULL;
1329 r.in.devmode_ctr.devmode= NULL;
1330 r.in.secdesc_ctr.sd = NULL;
1331 r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
1333 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1335 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 printf("SetPrinter failed - %s\n", nt_errstr(status));
1342 if (!W_ERROR_IS_OK(r.out.result)) {
1343 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1350 static BOOL test_ResumePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1351 struct policy_handle *handle)
1354 struct spoolss_SetPrinter r;
1356 r.in.handle = handle;
1358 r.in.info.info1 = NULL;
1359 r.in.devmode_ctr.devmode= NULL;
1360 r.in.secdesc_ctr.sd = NULL;
1361 r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
1363 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1365 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1367 if (!NT_STATUS_IS_OK(status)) {
1368 printf("SetPrinter failed - %s\n", nt_errstr(status));
1372 if (!W_ERROR_IS_OK(r.out.result)) {
1373 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1380 static BOOL test_GetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1381 struct policy_handle *handle,
1382 const char *value_name)
1385 struct spoolss_GetPrinterData r;
1387 r.in.handle = handle;
1388 r.in.value_name = value_name;
1391 printf("Testing GetPrinterData\n");
1393 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1394 if (!NT_STATUS_IS_OK(status)) {
1395 printf("GetPrinterData failed - %s\n", nt_errstr(status));
1399 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1400 r.in.offered = r.out.needed;
1402 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1403 if (!NT_STATUS_IS_OK(status)) {
1404 printf("GetPrinterData failed - %s\n",
1409 if (!W_ERROR_IS_OK(r.out.result)) {
1410 printf("GetPrinterData failed - %s\n",
1411 win_errstr(r.out.result));
1419 static BOOL test_GetPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1420 struct policy_handle *handle,
1421 const char *key_name,
1422 const char *value_name)
1425 struct spoolss_GetPrinterDataEx r;
1427 r.in.handle = handle;
1428 r.in.key_name = key_name;
1429 r.in.value_name = value_name;
1432 printf("Testing GetPrinterDataEx\n");
1434 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1435 if (!NT_STATUS_IS_OK(status)) {
1436 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1437 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1438 printf("GetPrinterDataEx not supported by server\n");
1441 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status));
1445 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1446 r.in.offered = r.out.needed;
1448 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1449 if (!NT_STATUS_IS_OK(status)) {
1450 printf("GetPrinterDataEx failed - %s\n",
1455 if (!W_ERROR_IS_OK(r.out.result)) {
1456 printf("GetPrinterDataEx failed - %s\n",
1457 win_errstr(r.out.result));
1465 static BOOL test_EnumPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1466 struct policy_handle *handle)
1469 struct spoolss_EnumPrinterData r;
1471 r.in.handle = handle;
1472 r.in.enum_index = 0;
1477 r.in.value_offered = 0;
1479 r.in.data_size = &data_size;
1480 r.out.data_size = &data_size;
1482 printf("Testing EnumPrinterData\n");
1484 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1486 if (!NT_STATUS_IS_OK(status)) {
1487 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1491 r.in.value_offered = r.out.value_needed;
1493 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1495 if (!NT_STATUS_IS_OK(status)) {
1496 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1500 test_GetPrinterData(p, mem_ctx, handle, r.out.value_name);
1502 test_GetPrinterDataEx(
1503 p, mem_ctx, handle, "PrinterDriverData",
1508 } while (W_ERROR_IS_OK(r.out.result));
1513 static BOOL test_EnumPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1514 struct policy_handle *handle)
1517 struct spoolss_EnumPrinterDataEx r;
1519 r.in.handle = handle;
1520 r.in.key_name = "PrinterDriverData";
1523 printf("Testing EnumPrinterDataEx\n");
1525 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1526 if (!NT_STATUS_IS_OK(status)) {
1527 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1531 r.in.offered = r.out.needed;
1533 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1544 static BOOL test_DeletePrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1545 struct policy_handle *handle,
1546 const char *value_name)
1549 struct spoolss_DeletePrinterData r;
1551 r.in.handle = handle;
1552 r.in.value_name = value_name;
1554 printf("Testing DeletePrinterData\n");
1556 status = dcerpc_spoolss_DeletePrinterData(p, mem_ctx, &r);
1558 if (!NT_STATUS_IS_OK(status)) {
1559 printf("DeletePrinterData failed - %s\n", nt_errstr(status));
1566 static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1567 struct policy_handle *handle)
1570 struct spoolss_SetPrinterData r;
1571 const char *value_name = "spottyfoot";
1573 r.in.handle = handle;
1574 r.in.value_name = value_name;
1575 r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
1576 r.in.data.string = "dog";
1578 printf("Testing SetPrinterData\n");
1580 status = dcerpc_spoolss_SetPrinterData(p, mem_ctx, &r);
1582 if (!NT_STATUS_IS_OK(status)) {
1583 printf("SetPrinterData failed - %s\n", nt_errstr(status));
1587 if (!test_GetPrinterData(p, mem_ctx, handle, value_name)) {
1591 if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) {
1598 static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1599 struct policy_handle *handle)
1602 struct dcerpc_binding *b;
1603 struct dcerpc_pipe *p2;
1606 /* only makes sense on SMB */
1607 if (p->conn->transport.transport != NCACN_NP) {
1611 printf("testing close on secondary pipe\n");
1613 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1619 status = dcerpc_secondary_connection(p, &p2, b);
1620 if (!NT_STATUS_IS_OK(status)) {
1621 printf("Failed to create secondary connection\n");
1625 status = dcerpc_bind_auth_none(p2, DCERPC_SPOOLSS_UUID,
1626 DCERPC_SPOOLSS_VERSION);
1627 if (!NT_STATUS_IS_OK(status)) {
1628 printf("Failed to create bind on secondary connection\n");
1634 if (test_ClosePrinter(p2, mem_ctx, handle)) {
1635 printf("ERROR: Allowed close on secondary connection!\n");
1639 if (p2->last_fault_code != DCERPC_FAULT_CONTEXT_MISMATCH) {
1640 printf("Unexpected fault code 0x%x - expected 0x%x\n",
1641 p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH);
1650 static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
1653 struct spoolss_OpenPrinter op;
1654 struct spoolss_OpenPrinterEx opEx;
1655 struct policy_handle handle;
1658 op.in.printername = name;
1659 op.in.datatype = NULL;
1660 op.in.devmode_ctr.devmode= NULL;
1661 op.in.access_mask = 0;
1662 op.out.handle = &handle;
1664 printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1666 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
1667 if (!NT_STATUS_IS_OK(status)) {
1668 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1671 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1672 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1673 name, win_errstr(op.out.result));
1676 if (W_ERROR_IS_OK(op.out.result)) {
1677 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1680 opEx.in.printername = name;
1681 opEx.in.datatype = NULL;
1682 opEx.in.devmode_ctr.devmode = NULL;
1683 opEx.in.access_mask = 0;
1685 opEx.in.userlevel.level1 = NULL;
1686 opEx.out.handle = &handle;
1688 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1690 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
1691 if (!NT_STATUS_IS_OK(status)) {
1692 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1695 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
1696 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1697 name, win_errstr(opEx.out.result));
1700 if (W_ERROR_IS_OK(opEx.out.result)) {
1701 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1707 static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1712 ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
1713 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
1714 ret &= test_OpenPrinter_badname(p, mem_ctx, "");
1715 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
1716 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
1718 name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
1719 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1722 name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
1723 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1729 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1733 struct spoolss_OpenPrinter r;
1734 struct policy_handle handle;
1737 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1738 r.in.datatype = NULL;
1739 r.in.devmode_ctr.devmode= NULL;
1740 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1741 r.out.handle = &handle;
1743 printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
1745 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
1747 if (!NT_STATUS_IS_OK(status)) {
1748 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1752 if (!W_ERROR_IS_OK(r.out.result)) {
1753 printf("OpenPrinter failed - %s\n", win_errstr(r.out.result));
1757 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1761 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1765 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1772 static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1773 const char *name, struct policy_handle *handle)
1775 struct spoolss_OpenPrinterEx r;
1776 struct spoolss_UserLevel1 userlevel1;
1779 if (name && name[0]) {
1780 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
1781 dcerpc_server_name(p), name);
1783 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
1784 dcerpc_server_name(p));
1787 r.in.datatype = NULL;
1788 r.in.devmode_ctr.devmode= NULL;
1789 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1791 r.in.userlevel.level1 = &userlevel1;
1792 r.out.handle = handle;
1794 userlevel1.size = 1234;
1795 userlevel1.client = "hello";
1796 userlevel1.user = "spottyfoot!";
1797 userlevel1.build = 1;
1798 userlevel1.major = 2;
1799 userlevel1.minor = 3;
1800 userlevel1.processor = 4;
1802 printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
1804 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
1806 if (!NT_STATUS_IS_OK(status)) {
1807 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
1811 if (!W_ERROR_IS_OK(r.out.result)) {
1812 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
1819 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1822 struct policy_handle handle;
1825 if (!call_OpenPrinterEx(p, mem_ctx, name, &handle)) {
1829 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1833 if (!test_EnumForms(p, mem_ctx, &handle, False)) {
1837 if (!test_AddForm(p, mem_ctx, &handle, False)) {
1841 if (!test_EnumPrinterData(p, mem_ctx, &handle)) {
1845 if (!test_EnumPrinterDataEx(p, mem_ctx, &handle)) {
1849 if (!test_PausePrinter(p, mem_ctx, &handle)) {
1853 if (!test_DoPrintTest(p, mem_ctx, &handle)) {
1857 if (!test_ResumePrinter(p, mem_ctx, &handle)) {
1861 if (!test_SetPrinterData(p, mem_ctx, &handle)) {
1865 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1869 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1876 static BOOL test_EnumPrinters_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1878 struct spoolss_EnumPrinters r;
1880 uint16_t levels[] = {1, 2, 4, 5};
1884 for (i=0;i<ARRAY_SIZE(levels);i++) {
1885 union spoolss_PrinterInfo *info;
1888 r.in.flags = PRINTER_ENUM_LOCAL;
1890 r.in.level = levels[i];
1894 printf("\nTesting EnumPrinters level %u\n", r.in.level);
1896 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 printf("EnumPrinters failed - %s\n", nt_errstr(status));
1903 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1904 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1905 data_blob_clear(&blob);
1906 r.in.buffer = &blob;
1907 r.in.offered = r.out.needed;
1908 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1911 if (!NT_STATUS_IS_OK(status)) {
1912 printf("EnumPrinters failed - %s\n",
1917 if (!W_ERROR_IS_OK(r.out.result)) {
1918 printf("EnumPrinters failed - %s\n",
1919 win_errstr(r.out.result));
1924 printf("No printers returned\n");
1930 for (j=0;j<r.out.count;j++) {
1931 if (r.in.level == 1) {
1932 /* the names appear to be comma-separated name lists? */
1933 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
1934 char *comma = strchr(name, ',');
1935 if (comma) *comma = 0;
1936 if (!test_OpenPrinter(p, mem_ctx, name)) {
1939 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
1950 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1951 struct policy_handle *handle,
1952 const char *driver_name)
1955 struct spoolss_GetPrinterDriver2 r;
1957 r.in.handle = handle;
1958 r.in.architecture = "W32X86";
1962 r.in.client_major_version = 0;
1963 r.in.client_minor_version = 0;
1965 printf("Testing GetPrinterDriver2\n");
1967 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1968 if (!NT_STATUS_IS_OK(status)) {
1969 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1973 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1974 r.in.offered = r.out.needed;
1975 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1978 if (!NT_STATUS_IS_OK(status)) {
1979 printf("GetPrinterDriver2 failed - %s\n",
1984 if (!W_ERROR_IS_OK(r.out.result)) {
1985 printf("GetPrinterDriver2 failed - %s\n",
1986 win_errstr(r.out.result));
1994 static BOOL test_EnumPrinterDrivers_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1996 struct spoolss_EnumPrinterDrivers r;
1998 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
2002 for (i=0;i<ARRAY_SIZE(levels);i++) {
2004 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
2005 r.in.environment = "Windows NT x86";
2006 r.in.level = levels[i];
2010 printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
2012 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2014 if (!NT_STATUS_IS_OK(status)) {
2015 printf("EnumPrinterDrivers failed - %s\n",
2021 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2022 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2023 data_blob_clear(&blob);
2024 r.in.buffer = &blob;
2025 r.in.offered = r.out.needed;
2026 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2029 if (!NT_STATUS_IS_OK(status)) {
2030 printf("EnumPrinterDrivers failed - %s\n",
2036 if (!W_ERROR_IS_OK(r.out.result)) {
2037 printf("EnumPrinterDrivers failed - %s\n",
2038 win_errstr(r.out.result));
2044 printf("No printer drivers returned\n");
2052 BOOL torture_rpc_spoolss(void)
2055 struct dcerpc_pipe *p;
2056 TALLOC_CTX *mem_ctx;
2058 struct test_spoolss_context *ctx;
2060 mem_ctx = talloc_init("torture_rpc_spoolss");
2062 status = torture_rpc_connection(mem_ctx,
2064 DCERPC_SPOOLSS_NAME,
2065 DCERPC_SPOOLSS_UUID,
2066 DCERPC_SPOOLSS_VERSION);
2067 if (!NT_STATUS_IS_OK(status)) {
2068 talloc_free(mem_ctx);
2072 ctx = talloc_zero(mem_ctx, struct test_spoolss_context);
2075 ret &= test_OpenPrinter_server(ctx);
2077 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "W3SvcInstalled");
2078 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "BeepEnabled");
2079 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "EventLog");
2080 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopup");
2081 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopupToComputer");
2082 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MajorVersion");
2083 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MinorVersion");
2084 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");
2085 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "Architecture");
2086 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DsPresent");
2087 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersion");
2088 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersionEx");
2089 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DNSMachineName");
2091 ret &= test_EnumForms(ctx->p, ctx, &ctx->server_handle, True);
2093 ret &= test_AddForm(ctx->p, ctx, &ctx->server_handle, True);
2095 ret &= test_EnumPorts(ctx);
2097 ret &= test_GetPrinterDriverDirectory(ctx);
2099 ret &= test_EnumPrinterDrivers(ctx);
2101 ret &= test_EnumMonitors(ctx);
2103 ret &= test_EnumPrintProcessors(ctx);
2105 ret &= test_EnumPrinters(ctx);
2107 ret &= test_OpenPrinter_badnames(p, mem_ctx);
2109 ret &= test_AddPort(p, mem_ctx);
2111 ret &= test_EnumPorts_old(p, mem_ctx);
2113 ret &= test_EnumPrinters_old(p, mem_ctx);
2115 ret &= test_EnumPrinterDrivers_old(p, mem_ctx);
2117 talloc_free(mem_ctx);