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 "torture/torture.h"
25 #include "torture/rpc/rpc.h"
26 #include "librpc/gen_ndr/ndr_spoolss.h"
28 struct test_spoolss_context {
29 struct dcerpc_pipe *p;
31 /* print server handle */
32 struct policy_handle server_handle;
35 uint32_t port_count[3];
36 union spoolss_PortInfo *ports[3];
38 /* for EnumPrinterDrivers */
39 uint32_t driver_count[7];
40 union spoolss_DriverInfo *drivers[7];
42 /* for EnumMonitors */
43 uint32_t monitor_count[3];
44 union spoolss_MonitorInfo *monitors[3];
46 /* for EnumPrintProcessors */
47 uint32_t print_processor_count[2];
48 union spoolss_PrintProcessorInfo *print_processors[2];
50 /* for EnumPrinters */
51 uint32_t printer_count[6];
52 union spoolss_PrinterInfo *printers[6];
55 #define COMPARE_STRING(c,r,e) do {\
57 if (c.e && !r.e) _ok = False;\
58 if (!c.e && r.e) _ok = False;\
59 if (c.e && r.e && strcmp_safe(c.e, r.e) != 0) _ok = False;\
61 printf("%s: " #c "." #e " [%s] doesn't match " #r "." #e " [%s]\n",\
62 __location__, c.e, r.e);\
67 #define COMPARE_UINT16(c,r,e) do {\
69 printf("%s: " #c "." #e " 0x%08X (%u) doesn't match " #r "." #e " 0x%08X (%u)\n",\
70 __location__, c.e, c.e, r.e, r.e);\
75 #define COMPARE_UINT32(c,r,e) do {\
77 printf("%s: " #c "." #e " 0x%04X (%u) doesn't match " #r "." #e " 0x%04X (%u)\n",\
78 __location__, c.e, c.e, r.e, r.e);\
83 #define COMPARE_UINT64(c,r,e) do {\
85 printf("%s: " #c "." #e " 0x%016llX (%llu) doesn't match " #r "." #e " 0x%016llX (%llu)\n",\
86 __location__, c.e, c.e, r.e, r.e);\
92 #define COMPARE_SEC_DESC(c,r,e)
93 #define COMPARE_SPOOLSS_TIME(c,r,e)
94 #define COMPARE_STRING_ARRAY(c,r,e)
96 static BOOL test_OpenPrinter_server(struct test_spoolss_context *ctx)
99 struct spoolss_OpenPrinter op;
102 op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p));
103 op.in.datatype = NULL;
104 op.in.devmode_ctr.devmode= NULL;
105 op.in.access_mask = 0;
106 op.out.handle = &ctx->server_handle;
108 printf("\nTesting OpenPrinter(%s)\n", op.in.printername);
110 status = dcerpc_spoolss_OpenPrinter(ctx->p, ctx, &op);
111 if (!NT_STATUS_IS_OK(status)) {
112 printf("dcerpc_spoolss_OpenPrinter failed - %s\n", nt_errstr(status));
115 if (!W_ERROR_IS_OK(op.out.result)) {
116 printf("OpenPrinter(%s) failed - %s\n",
117 op.in.printername, win_errstr(op.out.result));
124 static BOOL test_EnumPorts(struct test_spoolss_context *ctx)
127 struct spoolss_EnumPorts r;
128 uint16_t levels[] = { 1, 2 };
132 for (i=0;i<ARRAY_SIZE(levels);i++) {
133 int level = levels[i];
136 r.in.servername = "";
141 printf("Testing EnumPorts level %u\n", r.in.level);
143 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
144 if (!NT_STATUS_IS_OK(status)) {
145 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
149 if (W_ERROR_IS_OK(r.out.result)) {
150 /* TODO: do some more checks here */
153 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
154 printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
155 win_errstr(r.out.result));
160 blob = data_blob_talloc(ctx, NULL, r.out.needed);
161 data_blob_clear(&blob);
163 r.in.offered = r.out.needed;
165 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
166 if (!NT_STATUS_IS_OK(status)) {
167 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
172 if (!W_ERROR_IS_OK(r.out.result)) {
173 printf("EnumPorts failed - %s\n",
174 win_errstr(r.out.result));
179 ctx->port_count[level] = r.out.count;
180 ctx->ports[level] = r.out.info;
183 for (i=1;i<ARRAY_SIZE(levels);i++) {
184 int level = levels[i];
185 int old_level = levels[i-1];
186 if (ctx->port_count[level] != ctx->port_count[old_level]) {
187 printf("EnumPorts level[%d] returns [%u] ports, but level[%d] returns [%u]\n",
188 level, ctx->port_count[level], old_level, ctx->port_count[old_level]);
192 /* if the array sizes are not the same we would maybe segfault in the following code */
193 if (!ret) return ret;
195 for (i=0;i<ARRAY_SIZE(levels);i++) {
196 int level = levels[i];
197 for (j=0;j<ctx->port_count[level];j++) {
198 union spoolss_PortInfo *cur = &ctx->ports[level][j];
199 union spoolss_PortInfo *ref = &ctx->ports[2][j];
202 COMPARE_STRING(cur->info1, ref->info2, port_name);
205 /* level 2 is our reference, and it makes no sense to compare it to itself */
214 static BOOL test_GetPrinterDriverDirectory(struct test_spoolss_context *ctx)
217 struct spoolss_GetPrinterDriverDirectory r;
232 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
235 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
241 for (i=0;i<ARRAY_SIZE(levels);i++) {
242 int level = levels[i].level;
245 r.in.server = levels[i].server;
246 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
251 printf("Testing GetPrinterDriverDirectory level %u\n", r.in.level);
253 status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
254 if (!NT_STATUS_IS_OK(status)) {
255 printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
259 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
260 printf("GetPrinterDriverDirectory unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
261 win_errstr(r.out.result));
266 blob = data_blob_talloc(ctx, NULL, r.out.needed);
267 data_blob_clear(&blob);
269 r.in.offered = r.out.needed;
271 status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
272 if (!NT_STATUS_IS_OK(status)) {
273 printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
278 if (!W_ERROR_IS_OK(r.out.result)) {
279 printf("GetPrinterDriverDirectory failed - %s\n",
280 win_errstr(r.out.result));
289 static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
292 struct spoolss_EnumPrinterDrivers r;
293 uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
297 for (i=0;i<ARRAY_SIZE(levels);i++) {
298 int level = levels[i];
302 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
307 printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
309 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
310 if (!NT_STATUS_IS_OK(status)) {
311 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
315 if (W_ERROR_IS_OK(r.out.result)) {
316 /* TODO: do some more checks here */
319 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
320 printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
321 win_errstr(r.out.result));
326 blob = data_blob_talloc(ctx, NULL, r.out.needed);
327 data_blob_clear(&blob);
329 r.in.offered = r.out.needed;
331 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
332 if (!NT_STATUS_IS_OK(status)) {
333 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
338 if (!W_ERROR_IS_OK(r.out.result)) {
339 printf("EnumPrinterDrivers failed - %s\n",
340 win_errstr(r.out.result));
345 ctx->driver_count[level] = r.out.count;
346 ctx->drivers[level] = r.out.info;
349 for (i=1;i<ARRAY_SIZE(levels);i++) {
350 int level = levels[i];
351 int old_level = levels[i-1];
352 if (ctx->driver_count[level] != ctx->driver_count[old_level]) {
353 printf("EnumPrinterDrivers level[%d] returns [%u] drivers, but level[%d] returns [%u]\n",
354 level, ctx->driver_count[level], old_level, ctx->driver_count[old_level]);
358 /* if the array sizes are not the same we would maybe segfault in the following code */
359 if (!ret) return ret;
361 for (i=0;i<ARRAY_SIZE(levels);i++) {
362 int level = levels[i];
363 for (j=0;j<ctx->driver_count[level];j++) {
364 union spoolss_DriverInfo *cur = &ctx->drivers[level][j];
365 union spoolss_DriverInfo *ref = &ctx->drivers[6][j];
368 COMPARE_STRING(cur->info1, ref->info6, driver_name);
371 COMPARE_UINT32(cur->info2, ref->info6, version);
372 COMPARE_STRING(cur->info2, ref->info6, driver_name);
373 COMPARE_STRING(cur->info2, ref->info6, architecture);
374 COMPARE_STRING(cur->info2, ref->info6, driver_path);
375 COMPARE_STRING(cur->info2, ref->info6, data_file);
376 COMPARE_STRING(cur->info2, ref->info6, config_file);
379 COMPARE_UINT32(cur->info3, ref->info6, version);
380 COMPARE_STRING(cur->info3, ref->info6, driver_name);
381 COMPARE_STRING(cur->info3, ref->info6, architecture);
382 COMPARE_STRING(cur->info3, ref->info6, driver_path);
383 COMPARE_STRING(cur->info3, ref->info6, data_file);
384 COMPARE_STRING(cur->info3, ref->info6, config_file);
385 COMPARE_STRING(cur->info3, ref->info6, help_file);
386 COMPARE_STRING_ARRAY(cur->info3, ref->info6, dependent_files);
387 COMPARE_STRING(cur->info3, ref->info6, monitor_name);
388 COMPARE_STRING(cur->info3, ref->info6, default_datatype);
391 COMPARE_UINT32(cur->info4, ref->info6, version);
392 COMPARE_STRING(cur->info4, ref->info6, driver_name);
393 COMPARE_STRING(cur->info4, ref->info6, architecture);
394 COMPARE_STRING(cur->info4, ref->info6, driver_path);
395 COMPARE_STRING(cur->info4, ref->info6, data_file);
396 COMPARE_STRING(cur->info4, ref->info6, config_file);
397 COMPARE_STRING(cur->info4, ref->info6, help_file);
398 COMPARE_STRING_ARRAY(cur->info4, ref->info6, dependent_files);
399 COMPARE_STRING(cur->info4, ref->info6, monitor_name);
400 COMPARE_STRING(cur->info4, ref->info6, default_datatype);
401 COMPARE_STRING_ARRAY(cur->info4, ref->info6, previous_names);
404 COMPARE_UINT32(cur->info5, ref->info6, version);
405 COMPARE_STRING(cur->info5, ref->info6, driver_name);
406 COMPARE_STRING(cur->info5, ref->info6, architecture);
407 COMPARE_STRING(cur->info5, ref->info6, driver_path);
408 COMPARE_STRING(cur->info5, ref->info6, data_file);
409 COMPARE_STRING(cur->info5, ref->info6, config_file);
410 /*COMPARE_UINT32(cur->info5, ref->info6, driver_attributes);*/
411 /*COMPARE_UINT32(cur->info5, ref->info6, config_version);*/
412 /*TODO: ! COMPARE_UINT32(cur->info5, ref->info6, driver_version); */
415 /* level 6 is our reference, and it makes no sense to compare it to itself */
424 static BOOL test_EnumMonitors(struct test_spoolss_context *ctx)
427 struct spoolss_EnumMonitors r;
428 uint16_t levels[] = { 1, 2 };
432 for (i=0;i<ARRAY_SIZE(levels);i++) {
433 int level = levels[i];
436 r.in.servername = "";
441 printf("Testing EnumMonitors level %u\n", r.in.level);
443 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
444 if (!NT_STATUS_IS_OK(status)) {
445 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
449 if (W_ERROR_IS_OK(r.out.result)) {
450 /* TODO: do some more checks here */
453 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
454 printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
455 win_errstr(r.out.result));
460 blob = data_blob_talloc(ctx, NULL, r.out.needed);
461 data_blob_clear(&blob);
463 r.in.offered = r.out.needed;
465 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
466 if (!NT_STATUS_IS_OK(status)) {
467 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
472 if (!W_ERROR_IS_OK(r.out.result)) {
473 printf("EnumMonitors failed - %s\n",
474 win_errstr(r.out.result));
479 ctx->monitor_count[level] = r.out.count;
480 ctx->monitors[level] = r.out.info;
483 for (i=1;i<ARRAY_SIZE(levels);i++) {
484 int level = levels[i];
485 int old_level = levels[i-1];
486 if (ctx->monitor_count[level] != ctx->monitor_count[old_level]) {
487 printf("EnumMonitors level[%d] returns [%u] monitors, but level[%d] returns [%u]\n",
488 level, ctx->monitor_count[level], old_level, ctx->monitor_count[old_level]);
492 /* if the array sizes are not the same we would maybe segfault in the following code */
493 if (!ret) return ret;
495 for (i=0;i<ARRAY_SIZE(levels);i++) {
496 int level = levels[i];
497 for (j=0;j<ctx->monitor_count[level];j++) {
498 union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
499 union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
502 COMPARE_STRING(cur->info1, ref->info2, monitor_name);
505 /* level 2 is our reference, and it makes no sense to compare it to itself */
514 static BOOL test_EnumPrintProcessors(struct test_spoolss_context *ctx)
517 struct spoolss_EnumPrintProcessors r;
518 uint16_t levels[] = { 1 };
522 for (i=0;i<ARRAY_SIZE(levels);i++) {
523 int level = levels[i];
526 r.in.servername = "";
527 r.in.environment = "Windows NT x86";
532 printf("Testing EnumPrintProcessors level %u\n", r.in.level);
534 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
535 if (!NT_STATUS_IS_OK(status)) {
536 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
540 if (W_ERROR_IS_OK(r.out.result)) {
541 /* TODO: do some more checks here */
544 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
545 printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
546 win_errstr(r.out.result));
551 blob = data_blob_talloc(ctx, NULL, r.out.needed);
552 data_blob_clear(&blob);
554 r.in.offered = r.out.needed;
556 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
557 if (!NT_STATUS_IS_OK(status)) {
558 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
563 if (!W_ERROR_IS_OK(r.out.result)) {
564 printf("EnumPrintProcessors failed - %s\n",
565 win_errstr(r.out.result));
570 ctx->print_processor_count[level] = r.out.count;
571 ctx->print_processors[level] = r.out.info;
574 for (i=1;i<ARRAY_SIZE(levels);i++) {
575 int level = levels[i];
576 int old_level = levels[i-1];
577 if (ctx->print_processor_count[level] != ctx->print_processor_count[old_level]) {
578 printf("EnumPrintProcessors level[%d] returns [%u] print_processors, but level[%d] returns [%u]\n",
579 level, ctx->print_processor_count[level], old_level, ctx->print_processor_count[old_level]);
583 /* if the array sizes are not the same we would maybe segfault in the following code */
584 if (!ret) return ret;
586 for (i=0;i<ARRAY_SIZE(levels);i++) {
587 int level = levels[i];
588 for (j=0;j<ctx->print_processor_count[level];j++) {
590 union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][j];
591 union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][j];
595 /* level 1 is our reference, and it makes no sense to compare it to itself */
604 static BOOL test_EnumPrinters(struct test_spoolss_context *ctx)
606 struct spoolss_EnumPrinters r;
608 uint16_t levels[] = { 0, 1, 2, 4, 5 };
612 for (i=0;i<ARRAY_SIZE(levels);i++) {
613 int level = levels[i];
616 r.in.flags = PRINTER_ENUM_LOCAL;
622 printf("\nTesting EnumPrinters level %u\n", r.in.level);
624 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
625 if (!NT_STATUS_IS_OK(status)) {
626 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
630 if (W_ERROR_IS_OK(r.out.result)) {
631 /* TODO: do some more checks here */
634 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
635 printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
636 win_errstr(r.out.result));
641 blob = data_blob_talloc(ctx, NULL, r.out.needed);
642 data_blob_clear(&blob);
644 r.in.offered = r.out.needed;
646 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
647 if (!NT_STATUS_IS_OK(status)) {
648 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
653 if (!W_ERROR_IS_OK(r.out.result)) {
654 printf("EnumPrinters failed - %s\n",
655 win_errstr(r.out.result));
659 ctx->printer_count[level] = r.out.count;
660 ctx->printers[level] = r.out.info;
663 for (i=1;i<ARRAY_SIZE(levels);i++) {
664 int level = levels[i];
665 int old_level = levels[i-1];
666 if (ctx->printer_count[level] != ctx->printer_count[old_level]) {
667 printf("EnumPrinters level[%d] returns [%u] printers, but level[%d] returns [%u]\n",
668 level, ctx->printer_count[level], old_level, ctx->printer_count[old_level]);
672 /* if the array sizes are not the same we would maybe segfault in the following code */
673 if (!ret) return ret;
675 for (i=0;i<ARRAY_SIZE(levels);i++) {
676 int level = levels[i];
677 for (j=0;j<ctx->printer_count[level];j++) {
678 union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
679 union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
682 COMPARE_STRING(cur->info0, ref->info2, printername);
683 COMPARE_STRING(cur->info0, ref->info2, servername);
684 COMPARE_UINT32(cur->info0, ref->info2, cjobs);
685 /*COMPARE_UINT32(cur->info0, ref->info2, total_jobs);
686 COMPARE_UINT32(cur->info0, ref->info2, total_bytes);
687 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
688 COMPARE_UINT32(cur->info0, ref->info2, global_counter);
689 COMPARE_UINT32(cur->info0, ref->info2, total_pages);
690 COMPARE_UINT32(cur->info0, ref->info2, version);
691 COMPARE_UINT32(cur->info0, ref->info2, unknown10);
692 COMPARE_UINT32(cur->info0, ref->info2, unknown11);
693 COMPARE_UINT32(cur->info0, ref->info2, unknown12);
694 COMPARE_UINT32(cur->info0, ref->info2, session_counter);
695 COMPARE_UINT32(cur->info0, ref->info2, unknown14);
696 COMPARE_UINT32(cur->info0, ref->info2, printer_errors);
697 COMPARE_UINT32(cur->info0, ref->info2, unknown16);
698 COMPARE_UINT32(cur->info0, ref->info2, unknown17);
699 COMPARE_UINT32(cur->info0, ref->info2, unknown18);
700 COMPARE_UINT32(cur->info0, ref->info2, unknown19);
701 COMPARE_UINT32(cur->info0, ref->info2, change_id);
702 COMPARE_UINT32(cur->info0, ref->info2, unknown21);*/
703 COMPARE_UINT32(cur->info0, ref->info2, status);
704 /*COMPARE_UINT32(cur->info0, ref->info2, unknown23);
705 COMPARE_UINT32(cur->info0, ref->info2, c_setprinter);
706 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
707 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
708 COMPARE_UINT32(cur->info0, ref->info2, unknown27);
709 COMPARE_UINT32(cur->info0, ref->info2, unknown28);
710 COMPARE_UINT32(cur->info0, ref->info2, unknown29);*/
713 /*COMPARE_UINT32(cur->info1, ref->info2, flags);*/
714 /*COMPARE_STRING(cur->info1, ref->info2, name);*/
715 /*COMPARE_STRING(cur->info1, ref->info2, description);*/
716 COMPARE_STRING(cur->info1, ref->info2, comment);
719 /* level 2 is our reference, and it makes no sense to compare it to itself */
722 COMPARE_STRING(cur->info4, ref->info2, printername);
723 COMPARE_STRING(cur->info4, ref->info2, servername);
724 COMPARE_UINT32(cur->info4, ref->info2, attributes);
727 COMPARE_STRING(cur->info5, ref->info2, printername);
728 COMPARE_STRING(cur->info5, ref->info2, portname);
729 COMPARE_UINT32(cur->info5, ref->info2, attributes);
730 /*COMPARE_UINT32(cur->info5, ref->info2, device_not_selected_timeout);
731 COMPARE_UINT32(cur->info5, ref->info2, transmission_retry_timeout);*/
738 * - verify that the port of a printer was in the list returned by EnumPorts
744 static BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
745 struct policy_handle *handle)
748 struct spoolss_GetPrinter r;
749 uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
753 for (i=0;i<ARRAY_SIZE(levels);i++) {
754 r.in.handle = handle;
755 r.in.level = levels[i];
759 printf("Testing GetPrinter level %u\n", r.in.level);
761 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
762 if (!NT_STATUS_IS_OK(status)) {
763 printf("GetPrinter failed - %s\n", nt_errstr(status));
768 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
769 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
770 data_blob_clear(&blob);
772 r.in.offered = r.out.needed;
773 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
776 if (!NT_STATUS_IS_OK(status)) {
777 printf("GetPrinter failed - %s\n", nt_errstr(status));
782 if (!W_ERROR_IS_OK(r.out.result)) {
783 printf("GetPrinter failed - %s\n",
784 win_errstr(r.out.result));
794 static BOOL test_ClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
795 struct policy_handle *handle)
798 struct spoolss_ClosePrinter r;
800 r.in.handle = handle;
801 r.out.handle = handle;
803 printf("Testing ClosePrinter\n");
805 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("ClosePrinter failed - %s\n", nt_errstr(status));
814 static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
815 struct policy_handle *handle,
816 const char *form_name)
819 struct spoolss_GetForm r;
821 r.in.handle = handle;
822 r.in.form_name = form_name;
827 printf("Testing GetForm\n");
829 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
830 if (!NT_STATUS_IS_OK(status)) {
831 printf("GetForm failed - %s\n", nt_errstr(status));
835 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
836 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
837 data_blob_clear(&blob);
839 r.in.offered = r.out.needed;
840 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
841 if (!NT_STATUS_IS_OK(status)) {
842 printf("GetForm failed - %s\n",
847 if (!W_ERROR_IS_OK(r.out.result)) {
848 printf("GetForm failed - %s\n",
849 win_errstr(r.out.result));
854 printf("No form info returned\n");
860 if (!W_ERROR_IS_OK(r.out.result)) {
861 printf("GetForm failed - %s\n",
862 win_errstr(r.out.result));
869 static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
870 struct policy_handle *handle, BOOL print_server)
873 struct spoolss_EnumForms r;
876 r.in.handle = handle;
881 printf("Testing EnumForms\n");
883 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
884 if (!NT_STATUS_IS_OK(status)) {
885 printf("EnumForms failed - %s\n", nt_errstr(status));
889 if (print_server && W_ERROR_EQUAL(r.out.result,WERR_BADFID)) {
890 printf("EnumForms on the PrintServer isn't supported by test server (NT4)\n");
894 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
895 union spoolss_FormInfo *info;
897 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
898 data_blob_clear(&blob);
900 r.in.offered = r.out.needed;
902 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
905 printf("No forms returned\n");
911 for (j = 0; j < r.out.count; j++) {
912 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, info[j].info1.form_name);
916 if (!NT_STATUS_IS_OK(status)) {
917 printf("EnumForms failed - %s\n", nt_errstr(status));
921 if (!W_ERROR_IS_OK(r.out.result)) {
922 printf("EnumForms failed - %s\n", win_errstr(r.out.result));
929 static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
930 struct policy_handle *handle,
931 const char *form_name)
934 struct spoolss_DeleteForm r;
936 r.in.handle = handle;
937 r.in.form_name = form_name;
939 status = dcerpc_spoolss_DeleteForm(p, mem_ctx, &r);
941 if (!NT_STATUS_IS_OK(status)) {
942 printf("DeleteForm failed - %s\n", nt_errstr(status));
946 if (!W_ERROR_IS_OK(r.out.result)) {
947 printf("DeleteForm failed - %s\n", win_errstr(r.out.result));
954 static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
955 struct policy_handle *handle, BOOL print_server)
957 struct spoolss_AddForm r;
958 struct spoolss_AddFormInfo1 addform;
959 const char *form_name = "testform3";
963 r.in.handle = handle;
965 r.in.info.info1 = &addform;
966 addform.flags = SPOOLSS_FORM_USER;
967 addform.form_name = form_name;
968 addform.size.width = 50;
969 addform.size.height = 25;
970 addform.area.left = 5;
971 addform.area.top = 10;
972 addform.area.right = 45;
973 addform.area.bottom = 15;
975 status = dcerpc_spoolss_AddForm(p, mem_ctx, &r);
977 if (!NT_STATUS_IS_OK(status)) {
978 printf("AddForm failed - %s\n", nt_errstr(status));
982 if (!W_ERROR_IS_OK(r.out.result)) {
983 printf("AddForm failed - %s\n", win_errstr(r.out.result));
987 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
990 struct spoolss_SetForm sf;
991 struct spoolss_AddFormInfo1 setform;
993 sf.in.handle = handle;
994 sf.in.form_name = form_name;
996 sf.in.info.info1= &setform;
997 setform.flags = addform.flags;
998 setform.form_name = addform.form_name;
999 setform.size = addform.size;
1000 setform.area = addform.area;
1002 setform.size.width = 1234;
1004 status = dcerpc_spoolss_SetForm(p, mem_ctx, &sf);
1006 if (!NT_STATUS_IS_OK(status)) {
1007 printf("SetForm failed - %s\n", nt_errstr(status));
1012 if (!W_ERROR_IS_OK(r.out.result)) {
1013 printf("SetForm failed - %s\n",
1014 win_errstr(r.out.result));
1020 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
1023 if (!test_DeleteForm(p, mem_ctx, handle, form_name)) {
1024 printf("DeleteForm failed\n");
1031 static BOOL test_EnumPorts_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1034 struct spoolss_EnumPorts r;
1036 r.in.servername = talloc_asprintf(mem_ctx, "\\\\%s",
1037 dcerpc_server_name(p));
1042 printf("Testing EnumPorts\n");
1044 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1046 if (!NT_STATUS_IS_OK(status)) {
1047 printf("EnumPorts failed - %s\n", nt_errstr(status));
1051 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1052 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1053 data_blob_clear(&blob);
1054 r.in.buffer = &blob;
1055 r.in.offered = r.out.needed;
1057 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1058 if (!NT_STATUS_IS_OK(status)) {
1059 printf("EnumPorts failed - %s\n", nt_errstr(status));
1064 printf("No ports returned\n");
1072 static BOOL test_AddPort(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1075 struct spoolss_AddPort r;
1077 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
1078 dcerpc_server_name(p));
1080 r.in.monitor_name = "foo";
1082 printf ("Testing AddPort\n");
1084 status = dcerpc_spoolss_AddPort(p, mem_ctx, &r);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 printf("AddPort failed - %s\n", nt_errstr(status));
1091 /* win2k3 returns WERR_NOT_SUPPORTED */
1095 if (!W_ERROR_IS_OK(r.out.result)) {
1096 printf("AddPort failed - %s\n", win_errstr(r.out.result));
1105 static BOOL test_GetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1106 struct policy_handle *handle, uint32_t job_id)
1109 struct spoolss_GetJob r;
1111 r.in.handle = handle;
1112 r.in.job_id = job_id;
1117 printf("Testing GetJob\n");
1119 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1120 if (!NT_STATUS_IS_OK(status)) {
1121 printf("GetJob failed - %s\n", nt_errstr(status));
1125 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1126 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1127 data_blob_clear(&blob);
1128 r.in.buffer = &blob;
1129 r.in.offered = r.out.needed;
1131 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1134 printf("No job info returned\n");
1142 static BOOL test_SetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1143 struct policy_handle *handle, uint32_t job_id, enum spoolss_JobControl command)
1146 struct spoolss_SetJob r;
1148 r.in.handle = handle;
1149 r.in.job_id = job_id;
1151 r.in.command = command;
1153 printf("Testing SetJob\n");
1155 status = dcerpc_spoolss_SetJob(p, mem_ctx, &r);
1156 if (!NT_STATUS_IS_OK(status)) {
1157 printf("SetJob failed - %s\n", nt_errstr(status));
1160 if (!W_ERROR_IS_OK(r.out.result)) {
1161 printf("SetJob failed - %s\n", win_errstr(r.out.result));
1168 static BOOL test_EnumJobs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1169 struct policy_handle *handle)
1172 struct spoolss_EnumJobs r;
1174 r.in.handle = handle;
1176 r.in.numjobs = 0xffffffff;
1181 printf("Testing EnumJobs\n");
1183 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 printf("EnumJobs failed - %s\n", nt_errstr(status));
1190 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1191 union spoolss_JobInfo *info;
1193 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1194 data_blob_clear(&blob);
1195 r.in.buffer = &blob;
1196 r.in.offered = r.out.needed;
1198 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1201 printf("No jobs returned\n");
1207 for (j = 0; j < r.out.count; j++) {
1208 test_GetJob(p, mem_ctx, handle, info[j].info1.job_id);
1209 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
1210 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
1213 } else if (!W_ERROR_IS_OK(r.out.result)) {
1214 printf("EnumJobs failed - %s\n", win_errstr(r.out.result));
1221 static BOOL test_DoPrintTest(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1222 struct policy_handle *handle)
1226 struct spoolss_StartDocPrinter s;
1227 struct spoolss_DocumentInfo1 info1;
1228 struct spoolss_StartPagePrinter sp;
1229 struct spoolss_WritePrinter w;
1230 struct spoolss_EndPagePrinter ep;
1231 struct spoolss_EndDocPrinter e;
1235 printf("Testing StartDocPrinter\n");
1237 s.in.handle = handle;
1239 s.in.info.info1 = &info1;
1240 info1.document_name = "TorturePrintJob";
1241 info1.output_file = NULL;
1242 info1.datatype = "RAW";
1244 status = dcerpc_spoolss_StartDocPrinter(p, mem_ctx, &s);
1245 if (!NT_STATUS_IS_OK(status)) {
1246 printf("dcerpc_spoolss_StartDocPrinter failed - %s\n", nt_errstr(status));
1249 if (!W_ERROR_IS_OK(s.out.result)) {
1250 printf("StartDocPrinter failed - %s\n", win_errstr(s.out.result));
1254 job_id = s.out.job_id;
1256 for (i=1; i < 4; i++) {
1257 printf("Testing StartPagePrinter: Page[%d]\n", i);
1259 sp.in.handle = handle;
1261 status = dcerpc_spoolss_StartPagePrinter(p, mem_ctx, &sp);
1262 if (!NT_STATUS_IS_OK(status)) {
1263 printf("dcerpc_spoolss_StartPagePrinter failed - %s\n", nt_errstr(status));
1266 if (!W_ERROR_IS_OK(sp.out.result)) {
1267 printf("StartPagePrinter failed - %s\n", win_errstr(sp.out.result));
1271 printf("Testing WritePrinter: Page[%d]\n", i);
1273 w.in.handle = handle;
1274 w.in.data = data_blob_string_const(talloc_asprintf(mem_ctx,"TortureTestPage: %d\nData\n",i));
1276 status = dcerpc_spoolss_WritePrinter(p, mem_ctx, &w);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 printf("dcerpc_spoolss_WritePrinter failed - %s\n", nt_errstr(status));
1281 if (!W_ERROR_IS_OK(w.out.result)) {
1282 printf("WritePrinter failed - %s\n", win_errstr(w.out.result));
1286 printf("Testing EndPagePrinter: Page[%d]\n", i);
1288 ep.in.handle = handle;
1290 status = dcerpc_spoolss_EndPagePrinter(p, mem_ctx, &ep);
1291 if (!NT_STATUS_IS_OK(status)) {
1292 printf("dcerpc_spoolss_EndPagePrinter failed - %s\n", nt_errstr(status));
1295 if (!W_ERROR_IS_OK(ep.out.result)) {
1296 printf("EndPagePrinter failed - %s\n", win_errstr(ep.out.result));
1301 printf("Testing EndDocPrinter\n");
1303 e.in.handle = handle;
1305 status = dcerpc_spoolss_EndDocPrinter(p, mem_ctx, &e);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 printf("dcerpc_spoolss_EndDocPrinter failed - %s\n", nt_errstr(status));
1310 if (!W_ERROR_IS_OK(e.out.result)) {
1311 printf("EndDocPrinter failed - %s\n", win_errstr(e.out.result));
1315 ret &= test_EnumJobs(p, mem_ctx, handle);
1317 ret &= test_SetJob(p, mem_ctx, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
1322 static BOOL test_PausePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1323 struct policy_handle *handle)
1326 struct spoolss_SetPrinter r;
1328 r.in.handle = handle;
1330 r.in.info.info1 = NULL;
1331 r.in.devmode_ctr.devmode= NULL;
1332 r.in.secdesc_ctr.sd = NULL;
1333 r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
1335 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1337 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 printf("SetPrinter failed - %s\n", nt_errstr(status));
1344 if (!W_ERROR_IS_OK(r.out.result)) {
1345 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1352 static BOOL test_ResumePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1353 struct policy_handle *handle)
1356 struct spoolss_SetPrinter r;
1358 r.in.handle = handle;
1360 r.in.info.info1 = NULL;
1361 r.in.devmode_ctr.devmode= NULL;
1362 r.in.secdesc_ctr.sd = NULL;
1363 r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
1365 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1367 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1369 if (!NT_STATUS_IS_OK(status)) {
1370 printf("SetPrinter failed - %s\n", nt_errstr(status));
1374 if (!W_ERROR_IS_OK(r.out.result)) {
1375 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1382 static BOOL test_GetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1383 struct policy_handle *handle,
1384 const char *value_name)
1387 struct spoolss_GetPrinterData r;
1389 r.in.handle = handle;
1390 r.in.value_name = value_name;
1393 printf("Testing GetPrinterData\n");
1395 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 printf("GetPrinterData failed - %s\n", nt_errstr(status));
1401 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1402 r.in.offered = r.out.needed;
1404 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 printf("GetPrinterData failed - %s\n",
1411 if (!W_ERROR_IS_OK(r.out.result)) {
1412 printf("GetPrinterData failed - %s\n",
1413 win_errstr(r.out.result));
1421 static BOOL test_GetPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1422 struct policy_handle *handle,
1423 const char *key_name,
1424 const char *value_name)
1427 struct spoolss_GetPrinterDataEx r;
1429 r.in.handle = handle;
1430 r.in.key_name = key_name;
1431 r.in.value_name = value_name;
1434 printf("Testing GetPrinterDataEx\n");
1436 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1437 if (!NT_STATUS_IS_OK(status)) {
1438 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1439 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1440 printf("GetPrinterDataEx not supported by server\n");
1443 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status));
1447 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1448 r.in.offered = r.out.needed;
1450 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 printf("GetPrinterDataEx failed - %s\n",
1457 if (!W_ERROR_IS_OK(r.out.result)) {
1458 printf("GetPrinterDataEx failed - %s\n",
1459 win_errstr(r.out.result));
1467 static BOOL test_EnumPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1468 struct policy_handle *handle)
1471 struct spoolss_EnumPrinterData r;
1473 r.in.handle = handle;
1474 r.in.enum_index = 0;
1479 r.in.value_offered = 0;
1481 r.in.data_size = &data_size;
1482 r.out.data_size = &data_size;
1484 printf("Testing EnumPrinterData\n");
1486 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1488 if (!NT_STATUS_IS_OK(status)) {
1489 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1493 r.in.value_offered = r.out.value_needed;
1495 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1497 if (!NT_STATUS_IS_OK(status)) {
1498 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1502 test_GetPrinterData(p, mem_ctx, handle, r.out.value_name);
1504 test_GetPrinterDataEx(
1505 p, mem_ctx, handle, "PrinterDriverData",
1510 } while (W_ERROR_IS_OK(r.out.result));
1515 static BOOL test_EnumPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1516 struct policy_handle *handle)
1519 struct spoolss_EnumPrinterDataEx r;
1521 r.in.handle = handle;
1522 r.in.key_name = "PrinterDriverData";
1525 printf("Testing EnumPrinterDataEx\n");
1527 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1528 if (!NT_STATUS_IS_OK(status)) {
1529 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1533 r.in.offered = r.out.needed;
1535 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1537 if (!NT_STATUS_IS_OK(status)) {
1538 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1546 static BOOL test_DeletePrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1547 struct policy_handle *handle,
1548 const char *value_name)
1551 struct spoolss_DeletePrinterData r;
1553 r.in.handle = handle;
1554 r.in.value_name = value_name;
1556 printf("Testing DeletePrinterData\n");
1558 status = dcerpc_spoolss_DeletePrinterData(p, mem_ctx, &r);
1560 if (!NT_STATUS_IS_OK(status)) {
1561 printf("DeletePrinterData failed - %s\n", nt_errstr(status));
1568 static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1569 struct policy_handle *handle)
1572 struct spoolss_SetPrinterData r;
1573 const char *value_name = "spottyfoot";
1575 r.in.handle = handle;
1576 r.in.value_name = value_name;
1577 r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
1578 r.in.data.string = "dog";
1580 printf("Testing SetPrinterData\n");
1582 status = dcerpc_spoolss_SetPrinterData(p, mem_ctx, &r);
1584 if (!NT_STATUS_IS_OK(status)) {
1585 printf("SetPrinterData failed - %s\n", nt_errstr(status));
1589 if (!test_GetPrinterData(p, mem_ctx, handle, value_name)) {
1593 if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) {
1600 static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1601 struct policy_handle *handle)
1604 struct dcerpc_binding *b;
1605 struct dcerpc_pipe *p2;
1608 /* only makes sense on SMB */
1609 if (p->conn->transport.transport != NCACN_NP) {
1613 printf("testing close on secondary pipe\n");
1615 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1616 if (!NT_STATUS_IS_OK(status)) {
1617 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1621 status = dcerpc_secondary_connection(p, &p2, b);
1622 if (!NT_STATUS_IS_OK(status)) {
1623 printf("Failed to create secondary connection\n");
1627 status = dcerpc_bind_auth_none(p2, &dcerpc_table_spoolss);
1628 if (!NT_STATUS_IS_OK(status)) {
1629 printf("Failed to create bind on secondary connection\n");
1635 if (test_ClosePrinter(p2, mem_ctx, handle)) {
1636 printf("ERROR: Allowed close on secondary connection!\n");
1640 if (p2->last_fault_code != DCERPC_FAULT_CONTEXT_MISMATCH) {
1641 printf("Unexpected fault code 0x%x - expected 0x%x\n",
1642 p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH);
1651 static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
1654 struct spoolss_OpenPrinter op;
1655 struct spoolss_OpenPrinterEx opEx;
1656 struct policy_handle handle;
1659 op.in.printername = name;
1660 op.in.datatype = NULL;
1661 op.in.devmode_ctr.devmode= NULL;
1662 op.in.access_mask = 0;
1663 op.out.handle = &handle;
1665 printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1667 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
1668 if (!NT_STATUS_IS_OK(status)) {
1669 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1672 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1673 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1674 name, win_errstr(op.out.result));
1677 if (W_ERROR_IS_OK(op.out.result)) {
1678 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1681 opEx.in.printername = name;
1682 opEx.in.datatype = NULL;
1683 opEx.in.devmode_ctr.devmode = NULL;
1684 opEx.in.access_mask = 0;
1686 opEx.in.userlevel.level1 = NULL;
1687 opEx.out.handle = &handle;
1689 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1691 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
1692 if (!NT_STATUS_IS_OK(status)) {
1693 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1696 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
1697 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1698 name, win_errstr(opEx.out.result));
1701 if (W_ERROR_IS_OK(opEx.out.result)) {
1702 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1708 static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1713 ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
1714 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
1715 ret &= test_OpenPrinter_badname(p, mem_ctx, "");
1716 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
1717 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
1719 name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
1720 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1723 name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
1724 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1730 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1734 struct spoolss_OpenPrinter r;
1735 struct policy_handle handle;
1738 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1739 r.in.datatype = NULL;
1740 r.in.devmode_ctr.devmode= NULL;
1741 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1742 r.out.handle = &handle;
1744 printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
1746 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1753 if (!W_ERROR_IS_OK(r.out.result)) {
1754 printf("OpenPrinter failed - %s\n", win_errstr(r.out.result));
1758 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1762 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1766 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1773 static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1774 const char *name, struct policy_handle *handle)
1776 struct spoolss_OpenPrinterEx r;
1777 struct spoolss_UserLevel1 userlevel1;
1780 if (name && name[0]) {
1781 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
1782 dcerpc_server_name(p), name);
1784 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
1785 dcerpc_server_name(p));
1788 r.in.datatype = NULL;
1789 r.in.devmode_ctr.devmode= NULL;
1790 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1792 r.in.userlevel.level1 = &userlevel1;
1793 r.out.handle = handle;
1795 userlevel1.size = 1234;
1796 userlevel1.client = "hello";
1797 userlevel1.user = "spottyfoot!";
1798 userlevel1.build = 1;
1799 userlevel1.major = 2;
1800 userlevel1.minor = 3;
1801 userlevel1.processor = 4;
1803 printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
1805 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
1807 if (!NT_STATUS_IS_OK(status)) {
1808 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
1812 if (!W_ERROR_IS_OK(r.out.result)) {
1813 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
1820 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1823 struct policy_handle handle;
1826 if (!call_OpenPrinterEx(p, mem_ctx, name, &handle)) {
1830 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1834 if (!test_EnumForms(p, mem_ctx, &handle, False)) {
1838 if (!test_AddForm(p, mem_ctx, &handle, False)) {
1842 if (!test_EnumPrinterData(p, mem_ctx, &handle)) {
1846 if (!test_EnumPrinterDataEx(p, mem_ctx, &handle)) {
1850 if (!test_PausePrinter(p, mem_ctx, &handle)) {
1854 if (!test_DoPrintTest(p, mem_ctx, &handle)) {
1858 if (!test_ResumePrinter(p, mem_ctx, &handle)) {
1862 if (!test_SetPrinterData(p, mem_ctx, &handle)) {
1866 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1870 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1877 static BOOL test_EnumPrinters_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1879 struct spoolss_EnumPrinters r;
1881 uint16_t levels[] = {1, 2, 4, 5};
1885 for (i=0;i<ARRAY_SIZE(levels);i++) {
1886 union spoolss_PrinterInfo *info;
1889 r.in.flags = PRINTER_ENUM_LOCAL;
1891 r.in.level = levels[i];
1895 printf("\nTesting EnumPrinters level %u\n", r.in.level);
1897 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 printf("EnumPrinters failed - %s\n", nt_errstr(status));
1904 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1905 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1906 data_blob_clear(&blob);
1907 r.in.buffer = &blob;
1908 r.in.offered = r.out.needed;
1909 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1912 if (!NT_STATUS_IS_OK(status)) {
1913 printf("EnumPrinters failed - %s\n",
1918 if (!W_ERROR_IS_OK(r.out.result)) {
1919 printf("EnumPrinters failed - %s\n",
1920 win_errstr(r.out.result));
1925 printf("No printers returned\n");
1931 for (j=0;j<r.out.count;j++) {
1932 if (r.in.level == 1) {
1933 /* the names appear to be comma-separated name lists? */
1934 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
1935 char *comma = strchr(name, ',');
1936 if (comma) *comma = 0;
1937 if (!test_OpenPrinter(p, mem_ctx, name)) {
1940 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
1951 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1952 struct policy_handle *handle,
1953 const char *driver_name)
1956 struct spoolss_GetPrinterDriver2 r;
1958 r.in.handle = handle;
1959 r.in.architecture = "W32X86";
1963 r.in.client_major_version = 0;
1964 r.in.client_minor_version = 0;
1966 printf("Testing GetPrinterDriver2\n");
1968 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1969 if (!NT_STATUS_IS_OK(status)) {
1970 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1974 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1975 r.in.offered = r.out.needed;
1976 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1979 if (!NT_STATUS_IS_OK(status)) {
1980 printf("GetPrinterDriver2 failed - %s\n",
1985 if (!W_ERROR_IS_OK(r.out.result)) {
1986 printf("GetPrinterDriver2 failed - %s\n",
1987 win_errstr(r.out.result));
1995 static BOOL test_EnumPrinterDrivers_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1997 struct spoolss_EnumPrinterDrivers r;
1999 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
2003 for (i=0;i<ARRAY_SIZE(levels);i++) {
2005 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
2006 r.in.environment = "Windows NT x86";
2007 r.in.level = levels[i];
2011 printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
2013 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2015 if (!NT_STATUS_IS_OK(status)) {
2016 printf("EnumPrinterDrivers failed - %s\n",
2022 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2023 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2024 data_blob_clear(&blob);
2025 r.in.buffer = &blob;
2026 r.in.offered = r.out.needed;
2027 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2030 if (!NT_STATUS_IS_OK(status)) {
2031 printf("EnumPrinterDrivers failed - %s\n",
2037 if (!W_ERROR_IS_OK(r.out.result)) {
2038 printf("EnumPrinterDrivers failed - %s\n",
2039 win_errstr(r.out.result));
2045 printf("No printer drivers returned\n");
2053 BOOL torture_rpc_spoolss(void)
2056 struct dcerpc_pipe *p;
2057 TALLOC_CTX *mem_ctx;
2059 struct test_spoolss_context *ctx;
2061 mem_ctx = talloc_init("torture_rpc_spoolss");
2063 status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_spoolss);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 talloc_free(mem_ctx);
2069 ctx = talloc_zero(mem_ctx, struct test_spoolss_context);
2072 ret &= test_OpenPrinter_server(ctx);
2074 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "W3SvcInstalled");
2075 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "BeepEnabled");
2076 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "EventLog");
2077 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopup");
2078 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopupToComputer");
2079 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MajorVersion");
2080 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MinorVersion");
2081 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");
2082 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "Architecture");
2083 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DsPresent");
2084 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersion");
2085 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersionEx");
2086 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DNSMachineName");
2088 ret &= test_EnumForms(ctx->p, ctx, &ctx->server_handle, True);
2090 ret &= test_AddForm(ctx->p, ctx, &ctx->server_handle, True);
2092 ret &= test_EnumPorts(ctx);
2094 ret &= test_GetPrinterDriverDirectory(ctx);
2096 ret &= test_EnumPrinterDrivers(ctx);
2098 ret &= test_EnumMonitors(ctx);
2100 ret &= test_EnumPrintProcessors(ctx);
2102 ret &= test_EnumPrinters(ctx);
2104 ret &= test_OpenPrinter_badnames(p, mem_ctx);
2106 ret &= test_AddPort(p, mem_ctx);
2108 ret &= test_EnumPorts_old(p, mem_ctx);
2110 ret &= test_EnumPrinters_old(p, mem_ctx);
2112 ret &= test_EnumPrinterDrivers_old(p, mem_ctx);
2114 talloc_free(mem_ctx);