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 3 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, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.h"
24 #include "torture/rpc/rpc.h"
25 #include "librpc/gen_ndr/ndr_spoolss_c.h"
27 struct test_spoolss_context {
28 struct dcerpc_pipe *p;
30 /* print server handle */
31 struct policy_handle server_handle;
34 uint32_t port_count[3];
35 union spoolss_PortInfo *ports[3];
37 /* for EnumPrinterDrivers */
38 uint32_t driver_count[7];
39 union spoolss_DriverInfo *drivers[7];
41 /* for EnumMonitors */
42 uint32_t monitor_count[3];
43 union spoolss_MonitorInfo *monitors[3];
45 /* for EnumPrintProcessors */
46 uint32_t print_processor_count[2];
47 union spoolss_PrintProcessorInfo *print_processors[2];
49 /* for EnumPrinters */
50 uint32_t printer_count[6];
51 union spoolss_PrinterInfo *printers[6];
54 #define COMPARE_STRING(c,r,e) do {\
56 if (c.e && !r.e) _ok = False;\
57 if (!c.e && r.e) _ok = False;\
58 if (c.e && r.e && strcmp_safe(c.e, r.e) != 0) _ok = False;\
60 printf("%s: " #c "." #e " [%s] doesn't match " #r "." #e " [%s]\n",\
61 __location__, c.e, r.e);\
66 /* not every compiler supports __typeof__() */
68 #define _CHECK_FIELD_SIZE(c,r,e,type) do {\
69 if (sizeof(__typeof__(c.e)) != sizeof(type)) { \
70 printf(__location__ ":" #c "." #e "field is not " #type "\n"); \
71 smb_panic(__location__ ":" #c "." #e "field is not " #type ); \
74 if (sizeof(__typeof__(r.e)) != sizeof(type)) { \
75 printf(__location__ ":" #r "." #e "field is not " #type "\n"); \
76 smb_panic(__location__ ":" #r "." #e "field is not " #type ); \
81 #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0)
85 #define COMPARE_UINT16(c,r,e) do {\
86 _CHECK_FIELD_SIZE(c,r,e,uint16_t); \
88 printf("%s: " #c "." #e " 0x%04X (%u) doesn't match " #r "." #e " 0x%04X (%u)\n",\
89 __location__, c.e, c.e, r.e, r.e);\
95 #define COMPARE_UINT32(c,r,e) do {\
96 _CHECK_FIELD_SIZE(c,r,e,uint32_t); \
98 printf("%s: " #c "." #e " 0x%08X (%u) doesn't match " #r "." #e " 0x%08X (%u)\n",\
99 __location__, c.e, c.e, r.e, r.e);\
105 #define COMPARE_UINT64(c,r,e) do {\
106 _CHECK_FIELD_SIZE(c,r,e,uint64_t); \
108 printf("%s: " #c "." #e " 0x%016llX (%llu) doesn't match " #r "." #e " 0x%016llX (%llu)\n",\
109 __location__, c.e, c.e, r.e, r.e);\
117 #define COMPARE_SEC_DESC(c,r,e)
118 #define COMPARE_SPOOLSS_TIME(c,r,e)
120 #define COMPARE_STRING_ARRAY(c,r,e)
122 static BOOL test_OpenPrinter_server(struct test_spoolss_context *ctx)
125 struct spoolss_OpenPrinter op;
128 op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p));
129 op.in.datatype = NULL;
130 op.in.devmode_ctr.devmode= NULL;
131 op.in.access_mask = 0;
132 op.out.handle = &ctx->server_handle;
134 printf("\nTesting OpenPrinter(%s)\n", op.in.printername);
136 status = dcerpc_spoolss_OpenPrinter(ctx->p, ctx, &op);
137 if (!NT_STATUS_IS_OK(status)) {
138 printf("dcerpc_spoolss_OpenPrinter failed - %s\n", nt_errstr(status));
141 if (!W_ERROR_IS_OK(op.out.result)) {
142 printf("OpenPrinter(%s) failed - %s\n",
143 op.in.printername, win_errstr(op.out.result));
150 static BOOL test_EnumPorts(struct test_spoolss_context *ctx)
153 struct spoolss_EnumPorts r;
154 uint16_t levels[] = { 1, 2 };
158 for (i=0;i<ARRAY_SIZE(levels);i++) {
159 int level = levels[i];
162 r.in.servername = "";
167 printf("Testing EnumPorts level %u\n", r.in.level);
169 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
170 if (!NT_STATUS_IS_OK(status)) {
171 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
175 if (W_ERROR_IS_OK(r.out.result)) {
176 /* TODO: do some more checks here */
179 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
180 printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
181 win_errstr(r.out.result));
186 blob = data_blob_talloc(ctx, NULL, r.out.needed);
187 data_blob_clear(&blob);
189 r.in.offered = r.out.needed;
191 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
192 if (!NT_STATUS_IS_OK(status)) {
193 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
198 if (!W_ERROR_IS_OK(r.out.result)) {
199 printf("EnumPorts failed - %s\n",
200 win_errstr(r.out.result));
205 ctx->port_count[level] = r.out.count;
206 ctx->ports[level] = r.out.info;
209 for (i=1;i<ARRAY_SIZE(levels);i++) {
210 int level = levels[i];
211 int old_level = levels[i-1];
212 if (ctx->port_count[level] != ctx->port_count[old_level]) {
213 printf("EnumPorts level[%d] returns [%u] ports, but level[%d] returns [%u]\n",
214 level, ctx->port_count[level], old_level, ctx->port_count[old_level]);
218 /* if the array sizes are not the same we would maybe segfault in the following code */
219 if (!ret) return ret;
221 for (i=0;i<ARRAY_SIZE(levels);i++) {
222 int level = levels[i];
223 for (j=0;j<ctx->port_count[level];j++) {
224 union spoolss_PortInfo *cur = &ctx->ports[level][j];
225 union spoolss_PortInfo *ref = &ctx->ports[2][j];
228 COMPARE_STRING(cur->info1, ref->info2, port_name);
231 /* level 2 is our reference, and it makes no sense to compare it to itself */
240 static BOOL test_GetPrinterDriverDirectory(struct test_spoolss_context *ctx)
243 struct spoolss_GetPrinterDriverDirectory r;
258 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
261 .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(ctx->p))
267 for (i=0;i<ARRAY_SIZE(levels);i++) {
268 int level = levels[i].level;
271 r.in.server = levels[i].server;
272 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
277 printf("Testing GetPrinterDriverDirectory level %u\n", r.in.level);
279 status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
280 if (!NT_STATUS_IS_OK(status)) {
281 printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
285 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
286 printf("GetPrinterDriverDirectory unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
287 win_errstr(r.out.result));
292 blob = data_blob_talloc(ctx, NULL, r.out.needed);
293 data_blob_clear(&blob);
295 r.in.offered = r.out.needed;
297 status = dcerpc_spoolss_GetPrinterDriverDirectory(ctx->p, ctx, &r);
298 if (!NT_STATUS_IS_OK(status)) {
299 printf("dcerpc_spoolss_GetPrinterDriverDirectory failed - %s\n", nt_errstr(status));
304 if (!W_ERROR_IS_OK(r.out.result)) {
305 printf("GetPrinterDriverDirectory failed - %s\n",
306 win_errstr(r.out.result));
315 static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
318 struct spoolss_EnumPrinterDrivers r;
319 uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
323 for (i=0;i<ARRAY_SIZE(levels);i++) {
324 int level = levels[i];
328 r.in.environment = SPOOLSS_ARCHITECTURE_NT_X86;
333 printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
335 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
336 if (!NT_STATUS_IS_OK(status)) {
337 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
341 if (W_ERROR_IS_OK(r.out.result)) {
342 /* TODO: do some more checks here */
345 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
346 printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
347 win_errstr(r.out.result));
352 blob = data_blob_talloc(ctx, NULL, r.out.needed);
353 data_blob_clear(&blob);
355 r.in.offered = r.out.needed;
357 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
358 if (!NT_STATUS_IS_OK(status)) {
359 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
364 if (!W_ERROR_IS_OK(r.out.result)) {
365 printf("EnumPrinterDrivers failed - %s\n",
366 win_errstr(r.out.result));
371 ctx->driver_count[level] = r.out.count;
372 ctx->drivers[level] = r.out.info;
375 for (i=1;i<ARRAY_SIZE(levels);i++) {
376 int level = levels[i];
377 int old_level = levels[i-1];
378 if (ctx->driver_count[level] != ctx->driver_count[old_level]) {
379 printf("EnumPrinterDrivers level[%d] returns [%u] drivers, but level[%d] returns [%u]\n",
380 level, ctx->driver_count[level], old_level, ctx->driver_count[old_level]);
384 /* if the array sizes are not the same we would maybe segfault in the following code */
385 if (!ret) return ret;
387 for (i=0;i<ARRAY_SIZE(levels);i++) {
388 int level = levels[i];
389 for (j=0;j<ctx->driver_count[level];j++) {
390 union spoolss_DriverInfo *cur = &ctx->drivers[level][j];
391 union spoolss_DriverInfo *ref = &ctx->drivers[6][j];
394 COMPARE_STRING(cur->info1, ref->info6, driver_name);
397 COMPARE_UINT32(cur->info2, ref->info6, version);
398 COMPARE_STRING(cur->info2, ref->info6, driver_name);
399 COMPARE_STRING(cur->info2, ref->info6, architecture);
400 COMPARE_STRING(cur->info2, ref->info6, driver_path);
401 COMPARE_STRING(cur->info2, ref->info6, data_file);
402 COMPARE_STRING(cur->info2, ref->info6, config_file);
405 COMPARE_UINT32(cur->info3, ref->info6, version);
406 COMPARE_STRING(cur->info3, ref->info6, driver_name);
407 COMPARE_STRING(cur->info3, ref->info6, architecture);
408 COMPARE_STRING(cur->info3, ref->info6, driver_path);
409 COMPARE_STRING(cur->info3, ref->info6, data_file);
410 COMPARE_STRING(cur->info3, ref->info6, config_file);
411 COMPARE_STRING(cur->info3, ref->info6, help_file);
412 COMPARE_STRING_ARRAY(cur->info3, ref->info6, dependent_files);
413 COMPARE_STRING(cur->info3, ref->info6, monitor_name);
414 COMPARE_STRING(cur->info3, ref->info6, default_datatype);
417 COMPARE_UINT32(cur->info4, ref->info6, version);
418 COMPARE_STRING(cur->info4, ref->info6, driver_name);
419 COMPARE_STRING(cur->info4, ref->info6, architecture);
420 COMPARE_STRING(cur->info4, ref->info6, driver_path);
421 COMPARE_STRING(cur->info4, ref->info6, data_file);
422 COMPARE_STRING(cur->info4, ref->info6, config_file);
423 COMPARE_STRING(cur->info4, ref->info6, help_file);
424 COMPARE_STRING_ARRAY(cur->info4, ref->info6, dependent_files);
425 COMPARE_STRING(cur->info4, ref->info6, monitor_name);
426 COMPARE_STRING(cur->info4, ref->info6, default_datatype);
427 COMPARE_STRING_ARRAY(cur->info4, ref->info6, previous_names);
430 COMPARE_UINT32(cur->info5, ref->info6, version);
431 COMPARE_STRING(cur->info5, ref->info6, driver_name);
432 COMPARE_STRING(cur->info5, ref->info6, architecture);
433 COMPARE_STRING(cur->info5, ref->info6, driver_path);
434 COMPARE_STRING(cur->info5, ref->info6, data_file);
435 COMPARE_STRING(cur->info5, ref->info6, config_file);
436 /*COMPARE_UINT32(cur->info5, ref->info6, driver_attributes);*/
437 /*COMPARE_UINT32(cur->info5, ref->info6, config_version);*/
438 /*TODO: ! COMPARE_UINT32(cur->info5, ref->info6, driver_version); */
441 /* level 6 is our reference, and it makes no sense to compare it to itself */
450 static BOOL test_EnumMonitors(struct test_spoolss_context *ctx)
453 struct spoolss_EnumMonitors r;
454 uint16_t levels[] = { 1, 2 };
458 for (i=0;i<ARRAY_SIZE(levels);i++) {
459 int level = levels[i];
462 r.in.servername = "";
467 printf("Testing EnumMonitors level %u\n", r.in.level);
469 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
470 if (!NT_STATUS_IS_OK(status)) {
471 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
475 if (W_ERROR_IS_OK(r.out.result)) {
476 /* TODO: do some more checks here */
479 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
480 printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
481 win_errstr(r.out.result));
486 blob = data_blob_talloc(ctx, NULL, r.out.needed);
487 data_blob_clear(&blob);
489 r.in.offered = r.out.needed;
491 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
492 if (!NT_STATUS_IS_OK(status)) {
493 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
498 if (!W_ERROR_IS_OK(r.out.result)) {
499 printf("EnumMonitors failed - %s\n",
500 win_errstr(r.out.result));
505 ctx->monitor_count[level] = r.out.count;
506 ctx->monitors[level] = r.out.info;
509 for (i=1;i<ARRAY_SIZE(levels);i++) {
510 int level = levels[i];
511 int old_level = levels[i-1];
512 if (ctx->monitor_count[level] != ctx->monitor_count[old_level]) {
513 printf("EnumMonitors level[%d] returns [%u] monitors, but level[%d] returns [%u]\n",
514 level, ctx->monitor_count[level], old_level, ctx->monitor_count[old_level]);
518 /* if the array sizes are not the same we would maybe segfault in the following code */
519 if (!ret) return ret;
521 for (i=0;i<ARRAY_SIZE(levels);i++) {
522 int level = levels[i];
523 for (j=0;j<ctx->monitor_count[level];j++) {
524 union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
525 union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
528 COMPARE_STRING(cur->info1, ref->info2, monitor_name);
531 /* level 2 is our reference, and it makes no sense to compare it to itself */
540 static BOOL test_EnumPrintProcessors(struct test_spoolss_context *ctx)
543 struct spoolss_EnumPrintProcessors r;
544 uint16_t levels[] = { 1 };
548 for (i=0;i<ARRAY_SIZE(levels);i++) {
549 int level = levels[i];
552 r.in.servername = "";
553 r.in.environment = "Windows NT x86";
558 printf("Testing EnumPrintProcessors level %u\n", r.in.level);
560 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
561 if (!NT_STATUS_IS_OK(status)) {
562 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
566 if (W_ERROR_IS_OK(r.out.result)) {
567 /* TODO: do some more checks here */
570 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
571 printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
572 win_errstr(r.out.result));
577 blob = data_blob_talloc(ctx, NULL, r.out.needed);
578 data_blob_clear(&blob);
580 r.in.offered = r.out.needed;
582 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
583 if (!NT_STATUS_IS_OK(status)) {
584 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
589 if (!W_ERROR_IS_OK(r.out.result)) {
590 printf("EnumPrintProcessors failed - %s\n",
591 win_errstr(r.out.result));
596 ctx->print_processor_count[level] = r.out.count;
597 ctx->print_processors[level] = r.out.info;
600 for (i=1;i<ARRAY_SIZE(levels);i++) {
601 int level = levels[i];
602 int old_level = levels[i-1];
603 if (ctx->print_processor_count[level] != ctx->print_processor_count[old_level]) {
604 printf("EnumPrintProcessors level[%d] returns [%u] print_processors, but level[%d] returns [%u]\n",
605 level, ctx->print_processor_count[level], old_level, ctx->print_processor_count[old_level]);
609 /* if the array sizes are not the same we would maybe segfault in the following code */
610 if (!ret) return ret;
612 for (i=0;i<ARRAY_SIZE(levels);i++) {
613 int level = levels[i];
614 for (j=0;j<ctx->print_processor_count[level];j++) {
616 union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][j];
617 union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][j];
621 /* level 1 is our reference, and it makes no sense to compare it to itself */
630 static BOOL test_EnumPrinters(struct test_spoolss_context *ctx)
632 struct spoolss_EnumPrinters r;
634 uint16_t levels[] = { 0, 1, 2, 4, 5 };
638 for (i=0;i<ARRAY_SIZE(levels);i++) {
639 int level = levels[i];
642 r.in.flags = PRINTER_ENUM_LOCAL;
648 printf("\nTesting EnumPrinters level %u\n", r.in.level);
650 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
651 if (!NT_STATUS_IS_OK(status)) {
652 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
656 if (W_ERROR_IS_OK(r.out.result)) {
657 /* TODO: do some more checks here */
660 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
661 printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
662 win_errstr(r.out.result));
667 blob = data_blob_talloc(ctx, NULL, r.out.needed);
668 data_blob_clear(&blob);
670 r.in.offered = r.out.needed;
672 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
673 if (!NT_STATUS_IS_OK(status)) {
674 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
679 if (!W_ERROR_IS_OK(r.out.result)) {
680 printf("EnumPrinters failed - %s\n",
681 win_errstr(r.out.result));
685 ctx->printer_count[level] = r.out.count;
686 ctx->printers[level] = r.out.info;
689 for (i=1;i<ARRAY_SIZE(levels);i++) {
690 int level = levels[i];
691 int old_level = levels[i-1];
692 if (ctx->printer_count[level] != ctx->printer_count[old_level]) {
693 printf("EnumPrinters level[%d] returns [%u] printers, but level[%d] returns [%u]\n",
694 level, ctx->printer_count[level], old_level, ctx->printer_count[old_level]);
698 /* if the array sizes are not the same we would maybe segfault in the following code */
699 if (!ret) return ret;
701 for (i=0;i<ARRAY_SIZE(levels);i++) {
702 int level = levels[i];
703 for (j=0;j<ctx->printer_count[level];j++) {
704 union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
705 union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
708 COMPARE_STRING(cur->info0, ref->info2, printername);
709 COMPARE_STRING(cur->info0, ref->info2, servername);
710 COMPARE_UINT32(cur->info0, ref->info2, cjobs);
711 /*COMPARE_UINT32(cur->info0, ref->info2, total_jobs);
712 COMPARE_UINT32(cur->info0, ref->info2, total_bytes);
713 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
714 COMPARE_UINT32(cur->info0, ref->info2, global_counter);
715 COMPARE_UINT32(cur->info0, ref->info2, total_pages);
716 COMPARE_UINT32(cur->info0, ref->info2, version);
717 COMPARE_UINT32(cur->info0, ref->info2, unknown10);
718 COMPARE_UINT32(cur->info0, ref->info2, unknown11);
719 COMPARE_UINT32(cur->info0, ref->info2, unknown12);
720 COMPARE_UINT32(cur->info0, ref->info2, session_counter);
721 COMPARE_UINT32(cur->info0, ref->info2, unknown14);
722 COMPARE_UINT32(cur->info0, ref->info2, printer_errors);
723 COMPARE_UINT32(cur->info0, ref->info2, unknown16);
724 COMPARE_UINT32(cur->info0, ref->info2, unknown17);
725 COMPARE_UINT32(cur->info0, ref->info2, unknown18);
726 COMPARE_UINT32(cur->info0, ref->info2, unknown19);
727 COMPARE_UINT32(cur->info0, ref->info2, change_id);
728 COMPARE_UINT32(cur->info0, ref->info2, unknown21);*/
729 COMPARE_UINT32(cur->info0, ref->info2, status);
730 /*COMPARE_UINT32(cur->info0, ref->info2, unknown23);
731 COMPARE_UINT32(cur->info0, ref->info2, c_setprinter);
732 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
733 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
734 COMPARE_UINT32(cur->info0, ref->info2, unknown27);
735 COMPARE_UINT32(cur->info0, ref->info2, unknown28);
736 COMPARE_UINT32(cur->info0, ref->info2, unknown29);*/
739 /*COMPARE_UINT32(cur->info1, ref->info2, flags);*/
740 /*COMPARE_STRING(cur->info1, ref->info2, name);*/
741 /*COMPARE_STRING(cur->info1, ref->info2, description);*/
742 COMPARE_STRING(cur->info1, ref->info2, comment);
745 /* level 2 is our reference, and it makes no sense to compare it to itself */
748 COMPARE_STRING(cur->info4, ref->info2, printername);
749 COMPARE_STRING(cur->info4, ref->info2, servername);
750 COMPARE_UINT32(cur->info4, ref->info2, attributes);
753 COMPARE_STRING(cur->info5, ref->info2, printername);
754 COMPARE_STRING(cur->info5, ref->info2, portname);
755 COMPARE_UINT32(cur->info5, ref->info2, attributes);
756 /*COMPARE_UINT32(cur->info5, ref->info2, device_not_selected_timeout);
757 COMPARE_UINT32(cur->info5, ref->info2, transmission_retry_timeout);*/
764 * - verify that the port of a printer was in the list returned by EnumPorts
770 static BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
771 struct policy_handle *handle)
774 struct spoolss_GetPrinter r;
775 uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
779 for (i=0;i<ARRAY_SIZE(levels);i++) {
780 r.in.handle = handle;
781 r.in.level = levels[i];
785 printf("Testing GetPrinter level %u\n", r.in.level);
787 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
788 if (!NT_STATUS_IS_OK(status)) {
789 printf("GetPrinter failed - %s\n", nt_errstr(status));
794 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
795 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
796 data_blob_clear(&blob);
798 r.in.offered = r.out.needed;
799 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
802 if (!NT_STATUS_IS_OK(status)) {
803 printf("GetPrinter failed - %s\n", nt_errstr(status));
808 if (!W_ERROR_IS_OK(r.out.result)) {
809 printf("GetPrinter failed - %s\n",
810 win_errstr(r.out.result));
820 static BOOL test_ClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
821 struct policy_handle *handle)
824 struct spoolss_ClosePrinter r;
826 r.in.handle = handle;
827 r.out.handle = handle;
829 printf("Testing ClosePrinter\n");
831 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
832 if (!NT_STATUS_IS_OK(status)) {
833 printf("ClosePrinter failed - %s\n", nt_errstr(status));
840 static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
841 struct policy_handle *handle,
842 const char *form_name)
845 struct spoolss_GetForm r;
847 r.in.handle = handle;
848 r.in.form_name = form_name;
853 printf("Testing GetForm\n");
855 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
856 if (!NT_STATUS_IS_OK(status)) {
857 printf("GetForm failed - %s\n", nt_errstr(status));
861 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
862 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
863 data_blob_clear(&blob);
865 r.in.offered = r.out.needed;
866 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
867 if (!NT_STATUS_IS_OK(status)) {
868 printf("GetForm failed - %s\n",
873 if (!W_ERROR_IS_OK(r.out.result)) {
874 printf("GetForm failed - %s\n",
875 win_errstr(r.out.result));
880 printf("No form info returned\n");
886 if (!W_ERROR_IS_OK(r.out.result)) {
887 printf("GetForm failed - %s\n",
888 win_errstr(r.out.result));
895 static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
896 struct policy_handle *handle, BOOL print_server)
899 struct spoolss_EnumForms r;
902 r.in.handle = handle;
907 printf("Testing EnumForms\n");
909 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
910 if (!NT_STATUS_IS_OK(status)) {
911 printf("EnumForms failed - %s\n", nt_errstr(status));
915 if (print_server && W_ERROR_EQUAL(r.out.result,WERR_BADFID)) {
916 printf("EnumForms on the PrintServer isn't supported by test server (NT4)\n");
920 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
921 union spoolss_FormInfo *info;
923 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
924 data_blob_clear(&blob);
926 r.in.offered = r.out.needed;
928 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
931 printf("No forms returned\n");
937 for (j = 0; j < r.out.count; j++) {
938 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, info[j].info1.form_name);
942 if (!NT_STATUS_IS_OK(status)) {
943 printf("EnumForms failed - %s\n", nt_errstr(status));
947 if (!W_ERROR_IS_OK(r.out.result)) {
948 printf("EnumForms failed - %s\n", win_errstr(r.out.result));
955 static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
956 struct policy_handle *handle,
957 const char *form_name)
960 struct spoolss_DeleteForm r;
962 r.in.handle = handle;
963 r.in.form_name = form_name;
965 status = dcerpc_spoolss_DeleteForm(p, mem_ctx, &r);
967 if (!NT_STATUS_IS_OK(status)) {
968 printf("DeleteForm failed - %s\n", nt_errstr(status));
972 if (!W_ERROR_IS_OK(r.out.result)) {
973 printf("DeleteForm failed - %s\n", win_errstr(r.out.result));
980 static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
981 struct policy_handle *handle, BOOL print_server)
983 struct spoolss_AddForm r;
984 struct spoolss_AddFormInfo1 addform;
985 const char *form_name = "testform3";
989 r.in.handle = handle;
991 r.in.info.info1 = &addform;
992 addform.flags = SPOOLSS_FORM_USER;
993 addform.form_name = form_name;
994 addform.size.width = 50;
995 addform.size.height = 25;
996 addform.area.left = 5;
997 addform.area.top = 10;
998 addform.area.right = 45;
999 addform.area.bottom = 15;
1001 status = dcerpc_spoolss_AddForm(p, mem_ctx, &r);
1003 if (!NT_STATUS_IS_OK(status)) {
1004 printf("AddForm failed - %s\n", nt_errstr(status));
1008 if (!W_ERROR_IS_OK(r.out.result)) {
1009 printf("AddForm failed - %s\n", win_errstr(r.out.result));
1013 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
1016 struct spoolss_SetForm sf;
1017 struct spoolss_AddFormInfo1 setform;
1019 sf.in.handle = handle;
1020 sf.in.form_name = form_name;
1022 sf.in.info.info1= &setform;
1023 setform.flags = addform.flags;
1024 setform.form_name = addform.form_name;
1025 setform.size = addform.size;
1026 setform.area = addform.area;
1028 setform.size.width = 1234;
1030 status = dcerpc_spoolss_SetForm(p, mem_ctx, &sf);
1032 if (!NT_STATUS_IS_OK(status)) {
1033 printf("SetForm failed - %s\n", nt_errstr(status));
1038 if (!W_ERROR_IS_OK(r.out.result)) {
1039 printf("SetForm failed - %s\n",
1040 win_errstr(r.out.result));
1046 if (!print_server) ret &= test_GetForm(p, mem_ctx, handle, form_name);
1049 if (!test_DeleteForm(p, mem_ctx, handle, form_name)) {
1050 printf("DeleteForm failed\n");
1057 static BOOL test_EnumPorts_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1060 struct spoolss_EnumPorts r;
1062 r.in.servername = talloc_asprintf(mem_ctx, "\\\\%s",
1063 dcerpc_server_name(p));
1068 printf("Testing EnumPorts\n");
1070 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 printf("EnumPorts failed - %s\n", nt_errstr(status));
1077 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1078 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1079 data_blob_clear(&blob);
1080 r.in.buffer = &blob;
1081 r.in.offered = r.out.needed;
1083 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
1084 if (!NT_STATUS_IS_OK(status)) {
1085 printf("EnumPorts failed - %s\n", nt_errstr(status));
1090 printf("No ports returned\n");
1098 static BOOL test_AddPort(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1101 struct spoolss_AddPort r;
1103 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
1104 dcerpc_server_name(p));
1106 r.in.monitor_name = "foo";
1108 printf ("Testing AddPort\n");
1110 status = dcerpc_spoolss_AddPort(p, mem_ctx, &r);
1112 if (!NT_STATUS_IS_OK(status)) {
1113 printf("AddPort failed - %s\n", nt_errstr(status));
1117 /* win2k3 returns WERR_NOT_SUPPORTED */
1121 if (!W_ERROR_IS_OK(r.out.result)) {
1122 printf("AddPort failed - %s\n", win_errstr(r.out.result));
1131 static BOOL test_GetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1132 struct policy_handle *handle, uint32_t job_id)
1135 struct spoolss_GetJob r;
1137 r.in.handle = handle;
1138 r.in.job_id = job_id;
1143 printf("Testing GetJob\n");
1145 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1146 if (!NT_STATUS_IS_OK(status)) {
1147 printf("GetJob failed - %s\n", nt_errstr(status));
1151 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1152 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1153 data_blob_clear(&blob);
1154 r.in.buffer = &blob;
1155 r.in.offered = r.out.needed;
1157 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1160 printf("No job info returned\n");
1168 static BOOL test_SetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1169 struct policy_handle *handle, uint32_t job_id, enum spoolss_JobControl command)
1172 struct spoolss_SetJob r;
1174 r.in.handle = handle;
1175 r.in.job_id = job_id;
1177 r.in.command = command;
1179 printf("Testing SetJob\n");
1181 status = dcerpc_spoolss_SetJob(p, mem_ctx, &r);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 printf("SetJob failed - %s\n", nt_errstr(status));
1186 if (!W_ERROR_IS_OK(r.out.result)) {
1187 printf("SetJob failed - %s\n", win_errstr(r.out.result));
1194 static BOOL test_EnumJobs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1195 struct policy_handle *handle)
1198 struct spoolss_EnumJobs r;
1200 r.in.handle = handle;
1202 r.in.numjobs = 0xffffffff;
1207 printf("Testing EnumJobs\n");
1209 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 printf("EnumJobs failed - %s\n", nt_errstr(status));
1216 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1217 union spoolss_JobInfo *info;
1219 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1220 data_blob_clear(&blob);
1221 r.in.buffer = &blob;
1222 r.in.offered = r.out.needed;
1224 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1227 printf("No jobs returned\n");
1233 for (j = 0; j < r.out.count; j++) {
1234 test_GetJob(p, mem_ctx, handle, info[j].info1.job_id);
1235 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
1236 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
1239 } else if (!W_ERROR_IS_OK(r.out.result)) {
1240 printf("EnumJobs failed - %s\n", win_errstr(r.out.result));
1247 static BOOL test_DoPrintTest(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1248 struct policy_handle *handle)
1252 struct spoolss_StartDocPrinter s;
1253 struct spoolss_DocumentInfo1 info1;
1254 struct spoolss_StartPagePrinter sp;
1255 struct spoolss_WritePrinter w;
1256 struct spoolss_EndPagePrinter ep;
1257 struct spoolss_EndDocPrinter e;
1261 printf("Testing StartDocPrinter\n");
1263 s.in.handle = handle;
1265 s.in.info.info1 = &info1;
1266 info1.document_name = "TorturePrintJob";
1267 info1.output_file = NULL;
1268 info1.datatype = "RAW";
1270 status = dcerpc_spoolss_StartDocPrinter(p, mem_ctx, &s);
1271 if (!NT_STATUS_IS_OK(status)) {
1272 printf("dcerpc_spoolss_StartDocPrinter failed - %s\n", nt_errstr(status));
1275 if (!W_ERROR_IS_OK(s.out.result)) {
1276 printf("StartDocPrinter failed - %s\n", win_errstr(s.out.result));
1280 job_id = s.out.job_id;
1282 for (i=1; i < 4; i++) {
1283 printf("Testing StartPagePrinter: Page[%d]\n", i);
1285 sp.in.handle = handle;
1287 status = dcerpc_spoolss_StartPagePrinter(p, mem_ctx, &sp);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 printf("dcerpc_spoolss_StartPagePrinter failed - %s\n", nt_errstr(status));
1292 if (!W_ERROR_IS_OK(sp.out.result)) {
1293 printf("StartPagePrinter failed - %s\n", win_errstr(sp.out.result));
1297 printf("Testing WritePrinter: Page[%d]\n", i);
1299 w.in.handle = handle;
1300 w.in.data = data_blob_string_const(talloc_asprintf(mem_ctx,"TortureTestPage: %d\nData\n",i));
1302 status = dcerpc_spoolss_WritePrinter(p, mem_ctx, &w);
1303 if (!NT_STATUS_IS_OK(status)) {
1304 printf("dcerpc_spoolss_WritePrinter failed - %s\n", nt_errstr(status));
1307 if (!W_ERROR_IS_OK(w.out.result)) {
1308 printf("WritePrinter failed - %s\n", win_errstr(w.out.result));
1312 printf("Testing EndPagePrinter: Page[%d]\n", i);
1314 ep.in.handle = handle;
1316 status = dcerpc_spoolss_EndPagePrinter(p, mem_ctx, &ep);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 printf("dcerpc_spoolss_EndPagePrinter failed - %s\n", nt_errstr(status));
1321 if (!W_ERROR_IS_OK(ep.out.result)) {
1322 printf("EndPagePrinter failed - %s\n", win_errstr(ep.out.result));
1327 printf("Testing EndDocPrinter\n");
1329 e.in.handle = handle;
1331 status = dcerpc_spoolss_EndDocPrinter(p, mem_ctx, &e);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 printf("dcerpc_spoolss_EndDocPrinter failed - %s\n", nt_errstr(status));
1336 if (!W_ERROR_IS_OK(e.out.result)) {
1337 printf("EndDocPrinter failed - %s\n", win_errstr(e.out.result));
1341 ret &= test_EnumJobs(p, mem_ctx, handle);
1343 ret &= test_SetJob(p, mem_ctx, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
1348 static BOOL test_PausePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1349 struct policy_handle *handle)
1352 struct spoolss_SetPrinter r;
1354 r.in.handle = handle;
1356 r.in.info.info1 = NULL;
1357 r.in.devmode_ctr.devmode= NULL;
1358 r.in.secdesc_ctr.sd = NULL;
1359 r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
1361 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1363 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1365 if (!NT_STATUS_IS_OK(status)) {
1366 printf("SetPrinter failed - %s\n", nt_errstr(status));
1370 if (!W_ERROR_IS_OK(r.out.result)) {
1371 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1378 static BOOL test_ResumePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1379 struct policy_handle *handle)
1382 struct spoolss_SetPrinter r;
1384 r.in.handle = handle;
1386 r.in.info.info1 = NULL;
1387 r.in.devmode_ctr.devmode= NULL;
1388 r.in.secdesc_ctr.sd = NULL;
1389 r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
1391 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1393 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1395 if (!NT_STATUS_IS_OK(status)) {
1396 printf("SetPrinter failed - %s\n", nt_errstr(status));
1400 if (!W_ERROR_IS_OK(r.out.result)) {
1401 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1408 static BOOL test_GetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1409 struct policy_handle *handle,
1410 const char *value_name)
1413 struct spoolss_GetPrinterData r;
1415 r.in.handle = handle;
1416 r.in.value_name = value_name;
1419 printf("Testing GetPrinterData\n");
1421 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1422 if (!NT_STATUS_IS_OK(status)) {
1423 printf("GetPrinterData failed - %s\n", nt_errstr(status));
1427 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1428 r.in.offered = r.out.needed;
1430 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 printf("GetPrinterData failed - %s\n",
1437 if (!W_ERROR_IS_OK(r.out.result)) {
1438 printf("GetPrinterData failed - %s\n",
1439 win_errstr(r.out.result));
1447 static BOOL test_GetPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1448 struct policy_handle *handle,
1449 const char *key_name,
1450 const char *value_name)
1453 struct spoolss_GetPrinterDataEx r;
1455 r.in.handle = handle;
1456 r.in.key_name = key_name;
1457 r.in.value_name = value_name;
1460 printf("Testing GetPrinterDataEx\n");
1462 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1463 if (!NT_STATUS_IS_OK(status)) {
1464 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1465 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1466 printf("GetPrinterDataEx not supported by server\n");
1469 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status));
1473 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1474 r.in.offered = r.out.needed;
1476 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 printf("GetPrinterDataEx failed - %s\n",
1483 if (!W_ERROR_IS_OK(r.out.result)) {
1484 printf("GetPrinterDataEx failed - %s\n",
1485 win_errstr(r.out.result));
1493 static BOOL test_EnumPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1494 struct policy_handle *handle)
1497 struct spoolss_EnumPrinterData r;
1499 r.in.handle = handle;
1500 r.in.enum_index = 0;
1505 r.in.value_offered = 0;
1507 r.in.data_size = &data_size;
1508 r.out.data_size = &data_size;
1510 printf("Testing EnumPrinterData\n");
1512 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1519 r.in.value_offered = r.out.value_needed;
1521 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1528 test_GetPrinterData(p, mem_ctx, handle, r.out.value_name);
1530 test_GetPrinterDataEx(
1531 p, mem_ctx, handle, "PrinterDriverData",
1536 } while (W_ERROR_IS_OK(r.out.result));
1541 static BOOL test_EnumPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1542 struct policy_handle *handle)
1545 struct spoolss_EnumPrinterDataEx r;
1547 r.in.handle = handle;
1548 r.in.key_name = "PrinterDriverData";
1551 printf("Testing EnumPrinterDataEx\n");
1553 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1554 if (!NT_STATUS_IS_OK(status)) {
1555 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1559 r.in.offered = r.out.needed;
1561 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1572 static BOOL test_DeletePrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1573 struct policy_handle *handle,
1574 const char *value_name)
1577 struct spoolss_DeletePrinterData r;
1579 r.in.handle = handle;
1580 r.in.value_name = value_name;
1582 printf("Testing DeletePrinterData\n");
1584 status = dcerpc_spoolss_DeletePrinterData(p, mem_ctx, &r);
1586 if (!NT_STATUS_IS_OK(status)) {
1587 printf("DeletePrinterData failed - %s\n", nt_errstr(status));
1594 static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1595 struct policy_handle *handle)
1598 struct spoolss_SetPrinterData r;
1599 const char *value_name = "spottyfoot";
1601 r.in.handle = handle;
1602 r.in.value_name = value_name;
1603 r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
1604 r.in.data.string = "dog";
1606 printf("Testing SetPrinterData\n");
1608 status = dcerpc_spoolss_SetPrinterData(p, mem_ctx, &r);
1610 if (!NT_STATUS_IS_OK(status)) {
1611 printf("SetPrinterData failed - %s\n", nt_errstr(status));
1615 if (!test_GetPrinterData(p, mem_ctx, handle, value_name)) {
1619 if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) {
1626 static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1627 struct policy_handle *handle)
1630 struct dcerpc_binding *b;
1631 struct dcerpc_pipe *p2;
1634 /* only makes sense on SMB */
1635 if (p->conn->transport.transport != NCACN_NP) {
1639 printf("testing close on secondary pipe\n");
1641 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1642 if (!NT_STATUS_IS_OK(status)) {
1643 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1647 status = dcerpc_secondary_connection(p, &p2, b);
1648 if (!NT_STATUS_IS_OK(status)) {
1649 printf("Failed to create secondary connection\n");
1653 status = dcerpc_bind_auth_none(p2, &ndr_table_spoolss);
1654 if (!NT_STATUS_IS_OK(status)) {
1655 printf("Failed to create bind on secondary connection\n");
1661 if (test_ClosePrinter(p2, mem_ctx, handle)) {
1662 printf("ERROR: Allowed close on secondary connection!\n");
1666 if (p2->last_fault_code != DCERPC_FAULT_CONTEXT_MISMATCH) {
1667 printf("Unexpected fault code 0x%x - expected 0x%x\n",
1668 p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH);
1677 static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
1680 struct spoolss_OpenPrinter op;
1681 struct spoolss_OpenPrinterEx opEx;
1682 struct policy_handle handle;
1685 op.in.printername = name;
1686 op.in.datatype = NULL;
1687 op.in.devmode_ctr.devmode= NULL;
1688 op.in.access_mask = 0;
1689 op.out.handle = &handle;
1691 printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1693 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
1694 if (!NT_STATUS_IS_OK(status)) {
1695 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1698 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1699 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1700 name, win_errstr(op.out.result));
1703 if (W_ERROR_IS_OK(op.out.result)) {
1704 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1707 opEx.in.printername = name;
1708 opEx.in.datatype = NULL;
1709 opEx.in.devmode_ctr.devmode = NULL;
1710 opEx.in.access_mask = 0;
1712 opEx.in.userlevel.level1 = NULL;
1713 opEx.out.handle = &handle;
1715 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1717 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
1718 if (!NT_STATUS_IS_OK(status)) {
1719 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1722 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
1723 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1724 name, win_errstr(opEx.out.result));
1727 if (W_ERROR_IS_OK(opEx.out.result)) {
1728 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1734 static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1739 ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
1740 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
1741 ret &= test_OpenPrinter_badname(p, mem_ctx, "");
1742 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
1743 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
1745 name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
1746 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1749 name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
1750 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1756 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1760 struct spoolss_OpenPrinter r;
1761 struct policy_handle handle;
1764 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1765 r.in.datatype = NULL;
1766 r.in.devmode_ctr.devmode= NULL;
1767 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1768 r.out.handle = &handle;
1770 printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
1772 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
1774 if (!NT_STATUS_IS_OK(status)) {
1775 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1779 if (!W_ERROR_IS_OK(r.out.result)) {
1780 printf("OpenPrinter failed - %s\n", win_errstr(r.out.result));
1784 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1788 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1792 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1799 static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1800 const char *name, struct policy_handle *handle)
1802 struct spoolss_OpenPrinterEx r;
1803 struct spoolss_UserLevel1 userlevel1;
1806 if (name && name[0]) {
1807 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
1808 dcerpc_server_name(p), name);
1810 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
1811 dcerpc_server_name(p));
1814 r.in.datatype = NULL;
1815 r.in.devmode_ctr.devmode= NULL;
1816 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1818 r.in.userlevel.level1 = &userlevel1;
1819 r.out.handle = handle;
1821 userlevel1.size = 1234;
1822 userlevel1.client = "hello";
1823 userlevel1.user = "spottyfoot!";
1824 userlevel1.build = 1;
1825 userlevel1.major = 2;
1826 userlevel1.minor = 3;
1827 userlevel1.processor = 4;
1829 printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
1831 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
1833 if (!NT_STATUS_IS_OK(status)) {
1834 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
1838 if (!W_ERROR_IS_OK(r.out.result)) {
1839 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
1846 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1849 struct policy_handle handle;
1852 if (!call_OpenPrinterEx(p, mem_ctx, name, &handle)) {
1856 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1860 if (!test_EnumForms(p, mem_ctx, &handle, False)) {
1864 if (!test_AddForm(p, mem_ctx, &handle, False)) {
1868 if (!test_EnumPrinterData(p, mem_ctx, &handle)) {
1872 if (!test_EnumPrinterDataEx(p, mem_ctx, &handle)) {
1876 if (!test_PausePrinter(p, mem_ctx, &handle)) {
1880 if (!test_DoPrintTest(p, mem_ctx, &handle)) {
1884 if (!test_ResumePrinter(p, mem_ctx, &handle)) {
1888 if (!test_SetPrinterData(p, mem_ctx, &handle)) {
1892 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1896 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1903 static BOOL test_EnumPrinters_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1905 struct spoolss_EnumPrinters r;
1907 uint16_t levels[] = {1, 2, 4, 5};
1911 for (i=0;i<ARRAY_SIZE(levels);i++) {
1912 union spoolss_PrinterInfo *info;
1915 r.in.flags = PRINTER_ENUM_LOCAL;
1917 r.in.level = levels[i];
1921 printf("\nTesting EnumPrinters level %u\n", r.in.level);
1923 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1924 if (!NT_STATUS_IS_OK(status)) {
1925 printf("EnumPrinters failed - %s\n", nt_errstr(status));
1930 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1931 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
1932 data_blob_clear(&blob);
1933 r.in.buffer = &blob;
1934 r.in.offered = r.out.needed;
1935 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1938 if (!NT_STATUS_IS_OK(status)) {
1939 printf("EnumPrinters failed - %s\n",
1944 if (!W_ERROR_IS_OK(r.out.result)) {
1945 printf("EnumPrinters failed - %s\n",
1946 win_errstr(r.out.result));
1951 printf("No printers returned\n");
1957 for (j=0;j<r.out.count;j++) {
1958 if (r.in.level == 1) {
1959 /* the names appear to be comma-separated name lists? */
1960 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
1961 char *comma = strchr(name, ',');
1962 if (comma) *comma = 0;
1963 if (!test_OpenPrinter(p, mem_ctx, name)) {
1966 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
1977 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1978 struct policy_handle *handle,
1979 const char *driver_name)
1982 struct spoolss_GetPrinterDriver2 r;
1984 r.in.handle = handle;
1985 r.in.architecture = "W32X86";
1989 r.in.client_major_version = 0;
1990 r.in.client_minor_version = 0;
1992 printf("Testing GetPrinterDriver2\n");
1994 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1995 if (!NT_STATUS_IS_OK(status)) {
1996 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
2000 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2001 r.in.offered = r.out.needed;
2002 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
2005 if (!NT_STATUS_IS_OK(status)) {
2006 printf("GetPrinterDriver2 failed - %s\n",
2011 if (!W_ERROR_IS_OK(r.out.result)) {
2012 printf("GetPrinterDriver2 failed - %s\n",
2013 win_errstr(r.out.result));
2021 static BOOL test_EnumPrinterDrivers_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
2023 struct spoolss_EnumPrinterDrivers r;
2025 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
2029 for (i=0;i<ARRAY_SIZE(levels);i++) {
2031 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
2032 r.in.environment = "Windows NT x86";
2033 r.in.level = levels[i];
2037 printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
2039 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2041 if (!NT_STATUS_IS_OK(status)) {
2042 printf("EnumPrinterDrivers failed - %s\n",
2048 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
2049 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, r.out.needed);
2050 data_blob_clear(&blob);
2051 r.in.buffer = &blob;
2052 r.in.offered = r.out.needed;
2053 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
2056 if (!NT_STATUS_IS_OK(status)) {
2057 printf("EnumPrinterDrivers failed - %s\n",
2063 if (!W_ERROR_IS_OK(r.out.result)) {
2064 printf("EnumPrinterDrivers failed - %s\n",
2065 win_errstr(r.out.result));
2071 printf("No printer drivers returned\n");
2079 BOOL torture_rpc_spoolss(struct torture_context *torture)
2082 struct dcerpc_pipe *p;
2083 TALLOC_CTX *mem_ctx;
2085 struct test_spoolss_context *ctx;
2087 mem_ctx = talloc_init("torture_rpc_spoolss");
2089 status = torture_rpc_connection(mem_ctx, &p, &ndr_table_spoolss);
2090 if (!NT_STATUS_IS_OK(status)) {
2091 talloc_free(mem_ctx);
2095 ctx = talloc_zero(mem_ctx, struct test_spoolss_context);
2098 ret &= test_OpenPrinter_server(ctx);
2100 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "W3SvcInstalled");
2101 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "BeepEnabled");
2102 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "EventLog");
2103 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopup");
2104 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopupToComputer");
2105 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MajorVersion");
2106 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MinorVersion");
2107 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");
2108 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "Architecture");
2109 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DsPresent");
2110 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersion");
2111 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "OSVersionEx");
2112 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DNSMachineName");
2114 ret &= test_EnumForms(ctx->p, ctx, &ctx->server_handle, True);
2116 ret &= test_AddForm(ctx->p, ctx, &ctx->server_handle, True);
2118 ret &= test_EnumPorts(ctx);
2120 ret &= test_GetPrinterDriverDirectory(ctx);
2122 ret &= test_EnumPrinterDrivers(ctx);
2124 ret &= test_EnumMonitors(ctx);
2126 ret &= test_EnumPrintProcessors(ctx);
2128 ret &= test_EnumPrinters(ctx);
2130 ret &= test_OpenPrinter_badnames(p, mem_ctx);
2132 ret &= test_AddPort(p, mem_ctx);
2134 ret &= test_EnumPorts_old(p, mem_ctx);
2136 ret &= test_EnumPrinters_old(p, mem_ctx);
2138 ret &= test_EnumPrinterDrivers_old(p, mem_ctx);
2140 talloc_free(mem_ctx);