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%08X%08X (%llu) doesn't match " #r "." #e " 0x%08X%08X (%llu)\n",\
84 __location__, (uint32_t)(c.e >> 32), (uint32_t)(c.e & 0xFFFFFFFF), c.e,\
85 (uint32_t)(r.e >> 32), (uint32_t)(r.e & 0xFFFFFFFF), r.e);\
91 #define COMPARE_SEC_DESC(c,r,e)
92 #define COMPARE_SPOOLSS_TIME(c,r,e)
93 #define COMPARE_STRING_ARRAY(c,r,e)
95 static BOOL test_OpenPrinter_server(struct test_spoolss_context *ctx)
98 struct spoolss_OpenPrinter op;
101 op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p));
102 op.in.datatype = NULL;
103 op.in.devmode_ctr.size = 0;
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);
843 printf("No form info returned\n");
851 static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
852 struct policy_handle *handle, BOOL print_server)
855 struct spoolss_EnumForms r;
857 r.in.handle = handle;
862 printf("Testing EnumForms\n");
864 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
865 if (!NT_STATUS_IS_OK(status)) {
866 printf("EnumForms failed - %s\n", nt_errstr(status));
870 if (print_server && W_ERROR_EQUAL(r.out.result,WERR_BADFID)) {
871 printf("EnumForms on the PrintServer isn't supported by test server (NT4)\n");
875 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
876 union spoolss_FormInfo *info;
878 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
879 data_blob_clear(&blob);
881 r.in.offered = r.out.needed;
883 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
886 printf("No forms returned\n");
892 for (j = 0; j < r.out.count; j++) {
893 test_GetForm(p, mem_ctx, handle, info[j].info1.form_name);
897 if (!NT_STATUS_IS_OK(status)) {
898 printf("EnumForms failed - %s\n", nt_errstr(status));
902 if (!W_ERROR_IS_OK(r.out.result)) {
903 printf("EnumForms failed - %s\n", win_errstr(r.out.result));
910 static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
911 struct policy_handle *handle,
912 const char *form_name)
915 struct spoolss_DeleteForm r;
917 r.in.handle = handle;
918 r.in.form_name = form_name;
920 status = dcerpc_spoolss_DeleteForm(p, mem_ctx, &r);
922 if (!NT_STATUS_IS_OK(status)) {
923 printf("DeleteForm failed - %s\n", nt_errstr(status));
927 if (!W_ERROR_IS_OK(r.out.result)) {
928 printf("DeleteForm failed - %s\n", win_errstr(r.out.result));
935 static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
936 struct policy_handle *handle)
938 struct spoolss_AddForm r;
939 struct spoolss_AddFormInfo1 addform;
940 const char *form_name = "testform3";
944 r.in.handle = handle;
946 r.in.info.info1 = &addform;
947 addform.flags = SPOOLSS_FORM_USER;
948 addform.form_name = form_name;
949 addform.size.width = 50;
950 addform.size.height = 25;
951 addform.area.left = 5;
952 addform.area.top = 10;
953 addform.area.right = 45;
954 addform.area.bottom = 15;
956 status = dcerpc_spoolss_AddForm(p, mem_ctx, &r);
958 if (!NT_STATUS_IS_OK(status)) {
959 printf("AddForm failed - %s\n", nt_errstr(status));
963 if (!W_ERROR_IS_OK(r.out.result)) {
964 printf("AddForm failed - %s\n", nt_errstr(status));
969 struct spoolss_SetForm sf;
970 struct spoolss_AddFormInfo1 setform;
972 sf.in.handle = handle;
973 sf.in.form_name = form_name;
975 sf.in.info.info1= &setform;
976 setform.flags = addform.flags;
977 setform.form_name = addform.form_name;
978 setform.size = addform.size;
979 setform.area = addform.area;
981 setform.size.width = 1234;
983 status = dcerpc_spoolss_SetForm(p, mem_ctx, &sf);
985 if (!NT_STATUS_IS_OK(status)) {
986 printf("SetForm failed - %s\n", nt_errstr(status));
991 if (!W_ERROR_IS_OK(r.out.result)) {
992 printf("SetForm failed - %s\n",
993 win_errstr(r.out.result));
1000 if (!test_DeleteForm(p, mem_ctx, handle, form_name)) {
1001 printf("DeleteForm failed\n");
1008 static BOOL test_EnumPorts_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1011 struct spoolss_EnumPorts r;
1013 r.in.servername = talloc_asprintf(mem_ctx, "\\\\%s",
1014 dcerpc_server_name(p));
1019 printf("Testing EnumPorts\n");
1021 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1023 if (!NT_STATUS_IS_OK(status)) {
1024 printf("EnumPorts failed - %s\n", nt_errstr(status));
1028 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1029 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1030 data_blob_clear(&blob);
1031 r.in.buffer = &blob;
1032 r.in.offered = r.out.needed;
1034 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 printf("EnumPorts failed - %s\n", nt_errstr(status));
1041 printf("No ports returned\n");
1049 static BOOL test_AddPort(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1052 struct spoolss_AddPort r;
1054 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
1055 dcerpc_server_name(p));
1057 r.in.monitor_name = "foo";
1059 printf ("Testing AddPort\n");
1061 status = dcerpc_spoolss_AddPort(p, mem_ctx, &r);
1063 if (!NT_STATUS_IS_OK(status)) {
1064 printf("AddPort failed - %s\n", nt_errstr(status));
1068 /* win2k3 returns WERR_NOT_SUPPORTED */
1072 if (!W_ERROR_IS_OK(r.out.result)) {
1073 printf("AddPort failed - %s\n", win_errstr(r.out.result));
1082 static BOOL test_GetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1083 struct policy_handle *handle, uint32_t job_id)
1086 struct spoolss_GetJob r;
1088 r.in.handle = handle;
1089 r.in.job_id = job_id;
1094 printf("Testing GetJob\n");
1096 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 printf("GetJob failed - %s\n", nt_errstr(status));
1102 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1103 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1104 data_blob_clear(&blob);
1105 r.in.buffer = &blob;
1106 r.in.offered = r.out.needed;
1108 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1111 printf("No job info returned\n");
1119 static BOOL test_SetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1120 struct policy_handle *handle, uint32_t job_id, enum spoolss_JobControl command)
1123 struct spoolss_SetJob r;
1125 r.in.handle = handle;
1126 r.in.job_id = job_id;
1128 r.in.command = command;
1130 printf("Testing SetJob\n");
1132 status = dcerpc_spoolss_SetJob(p, mem_ctx, &r);
1133 if (!NT_STATUS_IS_OK(status)) {
1134 printf("SetJob failed - %s\n", nt_errstr(status));
1137 if (!W_ERROR_IS_OK(r.out.result)) {
1138 printf("SetJob failed - %s\n", win_errstr(r.out.result));
1145 static BOOL test_EnumJobs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1146 struct policy_handle *handle)
1149 struct spoolss_EnumJobs r;
1151 r.in.handle = handle;
1153 r.in.numjobs = 0xffffffff;
1158 printf("Testing EnumJobs\n");
1160 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1162 if (!NT_STATUS_IS_OK(status)) {
1163 printf("EnumJobs failed - %s\n", nt_errstr(status));
1167 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1168 union spoolss_JobInfo *info;
1170 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1171 data_blob_clear(&blob);
1172 r.in.buffer = &blob;
1173 r.in.offered = r.out.needed;
1175 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1178 printf("No jobs returned\n");
1184 for (j = 0; j < r.out.count; j++) {
1185 test_GetJob(p, mem_ctx, handle, info[j].info1.job_id);
1186 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
1187 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
1190 } else if (!W_ERROR_IS_OK(r.out.result)) {
1191 printf("EnumJobs failed - %s\n", win_errstr(r.out.result));
1198 static BOOL test_DoPrintTest(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1199 struct policy_handle *handle)
1203 struct spoolss_StartDocPrinter s;
1204 struct spoolss_DocumentInfo1 info1;
1205 struct spoolss_StartPagePrinter sp;
1206 struct spoolss_WritePrinter w;
1207 struct spoolss_EndPagePrinter ep;
1208 struct spoolss_EndDocPrinter e;
1212 printf("Testing StartDocPrinter\n");
1214 s.in.handle = handle;
1216 s.in.info.info1 = &info1;
1217 info1.document_name = "TorturePrintJob";
1218 info1.output_file = NULL;
1219 info1.datatype = "RAW";
1221 status = dcerpc_spoolss_StartDocPrinter(p, mem_ctx, &s);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 printf("dcerpc_spoolss_StartDocPrinter failed - %s\n", nt_errstr(status));
1226 if (!W_ERROR_IS_OK(s.out.result)) {
1227 printf("StartDocPrinter failed - %s\n", win_errstr(s.out.result));
1231 job_id = s.out.job_id;
1233 for (i=1; i < 4; i++) {
1234 printf("Testing StartPagePrinter: Page[%d]\n", i);
1236 sp.in.handle = handle;
1238 status = dcerpc_spoolss_StartPagePrinter(p, mem_ctx, &sp);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 printf("dcerpc_spoolss_StartPagePrinter failed - %s\n", nt_errstr(status));
1243 if (!W_ERROR_IS_OK(sp.out.result)) {
1244 printf("StartPagePrinter failed - %s\n", win_errstr(sp.out.result));
1248 printf("Testing WritePrinter: Page[%d]\n", i);
1250 w.in.handle = handle;
1251 w.in.data = data_blob_string_const(talloc_asprintf(mem_ctx,"TortureTestPage: %d\nData\n",i));
1253 status = dcerpc_spoolss_WritePrinter(p, mem_ctx, &w);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 printf("dcerpc_spoolss_WritePrinter failed - %s\n", nt_errstr(status));
1258 if (!W_ERROR_IS_OK(w.out.result)) {
1259 printf("WritePrinter failed - %s\n", win_errstr(w.out.result));
1263 printf("Testing EndPagePrinter: Page[%d]\n", i);
1265 ep.in.handle = handle;
1267 status = dcerpc_spoolss_EndPagePrinter(p, mem_ctx, &ep);
1268 if (!NT_STATUS_IS_OK(status)) {
1269 printf("dcerpc_spoolss_EndPagePrinter failed - %s\n", nt_errstr(status));
1272 if (!W_ERROR_IS_OK(ep.out.result)) {
1273 printf("EndPagePrinter failed - %s\n", win_errstr(ep.out.result));
1278 printf("Testing EndDocPrinter\n");
1280 e.in.handle = handle;
1282 status = dcerpc_spoolss_EndDocPrinter(p, mem_ctx, &e);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 printf("dcerpc_spoolss_EndDocPrinter failed - %s\n", nt_errstr(status));
1287 if (!W_ERROR_IS_OK(e.out.result)) {
1288 printf("EndDocPrinter failed - %s\n", win_errstr(e.out.result));
1292 ret &= test_EnumJobs(p, mem_ctx, handle);
1294 ret &= test_SetJob(p, mem_ctx, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
1299 static BOOL test_PausePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1300 struct policy_handle *handle)
1303 struct spoolss_SetPrinter r;
1305 r.in.handle = handle;
1307 r.in.info.info1 = NULL;
1308 r.in.devmode_ctr.size = 0;
1309 r.in.devmode_ctr.devmode= NULL;
1310 r.in.secdesc_ctr.size = 0;
1311 r.in.secdesc_ctr.sd = NULL;
1312 r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
1314 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1316 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 printf("SetPrinter failed - %s\n", nt_errstr(status));
1323 if (!W_ERROR_IS_OK(r.out.result)) {
1324 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1331 static BOOL test_ResumePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1332 struct policy_handle *handle)
1335 struct spoolss_SetPrinter r;
1337 r.in.handle = handle;
1339 r.in.info.info1 = NULL;
1340 r.in.devmode_ctr.size = 0;
1341 r.in.devmode_ctr.devmode= NULL;
1342 r.in.secdesc_ctr.size = 0;
1343 r.in.secdesc_ctr.sd = NULL;
1344 r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
1346 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1348 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1350 if (!NT_STATUS_IS_OK(status)) {
1351 printf("SetPrinter failed - %s\n", nt_errstr(status));
1355 if (!W_ERROR_IS_OK(r.out.result)) {
1356 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1363 static BOOL test_GetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1364 struct policy_handle *handle,
1365 const char *value_name)
1368 struct spoolss_GetPrinterData r;
1370 r.in.handle = handle;
1371 r.in.value_name = value_name;
1374 printf("Testing GetPrinterData\n");
1376 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 printf("GetPrinterData failed - %s\n", nt_errstr(status));
1382 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1383 r.in.offered = r.out.needed;
1385 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1386 if (!NT_STATUS_IS_OK(status)) {
1387 printf("GetPrinterData failed - %s\n",
1392 if (!W_ERROR_IS_OK(r.out.result)) {
1393 printf("GetPrinterData failed - %s\n",
1394 win_errstr(r.out.result));
1402 static BOOL test_GetPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1403 struct policy_handle *handle,
1404 const char *key_name,
1405 const char *value_name)
1408 struct spoolss_GetPrinterDataEx r;
1410 r.in.handle = handle;
1411 r.in.key_name = key_name;
1412 r.in.value_name = value_name;
1415 printf("Testing GetPrinterDataEx\n");
1417 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1418 if (!NT_STATUS_IS_OK(status)) {
1419 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1420 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1421 printf("GetPrinterDataEx not supported by server\n");
1424 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status));
1428 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1429 r.in.offered = r.out.needed;
1431 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1432 if (!NT_STATUS_IS_OK(status)) {
1433 printf("GetPrinterDataEx failed - %s\n",
1438 if (!W_ERROR_IS_OK(r.out.result)) {
1439 printf("GetPrinterDataEx failed - %s\n",
1440 win_errstr(r.out.result));
1448 static BOOL test_EnumPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1449 struct policy_handle *handle)
1452 struct spoolss_EnumPrinterData r;
1454 r.in.handle = handle;
1455 r.in.enum_index = 0;
1460 r.in.value_offered = 0;
1462 r.in.data_size = &data_size;
1463 r.out.data_size = &data_size;
1465 printf("Testing EnumPrinterData\n");
1467 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1469 if (!NT_STATUS_IS_OK(status)) {
1470 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1474 r.in.value_offered = r.out.value_needed;
1476 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1478 if (!NT_STATUS_IS_OK(status)) {
1479 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1483 test_GetPrinterData(p, mem_ctx, handle, r.out.value_name);
1485 test_GetPrinterDataEx(
1486 p, mem_ctx, handle, "PrinterDriverData",
1491 } while (W_ERROR_IS_OK(r.out.result));
1496 static BOOL test_EnumPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1497 struct policy_handle *handle)
1500 struct spoolss_EnumPrinterDataEx r;
1502 r.in.handle = handle;
1503 r.in.key_name = "PrinterDriverData";
1506 printf("Testing EnumPrinterDataEx\n");
1508 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1509 if (!NT_STATUS_IS_OK(status)) {
1510 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1514 r.in.offered = r.out.needed;
1516 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1518 if (!NT_STATUS_IS_OK(status)) {
1519 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1527 static BOOL test_DeletePrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1528 struct policy_handle *handle,
1529 const char *value_name)
1532 struct spoolss_DeletePrinterData r;
1534 r.in.handle = handle;
1535 r.in.value_name = value_name;
1537 printf("Testing DeletePrinterData\n");
1539 status = dcerpc_spoolss_DeletePrinterData(p, mem_ctx, &r);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 printf("DeletePrinterData failed - %s\n", nt_errstr(status));
1549 static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1550 struct policy_handle *handle)
1553 struct spoolss_SetPrinterData r;
1554 const char *value_name = "spottyfoot";
1556 r.in.handle = handle;
1557 r.in.value_name = value_name;
1558 r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
1559 r.in.data.string = "dog";
1561 printf("Testing SetPrinterData\n");
1563 status = dcerpc_spoolss_SetPrinterData(p, mem_ctx, &r);
1565 if (!NT_STATUS_IS_OK(status)) {
1566 printf("SetPrinterData failed - %s\n", nt_errstr(status));
1570 if (!test_GetPrinterData(p, mem_ctx, handle, value_name)) {
1574 if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) {
1581 static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1582 struct policy_handle *handle)
1585 struct dcerpc_binding *b;
1586 struct dcerpc_pipe *p2;
1589 /* only makes sense on SMB */
1590 if (p->conn->transport.transport != NCACN_NP) {
1594 printf("testing close on secondary pipe\n");
1596 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1597 if (!NT_STATUS_IS_OK(status)) {
1598 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1602 status = dcerpc_secondary_connection(p, &p2, b);
1603 if (!NT_STATUS_IS_OK(status)) {
1604 printf("Failed to create secondary connection\n");
1608 status = dcerpc_bind_auth_none(p2, DCERPC_SPOOLSS_UUID,
1609 DCERPC_SPOOLSS_VERSION);
1610 if (!NT_STATUS_IS_OK(status)) {
1611 printf("Failed to create bind on secondary connection\n");
1617 if (test_ClosePrinter(p2, mem_ctx, handle)) {
1618 printf("ERROR: Allowed close on secondary connection!\n");
1622 if (p2->last_fault_code != DCERPC_FAULT_CONTEXT_MISMATCH) {
1623 printf("Unexpected fault code 0x%x - expected 0x%x\n",
1624 p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH);
1633 static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
1636 struct spoolss_OpenPrinter op;
1637 struct spoolss_OpenPrinterEx opEx;
1638 struct policy_handle handle;
1641 op.in.printername = name;
1642 op.in.datatype = NULL;
1643 op.in.devmode_ctr.size = 0;
1644 op.in.devmode_ctr.devmode= NULL;
1645 op.in.access_mask = 0;
1646 op.out.handle = &handle;
1648 printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1650 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
1651 if (!NT_STATUS_IS_OK(status)) {
1652 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1655 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1656 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1657 name, win_errstr(op.out.result));
1660 if (W_ERROR_IS_OK(op.out.result)) {
1661 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1664 opEx.in.printername = name;
1665 opEx.in.datatype = NULL;
1666 opEx.in.devmode_ctr.size = 0;
1667 opEx.in.devmode_ctr.devmode = NULL;
1668 opEx.in.access_mask = 0;
1670 opEx.in.userlevel.level1 = NULL;
1671 opEx.out.handle = &handle;
1673 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1675 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
1676 if (!NT_STATUS_IS_OK(status)) {
1677 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1680 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
1681 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1682 name, win_errstr(opEx.out.result));
1685 if (W_ERROR_IS_OK(opEx.out.result)) {
1686 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1692 static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1697 ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
1698 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
1699 ret &= test_OpenPrinter_badname(p, mem_ctx, "");
1700 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
1701 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
1703 name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
1704 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1707 name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
1708 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1714 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1718 struct spoolss_OpenPrinter r;
1719 struct policy_handle handle;
1722 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1723 r.in.datatype = NULL;
1724 r.in.devmode_ctr.size = 0;
1725 r.in.devmode_ctr.devmode= NULL;
1726 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1727 r.out.handle = &handle;
1729 printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
1731 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
1733 if (!NT_STATUS_IS_OK(status)) {
1734 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1738 if (!W_ERROR_IS_OK(r.out.result)) {
1739 printf("OpenPrinter failed - %s\n", win_errstr(r.out.result));
1743 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1747 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1751 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1758 static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1759 const char *name, struct policy_handle *handle)
1761 struct spoolss_OpenPrinterEx r;
1762 struct spoolss_UserLevel1 userlevel1;
1765 if (name && name[0]) {
1766 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
1767 dcerpc_server_name(p), name);
1769 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
1770 dcerpc_server_name(p));
1773 r.in.datatype = NULL;
1774 r.in.devmode_ctr.size = 0;
1775 r.in.devmode_ctr.devmode= NULL;
1776 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1778 r.in.userlevel.level1 = &userlevel1;
1779 r.out.handle = handle;
1781 userlevel1.size = 1234;
1782 userlevel1.client = "hello";
1783 userlevel1.user = "spottyfoot!";
1784 userlevel1.build = 1;
1785 userlevel1.major = 2;
1786 userlevel1.minor = 3;
1787 userlevel1.processor = 4;
1789 printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
1791 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
1793 if (!NT_STATUS_IS_OK(status)) {
1794 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
1798 if (!W_ERROR_IS_OK(r.out.result)) {
1799 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
1806 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1809 struct policy_handle handle;
1812 if (!call_OpenPrinterEx(p, mem_ctx, name, &handle)) {
1816 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1820 if (!test_EnumForms(p, mem_ctx, &handle, False)) {
1824 if (!test_AddForm(p, mem_ctx, &handle)) {
1828 if (!test_EnumPrinterData(p, mem_ctx, &handle)) {
1832 if (!test_EnumPrinterDataEx(p, mem_ctx, &handle)) {
1836 if (!test_PausePrinter(p, mem_ctx, &handle)) {
1840 if (!test_DoPrintTest(p, mem_ctx, &handle)) {
1844 if (!test_ResumePrinter(p, mem_ctx, &handle)) {
1848 if (!test_SetPrinterData(p, mem_ctx, &handle)) {
1852 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1856 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1863 static BOOL test_EnumPrinters_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1865 struct spoolss_EnumPrinters r;
1867 uint16_t levels[] = {1, 2, 4, 5};
1871 for (i=0;i<ARRAY_SIZE(levels);i++) {
1872 union spoolss_PrinterInfo *info;
1875 r.in.flags = PRINTER_ENUM_LOCAL;
1877 r.in.level = levels[i];
1881 printf("\nTesting EnumPrinters level %u\n", r.in.level);
1883 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1884 if (!NT_STATUS_IS_OK(status)) {
1885 printf("EnumPrinters failed - %s\n", nt_errstr(status));
1890 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1891 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1892 data_blob_clear(&blob);
1893 r.in.buffer = &blob;
1894 r.in.offered = r.out.needed;
1895 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 printf("EnumPrinters failed - %s\n",
1904 if (!W_ERROR_IS_OK(r.out.result)) {
1905 printf("EnumPrinters failed - %s\n",
1906 win_errstr(r.out.result));
1911 printf("No printers returned\n");
1917 for (j=0;j<r.out.count;j++) {
1918 if (r.in.level == 1) {
1919 /* the names appear to be comma-separated name lists? */
1920 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
1921 char *comma = strchr(name, ',');
1922 if (comma) *comma = 0;
1923 if (!test_OpenPrinter(p, mem_ctx, name)) {
1926 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
1937 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1938 struct policy_handle *handle,
1939 const char *driver_name)
1942 struct spoolss_GetPrinterDriver2 r;
1944 r.in.handle = handle;
1945 r.in.architecture = "W32X86";
1949 r.in.client_major_version = 0;
1950 r.in.client_minor_version = 0;
1952 printf("Testing GetPrinterDriver2\n");
1954 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1955 if (!NT_STATUS_IS_OK(status)) {
1956 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1960 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1961 r.in.offered = r.out.needed;
1962 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1965 if (!NT_STATUS_IS_OK(status)) {
1966 printf("GetPrinterDriver2 failed - %s\n",
1971 if (!W_ERROR_IS_OK(r.out.result)) {
1972 printf("GetPrinterDriver2 failed - %s\n",
1973 win_errstr(r.out.result));
1981 static BOOL test_EnumPrinterDrivers_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1983 struct spoolss_EnumPrinterDrivers r;
1985 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
1989 for (i=0;i<ARRAY_SIZE(levels);i++) {
1991 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1992 r.in.environment = "Windows NT x86";
1993 r.in.level = levels[i];
1997 printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
1999 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2001 if (!NT_STATUS_IS_OK(status)) {
2002 printf("EnumPrinterDrivers failed - %s\n",
2008 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2009 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2010 data_blob_clear(&blob);
2011 r.in.buffer = &blob;
2012 r.in.offered = r.out.needed;
2013 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2016 if (!NT_STATUS_IS_OK(status)) {
2017 printf("EnumPrinterDrivers failed - %s\n",
2023 if (!W_ERROR_IS_OK(r.out.result)) {
2024 printf("EnumPrinterDrivers failed - %s\n",
2025 win_errstr(r.out.result));
2031 printf("No printer drivers returned\n");
2039 BOOL torture_rpc_spoolss(void)
2042 struct dcerpc_pipe *p;
2043 TALLOC_CTX *mem_ctx;
2045 struct test_spoolss_context *ctx;
2047 mem_ctx = talloc_init("torture_rpc_spoolss");
2049 status = torture_rpc_connection(mem_ctx,
2051 DCERPC_SPOOLSS_NAME,
2052 DCERPC_SPOOLSS_UUID,
2053 DCERPC_SPOOLSS_VERSION);
2054 if (!NT_STATUS_IS_OK(status)) {
2055 talloc_free(mem_ctx);
2059 ctx = talloc_zero(mem_ctx, struct test_spoolss_context);
2062 ret &= test_OpenPrinter_server(ctx);
2064 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "W3SvcInstalled");
2065 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "BeepEnabled");
2066 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "EventLog");
2067 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopup");
2068 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopupToComputer");
2069 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MajorVersion");
2070 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MinorVersion");
2071 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");
2072 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "Architecture");
2073 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DsPresent");
2075 ret &= test_EnumForms(ctx->p, ctx, &ctx->server_handle, True);
2077 ret &= test_EnumPorts(ctx);
2079 ret &= test_GetPrinterDriverDirectory(ctx);
2081 ret &= test_EnumPrinterDrivers(ctx);
2083 ret &= test_EnumMonitors(ctx);
2085 ret &= test_EnumPrintProcessors(ctx);
2087 ret &= test_EnumPrinters(ctx);
2089 ret &= test_OpenPrinter_badnames(p, mem_ctx);
2091 ret &= test_AddPort(p, mem_ctx);
2093 ret &= test_EnumPorts_old(p, mem_ctx);
2095 ret &= test_EnumPrinters_old(p, mem_ctx);
2097 ret &= test_EnumPrinterDrivers_old(p, mem_ctx);
2099 talloc_free(mem_ctx);