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];
135 uint32_t buf_size = 0;
137 r.in.servername = "";
141 r.in.buf_size = &buf_size;
142 r.out.buf_size = &buf_size;
144 printf("Testing EnumPorts level %u\n", r.in.level);
146 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
147 if (!NT_STATUS_IS_OK(status)) {
148 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
152 if (W_ERROR_IS_OK(r.out.result)) {
153 /* TODO: do some more checks here */
156 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
157 printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
158 win_errstr(r.out.result));
163 blob = data_blob_talloc(ctx, NULL, buf_size);
164 data_blob_clear(&blob);
167 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
168 if (!NT_STATUS_IS_OK(status)) {
169 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
174 if (!W_ERROR_IS_OK(r.out.result)) {
175 printf("EnumPorts failed - %s\n",
176 win_errstr(r.out.result));
181 ctx->port_count[level] = r.out.count;
182 ctx->ports[level] = r.out.info;
185 for (i=1;i<ARRAY_SIZE(levels);i++) {
186 int level = levels[i];
187 int old_level = levels[i-1];
188 if (ctx->port_count[level] != ctx->port_count[old_level]) {
189 printf("EnumPorts level[%d] returns [%u] ports, but level[%d] returns [%u]\n",
190 level, ctx->port_count[level], old_level, ctx->port_count[old_level]);
194 /* if the array sizes are not the same we would maybe segfault in the following code */
195 if (!ret) return ret;
197 for (i=0;i<ARRAY_SIZE(levels);i++) {
198 int level = levels[i];
199 for (j=0;j<ctx->port_count[level];j++) {
200 union spoolss_PortInfo *cur = &ctx->ports[level][j];
201 union spoolss_PortInfo *ref = &ctx->ports[2][j];
204 COMPARE_STRING(cur->info1, ref->info2, port_name);
207 /* level 2 is our reference, and it makes no sense to compare it to itself */
216 static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
219 struct spoolss_EnumPrinterDrivers r;
220 uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
224 for (i=0;i<ARRAY_SIZE(levels);i++) {
225 int level = levels[i];
227 uint32_t buf_size = 0;
230 r.in.environment = "Windows NT x86";
234 r.in.buf_size = &buf_size;
235 r.out.buf_size = &buf_size;
237 printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
239 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
240 if (!NT_STATUS_IS_OK(status)) {
241 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
245 if (W_ERROR_IS_OK(r.out.result)) {
246 /* TODO: do some more checks here */
249 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
250 printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
251 win_errstr(r.out.result));
256 blob = data_blob_talloc(ctx, NULL, buf_size);
257 data_blob_clear(&blob);
260 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
261 if (!NT_STATUS_IS_OK(status)) {
262 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
267 if (!W_ERROR_IS_OK(r.out.result)) {
268 printf("EnumPrinterDrivers failed - %s\n",
269 win_errstr(r.out.result));
274 ctx->driver_count[level] = r.out.count;
275 ctx->drivers[level] = r.out.info;
278 for (i=1;i<ARRAY_SIZE(levels);i++) {
279 int level = levels[i];
280 int old_level = levels[i-1];
281 if (ctx->driver_count[level] != ctx->driver_count[old_level]) {
282 printf("EnumPrinterDrivers level[%d] returns [%u] drivers, but level[%d] returns [%u]\n",
283 level, ctx->driver_count[level], old_level, ctx->driver_count[old_level]);
287 /* if the array sizes are not the same we would maybe segfault in the following code */
288 if (!ret) return ret;
290 for (i=0;i<ARRAY_SIZE(levels);i++) {
291 int level = levels[i];
292 for (j=0;j<ctx->driver_count[level];j++) {
293 union spoolss_DriverInfo *cur = &ctx->drivers[level][j];
294 union spoolss_DriverInfo *ref = &ctx->drivers[6][j];
297 COMPARE_STRING(cur->info1, ref->info6, driver_name);
300 COMPARE_UINT32(cur->info2, ref->info6, version);
301 COMPARE_STRING(cur->info2, ref->info6, driver_name);
302 COMPARE_STRING(cur->info2, ref->info6, architecture);
303 COMPARE_STRING(cur->info2, ref->info6, driver_path);
304 COMPARE_STRING(cur->info2, ref->info6, data_file);
305 COMPARE_STRING(cur->info2, ref->info6, config_file);
308 COMPARE_UINT32(cur->info3, ref->info6, version);
309 COMPARE_STRING(cur->info3, ref->info6, driver_name);
310 COMPARE_STRING(cur->info3, ref->info6, architecture);
311 COMPARE_STRING(cur->info3, ref->info6, driver_path);
312 COMPARE_STRING(cur->info3, ref->info6, data_file);
313 COMPARE_STRING(cur->info3, ref->info6, config_file);
314 COMPARE_STRING(cur->info3, ref->info6, help_file);
315 COMPARE_STRING_ARRAY(cur->info3, ref->info6, dependent_files);
316 COMPARE_STRING(cur->info3, ref->info6, monitor_name);
317 COMPARE_STRING(cur->info3, ref->info6, default_datatype);
320 COMPARE_UINT32(cur->info4, ref->info6, version);
321 COMPARE_STRING(cur->info4, ref->info6, driver_name);
322 COMPARE_STRING(cur->info4, ref->info6, architecture);
323 COMPARE_STRING(cur->info4, ref->info6, driver_path);
324 COMPARE_STRING(cur->info4, ref->info6, data_file);
325 COMPARE_STRING(cur->info4, ref->info6, config_file);
326 COMPARE_STRING(cur->info4, ref->info6, help_file);
327 COMPARE_STRING_ARRAY(cur->info4, ref->info6, dependent_files);
328 COMPARE_STRING(cur->info4, ref->info6, monitor_name);
329 COMPARE_STRING(cur->info4, ref->info6, default_datatype);
330 COMPARE_STRING_ARRAY(cur->info4, ref->info6, previous_names);
333 COMPARE_UINT32(cur->info5, ref->info6, version);
334 COMPARE_STRING(cur->info5, ref->info6, driver_name);
335 COMPARE_STRING(cur->info5, ref->info6, architecture);
336 COMPARE_STRING(cur->info5, ref->info6, driver_path);
337 COMPARE_STRING(cur->info5, ref->info6, data_file);
338 COMPARE_STRING(cur->info5, ref->info6, config_file);
339 /*COMPARE_UINT32(cur->info5, ref->info6, driver_attributes);*/
340 /*COMPARE_UINT32(cur->info5, ref->info6, config_version);*/
341 /*TODO: ! COMPARE_UINT32(cur->info5, ref->info6, driver_version); */
344 /* level 6 is our reference, and it makes no sense to compare it to itself */
353 static BOOL test_EnumMonitors(struct test_spoolss_context *ctx)
356 struct spoolss_EnumMonitors r;
357 uint16_t levels[] = { 1, 2 };
361 for (i=0;i<ARRAY_SIZE(levels);i++) {
362 int level = levels[i];
364 uint32_t buf_size = 0;
366 r.in.servername = "";
370 r.in.buf_size = &buf_size;
371 r.out.buf_size = &buf_size;
373 printf("Testing EnumMonitors level %u\n", r.in.level);
375 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
376 if (!NT_STATUS_IS_OK(status)) {
377 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
381 if (W_ERROR_IS_OK(r.out.result)) {
382 /* TODO: do some more checks here */
385 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
386 printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
387 win_errstr(r.out.result));
392 blob = data_blob_talloc(ctx, NULL, buf_size);
393 data_blob_clear(&blob);
396 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
397 if (!NT_STATUS_IS_OK(status)) {
398 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
403 if (!W_ERROR_IS_OK(r.out.result)) {
404 printf("EnumMonitors failed - %s\n",
405 win_errstr(r.out.result));
410 ctx->monitor_count[level] = r.out.count;
411 ctx->monitors[level] = r.out.info;
414 for (i=1;i<ARRAY_SIZE(levels);i++) {
415 int level = levels[i];
416 int old_level = levels[i-1];
417 if (ctx->monitor_count[level] != ctx->monitor_count[old_level]) {
418 printf("EnumMonitors level[%d] returns [%u] monitors, but level[%d] returns [%u]\n",
419 level, ctx->monitor_count[level], old_level, ctx->monitor_count[old_level]);
423 /* if the array sizes are not the same we would maybe segfault in the following code */
424 if (!ret) return ret;
426 for (i=0;i<ARRAY_SIZE(levels);i++) {
427 int level = levels[i];
428 for (j=0;j<ctx->monitor_count[level];j++) {
429 union spoolss_MonitorInfo *cur = &ctx->monitors[level][j];
430 union spoolss_MonitorInfo *ref = &ctx->monitors[2][j];
433 COMPARE_STRING(cur->info1, ref->info2, monitor_name);
436 /* level 2 is our reference, and it makes no sense to compare it to itself */
445 static BOOL test_EnumPrintProcessors(struct test_spoolss_context *ctx)
448 struct spoolss_EnumPrintProcessors r;
449 uint16_t levels[] = { 1 };
453 for (i=0;i<ARRAY_SIZE(levels);i++) {
454 int level = levels[i];
456 uint32_t buf_size = 0;
458 r.in.servername = "";
459 r.in.environment = "Windows NT x86";
463 r.in.buf_size = &buf_size;
464 r.out.buf_size = &buf_size;
466 printf("Testing EnumPrintProcessors level %u\n", r.in.level);
468 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
469 if (!NT_STATUS_IS_OK(status)) {
470 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
474 if (W_ERROR_IS_OK(r.out.result)) {
475 /* TODO: do some more checks here */
478 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
479 printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
480 win_errstr(r.out.result));
485 blob = data_blob_talloc(ctx, NULL, buf_size);
486 data_blob_clear(&blob);
489 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
490 if (!NT_STATUS_IS_OK(status)) {
491 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
496 if (!W_ERROR_IS_OK(r.out.result)) {
497 printf("EnumPrintProcessors failed - %s\n",
498 win_errstr(r.out.result));
503 ctx->print_processor_count[level] = r.out.count;
504 ctx->print_processors[level] = r.out.info;
507 for (i=1;i<ARRAY_SIZE(levels);i++) {
508 int level = levels[i];
509 int old_level = levels[i-1];
510 if (ctx->print_processor_count[level] != ctx->print_processor_count[old_level]) {
511 printf("EnumPrintProcessors level[%d] returns [%u] print_processors, but level[%d] returns [%u]\n",
512 level, ctx->print_processor_count[level], old_level, ctx->print_processor_count[old_level]);
516 /* if the array sizes are not the same we would maybe segfault in the following code */
517 if (!ret) return ret;
519 for (i=0;i<ARRAY_SIZE(levels);i++) {
520 int level = levels[i];
521 for (j=0;j<ctx->print_processor_count[level];j++) {
523 union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][j];
524 union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][j];
528 /* level 1 is our reference, and it makes no sense to compare it to itself */
537 static BOOL test_EnumPrinters(struct test_spoolss_context *ctx)
539 struct spoolss_EnumPrinters r;
541 uint16_t levels[] = { 0, 1, 2, 4, 5 };
545 for (i=0;i<ARRAY_SIZE(levels);i++) {
546 int level = levels[i];
548 uint32_t buf_size = 0;
550 r.in.flags = PRINTER_ENUM_LOCAL;
554 r.in.buf_size = &buf_size;
555 r.out.buf_size = &buf_size;
557 printf("\nTesting EnumPrinters level %u\n", r.in.level);
559 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
560 if (!NT_STATUS_IS_OK(status)) {
561 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
565 if (W_ERROR_IS_OK(r.out.result)) {
566 /* TODO: do some more checks here */
569 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
570 printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
571 win_errstr(r.out.result));
576 blob = data_blob_talloc(ctx, NULL, buf_size);
577 data_blob_clear(&blob);
579 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
580 if (!NT_STATUS_IS_OK(status)) {
581 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
586 if (!W_ERROR_IS_OK(r.out.result)) {
587 printf("EnumPrinters failed - %s\n",
588 win_errstr(r.out.result));
592 ctx->printer_count[level] = r.out.count;
593 ctx->printers[level] = r.out.info;
596 for (i=1;i<ARRAY_SIZE(levels);i++) {
597 int level = levels[i];
598 int old_level = levels[i-1];
599 if (ctx->printer_count[level] != ctx->printer_count[old_level]) {
600 printf("EnumPrinters level[%d] returns [%u] printers, but level[%d] returns [%u]\n",
601 level, ctx->printer_count[level], old_level, ctx->printer_count[old_level]);
605 /* if the array sizes are not the same we would maybe segfault in the following code */
606 if (!ret) return ret;
608 for (i=0;i<ARRAY_SIZE(levels);i++) {
609 int level = levels[i];
610 for (j=0;j<ctx->printer_count[level];j++) {
611 union spoolss_PrinterInfo *cur = &ctx->printers[level][j];
612 union spoolss_PrinterInfo *ref = &ctx->printers[2][j];
615 COMPARE_STRING(cur->info0, ref->info2, printername);
616 COMPARE_STRING(cur->info0, ref->info2, servername);
617 COMPARE_UINT32(cur->info0, ref->info2, cjobs);
618 /*COMPARE_UINT32(cur->info0, ref->info2, total_jobs);
619 COMPARE_UINT32(cur->info0, ref->info2, total_bytes);
620 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
621 COMPARE_UINT32(cur->info0, ref->info2, global_counter);
622 COMPARE_UINT32(cur->info0, ref->info2, total_pages);
623 COMPARE_UINT32(cur->info0, ref->info2, version);
624 COMPARE_UINT32(cur->info0, ref->info2, unknown10);
625 COMPARE_UINT32(cur->info0, ref->info2, unknown11);
626 COMPARE_UINT32(cur->info0, ref->info2, unknown12);
627 COMPARE_UINT32(cur->info0, ref->info2, session_counter);
628 COMPARE_UINT32(cur->info0, ref->info2, unknown14);
629 COMPARE_UINT32(cur->info0, ref->info2, printer_errors);
630 COMPARE_UINT32(cur->info0, ref->info2, unknown16);
631 COMPARE_UINT32(cur->info0, ref->info2, unknown17);
632 COMPARE_UINT32(cur->info0, ref->info2, unknown18);
633 COMPARE_UINT32(cur->info0, ref->info2, unknown19);
634 COMPARE_UINT32(cur->info0, ref->info2, change_id);
635 COMPARE_UINT32(cur->info0, ref->info2, unknown21);*/
636 COMPARE_UINT32(cur->info0, ref->info2, status);
637 /*COMPARE_UINT32(cur->info0, ref->info2, unknown23);
638 COMPARE_UINT32(cur->info0, ref->info2, c_setprinter);
639 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
640 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
641 COMPARE_UINT32(cur->info0, ref->info2, unknown27);
642 COMPARE_UINT32(cur->info0, ref->info2, unknown28);
643 COMPARE_UINT32(cur->info0, ref->info2, unknown29);*/
646 /*COMPARE_UINT32(cur->info1, ref->info2, flags);*/
647 /*COMPARE_STRING(cur->info1, ref->info2, name);*/
648 /*COMPARE_STRING(cur->info1, ref->info2, description);*/
649 COMPARE_STRING(cur->info1, ref->info2, comment);
652 /* level 2 is our reference, and it makes no sense to compare it to itself */
655 COMPARE_STRING(cur->info4, ref->info2, printername);
656 COMPARE_STRING(cur->info4, ref->info2, servername);
657 COMPARE_UINT32(cur->info4, ref->info2, attributes);
660 COMPARE_STRING(cur->info5, ref->info2, printername);
661 COMPARE_STRING(cur->info5, ref->info2, portname);
662 COMPARE_UINT32(cur->info5, ref->info2, attributes);
663 /*COMPARE_UINT32(cur->info5, ref->info2, device_not_selected_timeout);
664 COMPARE_UINT32(cur->info5, ref->info2, transmission_retry_timeout);*/
671 * - verify that the port of a printer was in the list returned by EnumPorts
677 static BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
678 struct policy_handle *handle)
681 struct spoolss_GetPrinter r;
682 uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
686 for (i=0;i<ARRAY_SIZE(levels);i++) {
687 uint32_t buf_size = 0;
688 r.in.handle = handle;
689 r.in.level = levels[i];
691 r.in.buf_size = &buf_size;
692 r.out.buf_size = &buf_size;
694 printf("Testing GetPrinter level %u\n", r.in.level);
696 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
697 if (!NT_STATUS_IS_OK(status)) {
698 printf("GetPrinter failed - %s\n", nt_errstr(status));
703 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
704 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
705 data_blob_clear(&blob);
707 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
710 if (!NT_STATUS_IS_OK(status)) {
711 printf("GetPrinter failed - %s\n", nt_errstr(status));
716 if (!W_ERROR_IS_OK(r.out.result)) {
717 printf("GetPrinter failed - %s\n",
718 win_errstr(r.out.result));
728 static BOOL test_ClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
729 struct policy_handle *handle)
732 struct spoolss_ClosePrinter r;
734 r.in.handle = handle;
735 r.out.handle = handle;
737 printf("Testing ClosePrinter\n");
739 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("ClosePrinter failed - %s\n", nt_errstr(status));
748 static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
749 struct policy_handle *handle,
750 const char *form_name)
753 struct spoolss_GetForm r;
756 r.in.handle = handle;
757 r.in.form_name = form_name;
761 r.in.buf_size = r.out.buf_size = &buf_size;
763 printf("Testing GetForm\n");
765 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
767 if (!NT_STATUS_IS_OK(status)) {
768 printf("GetForm failed - %s\n", nt_errstr(status));
772 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
773 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
775 data_blob_clear(&blob);
778 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
781 printf("No form info returned");
789 static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
790 struct policy_handle *handle)
793 struct spoolss_EnumForms r;
796 r.in.handle = handle;
800 r.in.buf_size = &buf_size;
801 r.out.buf_size = &buf_size;
803 printf("Testing EnumForms\n");
805 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("EnumForms failed - %s\n", nt_errstr(status));
812 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
813 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
814 union spoolss_FormInfo *info;
817 data_blob_clear(&blob);
820 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
823 printf("No forms returned");
829 for (j = 0; j < r.out.count; j++) {
830 test_GetForm(p, mem_ctx, handle, info[j].info1.form_name);
834 if (!NT_STATUS_IS_OK(status)) {
835 printf("EnumForms failed - %s\n", nt_errstr(status));
839 if (!W_ERROR_IS_OK(r.out.result)) {
840 printf("EnumForms failed - %s\n", win_errstr(r.out.result));
847 static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
848 struct policy_handle *handle,
849 const char *form_name)
852 struct spoolss_DeleteForm r;
854 r.in.handle = handle;
855 r.in.form_name = form_name;
857 status = dcerpc_spoolss_DeleteForm(p, mem_ctx, &r);
859 if (!NT_STATUS_IS_OK(status)) {
860 printf("DeleteForm failed - %s\n", nt_errstr(status));
864 if (!W_ERROR_IS_OK(r.out.result)) {
865 printf("DeleteForm failed - %s\n", win_errstr(r.out.result));
872 static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
873 struct policy_handle *handle)
875 struct spoolss_AddForm r;
876 struct spoolss_AddFormInfo1 addform;
877 const char *form_name = "testform3";
881 r.in.handle = handle;
883 r.in.info.info1 = &addform;
884 addform.flags = SPOOLSS_FORM_USER;
885 addform.form_name = form_name;
886 addform.size.width = 50;
887 addform.size.height = 25;
888 addform.area.left = 5;
889 addform.area.top = 10;
890 addform.area.right = 45;
891 addform.area.bottom = 15;
893 status = dcerpc_spoolss_AddForm(p, mem_ctx, &r);
895 if (!NT_STATUS_IS_OK(status)) {
896 printf("AddForm failed - %s\n", nt_errstr(status));
900 if (!W_ERROR_IS_OK(r.out.result)) {
901 printf("AddForm failed - %s\n", nt_errstr(status));
906 struct spoolss_SetForm sf;
907 struct spoolss_SetFormInfo1 setform;
909 sf.in.handle = handle;
910 sf.in.form_name = form_name;
912 sf.in.info.info1= &setform;
913 setform.flags = addform.flags;
914 setform.form_name = addform.form_name;
915 setform.size = addform.size;
916 setform.area = addform.area;
918 setform.size.width = 1234;
920 status = dcerpc_spoolss_SetForm(p, mem_ctx, &sf);
922 if (!NT_STATUS_IS_OK(status)) {
923 printf("SetForm failed - %s\n", nt_errstr(status));
928 if (!W_ERROR_IS_OK(r.out.result)) {
929 printf("SetForm failed - %s\n",
930 win_errstr(r.out.result));
937 if (!test_DeleteForm(p, mem_ctx, handle, form_name)) {
938 printf("DeleteForm failed\n");
945 static BOOL test_EnumPorts_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
948 struct spoolss_EnumPorts r;
951 r.in.servername = talloc_asprintf(mem_ctx, "\\\\%s",
952 dcerpc_server_name(p));
956 r.in.buf_size = &buf_size;
957 r.out.buf_size = &buf_size;
959 printf("Testing EnumPorts\n");
961 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
963 if (!NT_STATUS_IS_OK(status)) {
964 printf("EnumPorts failed - %s\n", nt_errstr(status));
968 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
969 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
971 data_blob_clear(&blob);
974 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
976 if (!NT_STATUS_IS_OK(status)) {
977 printf("EnumPorts failed - %s\n", nt_errstr(status));
982 printf("No ports returned");
990 static BOOL test_AddPort(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
993 struct spoolss_AddPort r;
995 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
996 dcerpc_server_name(p));
998 r.in.monitor_name = "foo";
1000 printf ("Testing AddPort\n");
1002 status = dcerpc_spoolss_AddPort(p, mem_ctx, &r);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 printf("AddPort failed - %s\n", nt_errstr(status));
1009 /* win2k3 returns WERR_NOT_SUPPORTED */
1013 if (!W_ERROR_IS_OK(r.out.result)) {
1014 printf("AddPort failed - %s\n", win_errstr(r.out.result));
1023 static BOOL test_GetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1024 struct policy_handle *handle, uint32_t job_id)
1027 struct spoolss_GetJob r;
1030 r.in.handle = handle;
1031 r.in.job_id = job_id;
1035 r.in.buf_size = r.out.buf_size = &buf_size;
1037 printf("Testing GetJob\n");
1039 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 printf("GetJob failed - %s\n", nt_errstr(status));
1046 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1047 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
1049 data_blob_clear(&blob);
1050 r.in.buffer = &blob;
1052 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1055 printf("No job info returned");
1063 static BOOL test_SetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1064 struct policy_handle *handle, uint32_t job_id, enum spoolss_JobControl command)
1067 struct spoolss_SetJob r;
1069 r.in.handle = handle;
1070 r.in.job_id = job_id;
1072 r.in.command = command;
1074 printf("Testing SetJob\n");
1076 status = dcerpc_spoolss_SetJob(p, mem_ctx, &r);
1077 if (!NT_STATUS_IS_OK(status)) {
1078 printf("SetJob failed - %s\n", nt_errstr(status));
1081 if (!W_ERROR_IS_OK(r.out.result)) {
1082 printf("SetJob failed - %s\n", win_errstr(r.out.result));
1089 static BOOL test_EnumJobs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1090 struct policy_handle *handle)
1093 struct spoolss_EnumJobs r;
1096 r.in.handle = handle;
1098 r.in.numjobs = 0xffffffff;
1102 r.in.buf_size = &buf_size;
1103 r.out.buf_size = &buf_size;
1105 printf("Testing EnumJobs\n");
1107 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1109 if (!NT_STATUS_IS_OK(status)) {
1110 printf("EnumJobs failed - %s\n", nt_errstr(status));
1114 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1115 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
1116 union spoolss_JobInfo *info;
1119 data_blob_clear(&blob);
1120 r.in.buffer = &blob;
1122 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1125 printf("No jobs returned");
1131 for (j = 0; j < r.out.count; j++) {
1132 test_GetJob(p, mem_ctx, handle, info[j].info1.job_id);
1133 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
1134 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
1137 } else if (!W_ERROR_IS_OK(r.out.result)) {
1138 printf("EnumJobs failed - %s\n", win_errstr(r.out.result));
1145 static BOOL test_DoPrintTest(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1146 struct policy_handle *handle)
1150 struct spoolss_StartDocPrinter s;
1151 struct spoolss_DocumentInfo1 info1;
1152 struct spoolss_StartPagePrinter sp;
1153 struct spoolss_WritePrinter w;
1154 struct spoolss_EndPagePrinter ep;
1155 struct spoolss_EndDocPrinter e;
1159 printf("Testing StartDocPrinter\n");
1161 s.in.handle = handle;
1163 s.in.info.info1 = &info1;
1164 info1.document_name = "TorturePrintJob";
1165 info1.output_file = NULL;
1166 info1.datatype = "RAW";
1168 status = dcerpc_spoolss_StartDocPrinter(p, mem_ctx, &s);
1169 if (!NT_STATUS_IS_OK(status)) {
1170 printf("dcerpc_spoolss_StartDocPrinter failed - %s\n", nt_errstr(status));
1173 if (!W_ERROR_IS_OK(s.out.result)) {
1174 printf("StartDocPrinter failed - %s\n", win_errstr(s.out.result));
1178 job_id = s.out.job_id;
1180 for (i=1; i < 4; i++) {
1181 printf("Testing StartPagePrinter: Page[%d]\n", i);
1183 sp.in.handle = handle;
1185 status = dcerpc_spoolss_StartPagePrinter(p, mem_ctx, &sp);
1186 if (!NT_STATUS_IS_OK(status)) {
1187 printf("dcerpc_spoolss_StartPagePrinter failed - %s\n", nt_errstr(status));
1190 if (!W_ERROR_IS_OK(sp.out.result)) {
1191 printf("StartPagePrinter failed - %s\n", win_errstr(sp.out.result));
1195 printf("Testing WritePrinter: Page[%d]\n", i);
1197 w.in.handle = handle;
1198 w.in.data = data_blob_string_const(talloc_asprintf(mem_ctx,"TortureTestPage: %d\nData\n",i));
1200 status = dcerpc_spoolss_WritePrinter(p, mem_ctx, &w);
1201 if (!NT_STATUS_IS_OK(status)) {
1202 printf("dcerpc_spoolss_WritePrinter failed - %s\n", nt_errstr(status));
1205 if (!W_ERROR_IS_OK(w.out.result)) {
1206 printf("WritePrinter failed - %s\n", win_errstr(w.out.result));
1210 printf("Testing EndPagePrinter: Page[%d]\n", i);
1212 ep.in.handle = handle;
1214 status = dcerpc_spoolss_EndPagePrinter(p, mem_ctx, &ep);
1215 if (!NT_STATUS_IS_OK(status)) {
1216 printf("dcerpc_spoolss_EndPagePrinter failed - %s\n", nt_errstr(status));
1219 if (!W_ERROR_IS_OK(ep.out.result)) {
1220 printf("EndPagePrinter failed - %s\n", win_errstr(ep.out.result));
1225 printf("Testing EndDocPrinter\n");
1227 e.in.handle = handle;
1229 status = dcerpc_spoolss_EndDocPrinter(p, mem_ctx, &e);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 printf("dcerpc_spoolss_EndDocPrinter failed - %s\n", nt_errstr(status));
1234 if (!W_ERROR_IS_OK(e.out.result)) {
1235 printf("EndDocPrinter failed - %s\n", win_errstr(e.out.result));
1239 ret &= test_EnumJobs(p, mem_ctx, handle);
1241 ret &= test_SetJob(p, mem_ctx, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
1246 static BOOL test_PausePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1247 struct policy_handle *handle)
1250 struct spoolss_SetPrinter r;
1252 r.in.handle = handle;
1254 r.in.info.info1 = NULL;
1255 r.in.devmode_ctr.size = 0;
1256 r.in.devmode_ctr.devmode= NULL;
1257 r.in.secdesc_ctr.size = 0;
1258 r.in.secdesc_ctr.sd = NULL;
1259 r.in.command = SPOOLSS_PRINTER_CONTROL_PAUSE;
1261 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_PAUSE\n");
1263 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1265 if (!NT_STATUS_IS_OK(status)) {
1266 printf("SetPrinter failed - %s\n", nt_errstr(status));
1270 if (!W_ERROR_IS_OK(r.out.result)) {
1271 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1278 static BOOL test_ResumePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1279 struct policy_handle *handle)
1282 struct spoolss_SetPrinter r;
1284 r.in.handle = handle;
1286 r.in.info.info1 = NULL;
1287 r.in.devmode_ctr.size = 0;
1288 r.in.devmode_ctr.devmode= NULL;
1289 r.in.secdesc_ctr.size = 0;
1290 r.in.secdesc_ctr.sd = NULL;
1291 r.in.command = SPOOLSS_PRINTER_CONTROL_RESUME;
1293 printf("Testing SetPrinter: SPOOLSS_PRINTER_CONTROL_RESUME\n");
1295 status = dcerpc_spoolss_SetPrinter(p, mem_ctx, &r);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 printf("SetPrinter failed - %s\n", nt_errstr(status));
1302 if (!W_ERROR_IS_OK(r.out.result)) {
1303 printf("SetPrinter failed - %s\n", win_errstr(r.out.result));
1310 static BOOL test_GetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1311 struct policy_handle *handle,
1312 const char *value_name)
1315 struct spoolss_GetPrinterData r;
1318 r.in.handle = handle;
1319 r.in.value_name = value_name;
1321 r.in.buf_size = r.out.buf_size = &buf_size;
1323 printf("Testing GetPrinterData\n");
1325 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 printf("GetPrinterData failed - %s\n", nt_errstr(status));
1332 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1334 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 printf("GetPrinterData failed - %s\n",
1342 if (!W_ERROR_IS_OK(r.out.result)) {
1343 printf("GetPrinterData failed - %s\n",
1344 win_errstr(r.out.result));
1352 static BOOL test_GetPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1353 struct policy_handle *handle,
1354 const char *key_name,
1355 const char *value_name)
1358 struct spoolss_GetPrinterDataEx r;
1361 r.in.handle = handle;
1362 r.in.key_name = key_name;
1363 r.in.value_name = value_name;
1365 r.in.buf_size = r.out.buf_size = &buf_size;
1367 printf("Testing GetPrinterDataEx\n");
1369 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1370 if (!NT_STATUS_IS_OK(status)) {
1371 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1372 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1373 printf("GetPrinterDataEx not supported by server\n");
1376 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status));
1380 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1382 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1384 if (!NT_STATUS_IS_OK(status)) {
1385 printf("GetPrinterDataEx failed - %s\n",
1390 if (!W_ERROR_IS_OK(r.out.result)) {
1391 printf("GetPrinterDataEx failed - %s\n",
1392 win_errstr(r.out.result));
1400 static BOOL test_EnumPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1401 struct policy_handle *handle)
1404 struct spoolss_EnumPrinterData r;
1406 r.in.handle = handle;
1407 r.in.enum_index = 0;
1412 r.in.value_offered = 0;
1414 r.in.data_size = &data_size;
1415 r.out.data_size = &data_size;
1417 printf("Testing EnumPrinterData\n");
1419 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1421 if (!NT_STATUS_IS_OK(status)) {
1422 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1426 r.in.value_offered = r.out.value_needed;
1428 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1435 test_GetPrinterData(p, mem_ctx, handle, r.out.value_name);
1437 test_GetPrinterDataEx(
1438 p, mem_ctx, handle, "PrinterDriverData",
1443 } while (W_ERROR_IS_OK(r.out.result));
1448 static BOOL test_EnumPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1449 struct policy_handle *handle)
1452 struct spoolss_EnumPrinterDataEx r;
1454 r.in.handle = handle;
1455 r.in.key_name = "PrinterDriverData";
1458 printf("Testing EnumPrinterDataEx\n");
1460 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1467 r.in.buf_size = r.out.buf_size;
1469 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1471 if (!NT_STATUS_IS_OK(status)) {
1472 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1480 static BOOL test_DeletePrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1481 struct policy_handle *handle,
1482 const char *value_name)
1485 struct spoolss_DeletePrinterData r;
1487 r.in.handle = handle;
1488 r.in.value_name = value_name;
1490 printf("Testing DeletePrinterData\n");
1492 status = dcerpc_spoolss_DeletePrinterData(p, mem_ctx, &r);
1494 if (!NT_STATUS_IS_OK(status)) {
1495 printf("DeletePrinterData failed - %s\n", nt_errstr(status));
1502 static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1503 struct policy_handle *handle)
1506 struct spoolss_SetPrinterData r;
1507 const char *value_name = "spottyfoot";
1509 r.in.handle = handle;
1510 r.in.value_name = value_name;
1511 r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
1512 r.in.data.string = "dog";
1514 printf("Testing SetPrinterData\n");
1516 status = dcerpc_spoolss_SetPrinterData(p, mem_ctx, &r);
1518 if (!NT_STATUS_IS_OK(status)) {
1519 printf("SetPrinterData failed - %s\n", nt_errstr(status));
1523 if (!test_GetPrinterData(p, mem_ctx, handle, value_name)) {
1527 if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) {
1534 static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1535 struct policy_handle *handle)
1538 struct dcerpc_binding *b;
1539 struct dcerpc_pipe *p2;
1542 /* only makes sense on SMB */
1543 if (p->conn->transport.transport != NCACN_NP) {
1547 printf("testing close on secondary pipe\n");
1549 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1550 if (!NT_STATUS_IS_OK(status)) {
1551 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1555 status = dcerpc_secondary_connection(p, &p2, b);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 printf("Failed to create secondary connection\n");
1561 status = dcerpc_bind_auth_none(p2, DCERPC_SPOOLSS_UUID,
1562 DCERPC_SPOOLSS_VERSION);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 printf("Failed to create bind on secondary connection\n");
1570 if (test_ClosePrinter(p2, mem_ctx, handle)) {
1571 printf("ERROR: Allowed close on secondary connection!\n");
1575 if (p2->last_fault_code != DCERPC_FAULT_CONTEXT_MISMATCH) {
1576 printf("Unexpected fault code 0x%x - expected 0x%x\n",
1577 p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH);
1586 static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
1589 struct spoolss_OpenPrinter op;
1590 struct spoolss_OpenPrinterEx opEx;
1591 struct policy_handle handle;
1594 op.in.printername = name;
1595 op.in.datatype = NULL;
1596 op.in.devmode_ctr.size = 0;
1597 op.in.devmode_ctr.devmode= NULL;
1598 op.in.access_mask = 0;
1599 op.out.handle = &handle;
1601 printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1603 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
1604 if (!NT_STATUS_IS_OK(status)) {
1605 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1608 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1609 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1610 name, win_errstr(op.out.result));
1613 if (W_ERROR_IS_OK(op.out.result)) {
1614 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1617 opEx.in.printername = name;
1618 opEx.in.datatype = NULL;
1619 opEx.in.devmode_ctr.size = 0;
1620 opEx.in.devmode_ctr.devmode = NULL;
1621 opEx.in.access_mask = 0;
1623 opEx.in.userlevel.level1 = NULL;
1624 opEx.out.handle = &handle;
1626 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1628 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
1629 if (!NT_STATUS_IS_OK(status)) {
1630 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1633 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
1634 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1635 name, win_errstr(opEx.out.result));
1638 if (W_ERROR_IS_OK(opEx.out.result)) {
1639 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1645 static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1650 ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
1651 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
1652 ret &= test_OpenPrinter_badname(p, mem_ctx, "");
1653 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
1654 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
1656 name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
1657 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1660 name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
1661 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1667 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1671 struct spoolss_OpenPrinter r;
1672 struct policy_handle handle;
1675 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1676 r.in.datatype = NULL;
1677 r.in.devmode_ctr.size = 0;
1678 r.in.devmode_ctr.devmode= NULL;
1679 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1680 r.out.handle = &handle;
1682 printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
1684 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
1686 if (!NT_STATUS_IS_OK(status)) {
1687 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1691 if (!W_ERROR_IS_OK(r.out.result)) {
1692 printf("OpenPrinter failed - %s\n", win_errstr(r.out.result));
1696 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1700 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1704 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1711 static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1712 const char *name, struct policy_handle *handle)
1714 struct spoolss_OpenPrinterEx r;
1715 struct spoolss_UserLevel1 userlevel1;
1718 if (name && name[0]) {
1719 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
1720 dcerpc_server_name(p), name);
1722 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
1723 dcerpc_server_name(p));
1726 r.in.datatype = NULL;
1727 r.in.devmode_ctr.size = 0;
1728 r.in.devmode_ctr.devmode= NULL;
1729 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1731 r.in.userlevel.level1 = &userlevel1;
1732 r.out.handle = handle;
1734 userlevel1.size = 1234;
1735 userlevel1.client = "hello";
1736 userlevel1.user = "spottyfoot!";
1737 userlevel1.build = 1;
1738 userlevel1.major = 2;
1739 userlevel1.minor = 3;
1740 userlevel1.processor = 4;
1742 printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
1744 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
1746 if (!NT_STATUS_IS_OK(status)) {
1747 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
1751 if (!W_ERROR_IS_OK(r.out.result)) {
1752 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
1759 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1762 struct policy_handle handle;
1765 if (!call_OpenPrinterEx(p, mem_ctx, name, &handle)) {
1769 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1773 if (!test_EnumForms(p, mem_ctx, &handle)) {
1777 if (!test_AddForm(p, mem_ctx, &handle)) {
1781 if (!test_EnumPrinterData(p, mem_ctx, &handle)) {
1785 if (!test_EnumPrinterDataEx(p, mem_ctx, &handle)) {
1789 if (!test_PausePrinter(p, mem_ctx, &handle)) {
1793 if (!test_DoPrintTest(p, mem_ctx, &handle)) {
1797 if (!test_ResumePrinter(p, mem_ctx, &handle)) {
1801 if (!test_SetPrinterData(p, mem_ctx, &handle)) {
1805 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1809 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1816 static BOOL test_EnumPrinters_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1818 struct spoolss_EnumPrinters r;
1820 uint16_t levels[] = {1, 2, 4, 5};
1824 for (i=0;i<ARRAY_SIZE(levels);i++) {
1825 uint32_t buf_size = 0;
1826 union spoolss_PrinterInfo *info;
1829 r.in.flags = PRINTER_ENUM_LOCAL;
1831 r.in.level = levels[i];
1833 r.in.buf_size = &buf_size;
1834 r.out.buf_size = &buf_size;
1836 printf("\nTesting EnumPrinters level %u\n", r.in.level);
1838 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1839 if (!NT_STATUS_IS_OK(status)) {
1840 printf("EnumPrinters failed - %s\n", nt_errstr(status));
1845 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1846 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
1847 data_blob_clear(&blob);
1848 r.in.buffer = &blob;
1849 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1852 if (!NT_STATUS_IS_OK(status)) {
1853 printf("EnumPrinters failed - %s\n",
1858 if (!W_ERROR_IS_OK(r.out.result)) {
1859 printf("EnumPrinters failed - %s\n",
1860 win_errstr(r.out.result));
1865 printf("No printers returned");
1871 for (j=0;j<r.out.count;j++) {
1872 if (r.in.level == 1) {
1873 /* the names appear to be comma-separated name lists? */
1874 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
1875 char *comma = strchr(name, ',');
1876 if (comma) *comma = 0;
1877 if (!test_OpenPrinter(p, mem_ctx, name)) {
1880 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
1891 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1892 struct policy_handle *handle,
1893 const char *driver_name)
1896 struct spoolss_GetPrinterDriver2 r;
1899 r.in.handle = handle;
1900 r.in.architecture = "W32X86";
1904 r.in.buf_size = r.out.buf_size = &buf_size;
1905 r.in.client_major_version = 0;
1906 r.in.client_minor_version = 0;
1908 printf("Testing GetPrinterDriver2\n");
1910 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1912 if (!NT_STATUS_IS_OK(status)) {
1913 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1917 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1918 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1921 if (!NT_STATUS_IS_OK(status)) {
1922 printf("GetPrinterDriver2 failed - %s\n",
1927 if (!W_ERROR_IS_OK(r.out.result)) {
1928 printf("GetPrinterDriver2 failed - %s\n",
1929 win_errstr(r.out.result));
1937 static BOOL test_EnumPrinterDrivers_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1939 struct spoolss_EnumPrinterDrivers r;
1941 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
1945 for (i=0;i<ARRAY_SIZE(levels);i++) {
1948 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1949 r.in.environment = "Windows NT x86";
1950 r.in.level = levels[i];
1953 r.in.buf_size = &buf_size;
1954 r.out.buf_size = &buf_size;
1956 printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
1958 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
1960 if (!NT_STATUS_IS_OK(status)) {
1961 printf("EnumPrinterDrivers failed - %s\n",
1967 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1968 DATA_BLOB blob = data_blob_talloc(
1969 mem_ctx, NULL, buf_size);
1971 data_blob_clear(&blob);
1972 r.in.buffer = &blob;
1973 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
1976 if (!NT_STATUS_IS_OK(status)) {
1977 printf("EnumPrinterDrivers failed - %s\n",
1983 if (!W_ERROR_IS_OK(r.out.result)) {
1984 printf("EnumPrinterDrivers failed - %s\n",
1985 win_errstr(r.out.result));
1991 printf("No printer drivers returned");
1999 BOOL torture_rpc_spoolss(void)
2002 struct dcerpc_pipe *p;
2003 TALLOC_CTX *mem_ctx;
2005 struct test_spoolss_context *ctx;
2007 mem_ctx = talloc_init("torture_rpc_spoolss");
2009 status = torture_rpc_connection(mem_ctx,
2011 DCERPC_SPOOLSS_NAME,
2012 DCERPC_SPOOLSS_UUID,
2013 DCERPC_SPOOLSS_VERSION);
2014 if (!NT_STATUS_IS_OK(status)) {
2015 talloc_free(mem_ctx);
2019 ctx = talloc_zero(mem_ctx, struct test_spoolss_context);
2022 ret &= test_OpenPrinter_server(ctx);
2024 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "W3SvcInstalled");
2025 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "BeepEnabled");
2026 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "EventLog");
2027 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopup");
2028 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "NetPopupToComputer");
2029 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MajorVersion");
2030 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "MinorVersion");
2031 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DefaultSpoolDirectory");
2032 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "Architecture");
2033 ret &= test_GetPrinterData(ctx->p, ctx, &ctx->server_handle, "DsPresent");
2035 ret &= test_EnumPorts(ctx);
2037 ret &= test_EnumPrinterDrivers(ctx);
2039 ret &= test_EnumMonitors(ctx);
2041 ret &= test_EnumPrintProcessors(ctx);
2043 ret &= test_EnumPrinters(ctx);
2045 ret &= test_OpenPrinter_badnames(p, mem_ctx);
2047 ret &= test_AddPort(p, mem_ctx);
2049 ret &= test_EnumPorts_old(p, mem_ctx);
2051 ret &= test_EnumPrinters_old(p, mem_ctx);
2053 ret &= test_EnumPrinterDrivers_old(p, mem_ctx);
2055 talloc_free(mem_ctx);