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;
30 uint32_t port_count[3];
31 union spoolss_PortInfo **ports[3];
33 /* for EnumPrinterDrivers */
34 uint32_t driver_count[7];
35 union spoolss_DriverInfo **drivers[7];
37 /* for EnumMonitors */
38 uint32_t monitor_count[3];
39 union spoolss_MonitorInfo **monitors[3];
41 /* for EnumPrintProcessors */
42 uint32_t print_processor_count[2];
43 union spoolss_PrintProcessorInfo **print_processors[2];
45 /* for EnumPrinters */
46 uint32_t printer_count[6];
47 union spoolss_PrinterInfo **printers[6];
50 #define COMPARE_STRING(c,r,e) do {\
52 if (c.e && !r.e) _ok = False;\
53 if (!c.e && r.e) _ok = False;\
54 if (c.e && r.e && strcmp_safe(c.e, r.e) != 0) _ok = False;\
56 printf("%s: " #c "." #e " [%s] doesn't match " #r "." #e " [%s]\n",\
57 __location__, c.e, r.e);\
62 #define COMPARE_UINT16(c,r,e) do {\
64 printf("%s: " #c "." #e " 0x%08X (%u) doesn't match " #r "." #e " 0x%08X (%u)\n",\
65 __location__, c.e, c.e, r.e, r.e);\
70 #define COMPARE_UINT32(c,r,e) do {\
72 printf("%s: " #c "." #e " 0x%04X (%u) doesn't match " #r "." #e " 0x%04X (%u)\n",\
73 __location__, c.e, c.e, r.e, r.e);\
78 #define COMPARE_UINT64(c,r,e) do {\
80 printf("%s: " #c "." #e " 0x%08X%08X (%llu) doesn't match " #r "." #e " 0x%08X%08X (%llu)\n",\
81 __location__, (uint32_t)(c.e >> 32), (uint32_t)(c.e & 0xFFFFFFFF), c.e,\
82 (uint32_t)(r.e >> 32), (uint32_t)(r.e & 0xFFFFFFFF), r.e);\
88 #define COMPARE_SEC_DESC(c,r,e)
89 #define COMPARE_SPOOLSS_TIME(c,r,e)
90 #define COMPARE_STRING_ARRAY(c,r,e)
92 static BOOL test_EnumPorts(struct test_spoolss_context *ctx)
95 struct spoolss_EnumPorts r;
96 uint16_t levels[] = { 1, 2 };
100 for (i=0;i<ARRAY_SIZE(levels);i++) {
101 int level = levels[i];
103 uint32_t buf_size = 0;
105 r.in.servername = "";
109 r.in.buf_size = &buf_size;
110 r.out.buf_size = &buf_size;
112 printf("Testing EnumPorts level %u\n", r.in.level);
114 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
115 if (!NT_STATUS_IS_OK(status)) {
116 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
121 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
122 printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
123 win_errstr(r.out.result));
128 blob = data_blob_talloc(ctx, NULL, buf_size);
129 data_blob_clear(&blob);
132 status = dcerpc_spoolss_EnumPorts(ctx->p, ctx, &r);
133 if (!NT_STATUS_IS_OK(status)) {
134 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status));
139 if (!W_ERROR_IS_OK(r.out.result)) {
140 printf("EnumPorts failed - %s\n",
141 win_errstr(r.out.result));
146 ctx->port_count[level] = r.out.count;
147 ctx->ports[level] = r.out.info;
150 for (i=1;i<ARRAY_SIZE(levels);i++) {
151 int level = levels[i];
152 int old_level = levels[i-1];
153 if (ctx->port_count[level] != ctx->port_count[old_level]) {
154 printf("EnumPorts level[%d] returns [%u] ports, but level[%d] returns [%u]\n",
155 level, ctx->port_count[level], old_level, ctx->port_count[old_level]);
159 /* if the array sizes are not the same we would maybe segfault in the following code */
160 if (!ret) return ret;
162 for (i=0;i<ARRAY_SIZE(levels);i++) {
163 int level = levels[i];
164 for (j=0;j<ctx->port_count[level];j++) {
165 union spoolss_PortInfo *cur = &ctx->ports[level][0][j];
166 union spoolss_PortInfo *ref = &ctx->ports[2][0][j];
169 COMPARE_STRING(cur->info1, ref->info2, port_name);
172 /* level 2 is our reference, and it makes no sense to compare it to itself */
181 static BOOL test_EnumPrinterDrivers(struct test_spoolss_context *ctx)
184 struct spoolss_EnumPrinterDrivers r;
185 uint16_t levels[] = { 1, 2, 3, 4, 5, 6 };
189 for (i=0;i<ARRAY_SIZE(levels);i++) {
190 int level = levels[i];
192 uint32_t buf_size = 0;
195 r.in.environment = "Windows NT x86";
199 r.in.buf_size = &buf_size;
200 r.out.buf_size = &buf_size;
202 printf("Testing EnumPrinterDrivers level %u\n", r.in.level);
204 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
205 if (!NT_STATUS_IS_OK(status)) {
206 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
211 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
212 printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
213 win_errstr(r.out.result));
218 blob = data_blob_talloc(ctx, NULL, buf_size);
219 data_blob_clear(&blob);
222 status = dcerpc_spoolss_EnumPrinterDrivers(ctx->p, ctx, &r);
223 if (!NT_STATUS_IS_OK(status)) {
224 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status));
229 if (!W_ERROR_IS_OK(r.out.result)) {
230 printf("EnumPrinterDrivers failed - %s\n",
231 win_errstr(r.out.result));
236 ctx->driver_count[level] = r.out.count;
237 ctx->drivers[level] = r.out.info;
240 for (i=1;i<ARRAY_SIZE(levels);i++) {
241 int level = levels[i];
242 int old_level = levels[i-1];
243 if (ctx->driver_count[level] != ctx->driver_count[old_level]) {
244 printf("EnumPrinterDrivers level[%d] returns [%u] drivers, but level[%d] returns [%u]\n",
245 level, ctx->driver_count[level], old_level, ctx->driver_count[old_level]);
249 /* if the array sizes are not the same we would maybe segfault in the following code */
250 if (!ret) return ret;
252 for (i=0;i<ARRAY_SIZE(levels);i++) {
253 int level = levels[i];
254 for (j=0;j<ctx->driver_count[level];j++) {
255 union spoolss_DriverInfo *cur = &ctx->drivers[level][0][j];
256 union spoolss_DriverInfo *ref = &ctx->drivers[6][0][j];
259 COMPARE_STRING(cur->info1, ref->info6, driver_name);
262 COMPARE_UINT32(cur->info2, ref->info6, version);
263 COMPARE_STRING(cur->info2, ref->info6, driver_name);
264 COMPARE_STRING(cur->info2, ref->info6, architecture);
265 COMPARE_STRING(cur->info2, ref->info6, driver_path);
266 COMPARE_STRING(cur->info2, ref->info6, data_file);
267 COMPARE_STRING(cur->info2, ref->info6, config_file);
270 COMPARE_UINT32(cur->info3, ref->info6, version);
271 COMPARE_STRING(cur->info3, ref->info6, driver_name);
272 COMPARE_STRING(cur->info3, ref->info6, architecture);
273 COMPARE_STRING(cur->info3, ref->info6, driver_path);
274 COMPARE_STRING(cur->info3, ref->info6, data_file);
275 COMPARE_STRING(cur->info3, ref->info6, config_file);
276 COMPARE_STRING(cur->info3, ref->info6, help_file);
277 COMPARE_STRING_ARRAY(cur->info3, ref->info6, dependent_files);
278 COMPARE_STRING(cur->info3, ref->info6, monitor_name);
279 COMPARE_STRING(cur->info3, ref->info6, default_datatype);
282 COMPARE_UINT32(cur->info4, ref->info6, version);
283 COMPARE_STRING(cur->info4, ref->info6, driver_name);
284 COMPARE_STRING(cur->info4, ref->info6, architecture);
285 COMPARE_STRING(cur->info4, ref->info6, driver_path);
286 COMPARE_STRING(cur->info4, ref->info6, data_file);
287 COMPARE_STRING(cur->info4, ref->info6, config_file);
288 COMPARE_STRING(cur->info4, ref->info6, help_file);
289 COMPARE_STRING_ARRAY(cur->info4, ref->info6, dependent_files);
290 COMPARE_STRING(cur->info4, ref->info6, monitor_name);
291 COMPARE_STRING(cur->info4, ref->info6, default_datatype);
292 COMPARE_STRING_ARRAY(cur->info4, ref->info6, previous_names);
295 COMPARE_UINT32(cur->info5, ref->info6, version);
296 COMPARE_STRING(cur->info5, ref->info6, driver_name);
297 COMPARE_STRING(cur->info5, ref->info6, architecture);
298 COMPARE_STRING(cur->info5, ref->info6, driver_path);
299 COMPARE_STRING(cur->info5, ref->info6, data_file);
300 COMPARE_STRING(cur->info5, ref->info6, config_file);
301 /*COMPARE_UINT32(cur->info5, ref->info6, driver_attributes);*/
302 /*COMPARE_UINT32(cur->info5, ref->info6, config_version);*/
303 /*TODO: ! COMPARE_UINT32(cur->info5, ref->info6, driver_version); */
306 /* level 6 is our reference, and it makes no sense to compare it to itself */
315 static BOOL test_EnumMonitors(struct test_spoolss_context *ctx)
318 struct spoolss_EnumMonitors r;
319 uint16_t levels[] = { 1, 2 };
323 for (i=0;i<ARRAY_SIZE(levels);i++) {
324 int level = levels[i];
326 uint32_t buf_size = 0;
328 r.in.servername = "";
332 r.in.buf_size = &buf_size;
333 r.out.buf_size = &buf_size;
335 printf("Testing EnumMonitors level %u\n", r.in.level);
337 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
338 if (!NT_STATUS_IS_OK(status)) {
339 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
344 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
345 printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
346 win_errstr(r.out.result));
351 blob = data_blob_talloc(ctx, NULL, buf_size);
352 data_blob_clear(&blob);
355 status = dcerpc_spoolss_EnumMonitors(ctx->p, ctx, &r);
356 if (!NT_STATUS_IS_OK(status)) {
357 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status));
362 if (!W_ERROR_IS_OK(r.out.result)) {
363 printf("EnumMonitors failed - %s\n",
364 win_errstr(r.out.result));
369 ctx->monitor_count[level] = r.out.count;
370 ctx->monitors[level] = r.out.info;
373 for (i=1;i<ARRAY_SIZE(levels);i++) {
374 int level = levels[i];
375 int old_level = levels[i-1];
376 if (ctx->monitor_count[level] != ctx->monitor_count[old_level]) {
377 printf("EnumMonitors level[%d] returns [%u] monitors, but level[%d] returns [%u]\n",
378 level, ctx->monitor_count[level], old_level, ctx->monitor_count[old_level]);
382 /* if the array sizes are not the same we would maybe segfault in the following code */
383 if (!ret) return ret;
385 for (i=0;i<ARRAY_SIZE(levels);i++) {
386 int level = levels[i];
387 for (j=0;j<ctx->monitor_count[level];j++) {
388 union spoolss_MonitorInfo *cur = &ctx->monitors[level][0][j];
389 union spoolss_MonitorInfo *ref = &ctx->monitors[2][0][j];
392 COMPARE_STRING(cur->info1, ref->info2, monitor_name);
395 /* level 2 is our reference, and it makes no sense to compare it to itself */
404 static BOOL test_EnumPrintProcessors(struct test_spoolss_context *ctx)
407 struct spoolss_EnumPrintProcessors r;
408 uint16_t levels[] = { 1 };
412 for (i=0;i<ARRAY_SIZE(levels);i++) {
413 int level = levels[i];
415 uint32_t buf_size = 0;
417 r.in.servername = "";
418 r.in.environment = "Windows NT x86";
422 r.in.buf_size = &buf_size;
423 r.out.buf_size = &buf_size;
425 printf("Testing EnumPrintProcessors level %u\n", r.in.level);
427 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
428 if (!NT_STATUS_IS_OK(status)) {
429 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
434 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
435 printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
436 win_errstr(r.out.result));
441 blob = data_blob_talloc(ctx, NULL, buf_size);
442 data_blob_clear(&blob);
445 status = dcerpc_spoolss_EnumPrintProcessors(ctx->p, ctx, &r);
446 if (!NT_STATUS_IS_OK(status)) {
447 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status));
452 if (!W_ERROR_IS_OK(r.out.result)) {
453 printf("EnumPrintProcessors failed - %s\n",
454 win_errstr(r.out.result));
459 ctx->print_processor_count[level] = r.out.count;
460 ctx->print_processors[level] = r.out.info;
463 for (i=1;i<ARRAY_SIZE(levels);i++) {
464 int level = levels[i];
465 int old_level = levels[i-1];
466 if (ctx->print_processor_count[level] != ctx->print_processor_count[old_level]) {
467 printf("EnumPrintProcessors level[%d] returns [%u] print_processors, but level[%d] returns [%u]\n",
468 level, ctx->print_processor_count[level], old_level, ctx->print_processor_count[old_level]);
472 /* if the array sizes are not the same we would maybe segfault in the following code */
473 if (!ret) return ret;
475 for (i=0;i<ARRAY_SIZE(levels);i++) {
476 int level = levels[i];
477 for (j=0;j<ctx->print_processor_count[level];j++) {
479 union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][0][j];
480 union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][0][j];
484 /* level 1 is our reference, and it makes no sense to compare it to itself */
493 static BOOL test_EnumPrinters(struct test_spoolss_context *ctx)
495 struct spoolss_EnumPrinters r;
497 uint16_t levels[] = { 0, 1, 2, 4, 5 };
501 for (i=0;i<ARRAY_SIZE(levels);i++) {
502 int level = levels[i];
504 uint32_t buf_size = 0;
506 r.in.flags = PRINTER_ENUM_LOCAL;
510 r.in.buf_size = &buf_size;
511 r.out.buf_size = &buf_size;
513 printf("\nTesting EnumPrinters level %u\n", r.in.level);
515 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
516 if (!NT_STATUS_IS_OK(status)) {
517 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
522 if (!W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
523 printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
524 win_errstr(r.out.result));
529 blob = data_blob_talloc(ctx, NULL, buf_size);
530 data_blob_clear(&blob);
532 status = dcerpc_spoolss_EnumPrinters(ctx->p, ctx, &r);
533 if (!NT_STATUS_IS_OK(status)) {
534 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status));
539 if (!W_ERROR_IS_OK(r.out.result)) {
540 printf("EnumPrinters failed - %s\n",
541 win_errstr(r.out.result));
545 ctx->printer_count[level] = r.out.count;
546 ctx->printers[level] = r.out.info;
549 for (i=1;i<ARRAY_SIZE(levels);i++) {
550 int level = levels[i];
551 int old_level = levels[i-1];
552 if (ctx->printer_count[level] != ctx->printer_count[old_level]) {
553 printf("EnumPrinters level[%d] returns [%u] printers, but level[%d] returns [%u]\n",
554 level, ctx->printer_count[level], old_level, ctx->printer_count[old_level]);
558 /* if the array sizes are not the same we would maybe segfault in the following code */
559 if (!ret) return ret;
561 for (i=0;i<ARRAY_SIZE(levels);i++) {
562 int level = levels[i];
563 for (j=0;j<ctx->printer_count[level];j++) {
564 union spoolss_PrinterInfo *cur = &ctx->printers[level][0][j];
565 union spoolss_PrinterInfo *ref = &ctx->printers[2][0][j];
568 COMPARE_STRING(cur->info0, ref->info2, printername);
569 COMPARE_STRING(cur->info0, ref->info2, servername);
570 COMPARE_UINT32(cur->info0, ref->info2, cjobs);
571 /*COMPARE_UINT32(cur->info0, ref->info2, total_jobs);
572 COMPARE_UINT32(cur->info0, ref->info2, total_bytes);
573 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
574 COMPARE_UINT32(cur->info0, ref->info2, global_counter);
575 COMPARE_UINT32(cur->info0, ref->info2, total_pages);
576 COMPARE_UINT32(cur->info0, ref->info2, version);
577 COMPARE_UINT32(cur->info0, ref->info2, unknown10);
578 COMPARE_UINT32(cur->info0, ref->info2, unknown11);
579 COMPARE_UINT32(cur->info0, ref->info2, unknown12);
580 COMPARE_UINT32(cur->info0, ref->info2, session_counter);
581 COMPARE_UINT32(cur->info0, ref->info2, unknown14);
582 COMPARE_UINT32(cur->info0, ref->info2, printer_errors);
583 COMPARE_UINT32(cur->info0, ref->info2, unknown16);
584 COMPARE_UINT32(cur->info0, ref->info2, unknown17);
585 COMPARE_UINT32(cur->info0, ref->info2, unknown18);
586 COMPARE_UINT32(cur->info0, ref->info2, unknown19);
587 COMPARE_UINT32(cur->info0, ref->info2, change_id);
588 COMPARE_UINT32(cur->info0, ref->info2, unknown21);*/
589 COMPARE_UINT32(cur->info0, ref->info2, status);
590 /*COMPARE_UINT32(cur->info0, ref->info2, unknown23);
591 COMPARE_UINT32(cur->info0, ref->info2, c_setprinter);
592 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
593 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
594 COMPARE_UINT32(cur->info0, ref->info2, unknown27);
595 COMPARE_UINT32(cur->info0, ref->info2, unknown28);
596 COMPARE_UINT32(cur->info0, ref->info2, unknown29);*/
599 /*COMPARE_UINT32(cur->info1, ref->info2, flags);*/
600 /*COMPARE_STRING(cur->info1, ref->info2, name);*/
601 /*COMPARE_STRING(cur->info1, ref->info2, description);*/
602 COMPARE_STRING(cur->info1, ref->info2, comment);
605 /* level 2 is our reference, and it makes no sense to compare it to itself */
608 COMPARE_STRING(cur->info4, ref->info2, printername);
609 COMPARE_STRING(cur->info4, ref->info2, servername);
610 COMPARE_UINT32(cur->info4, ref->info2, attributes);
613 COMPARE_STRING(cur->info5, ref->info2, printername);
614 COMPARE_STRING(cur->info5, ref->info2, portname);
615 COMPARE_UINT32(cur->info5, ref->info2, attributes);
616 /*COMPARE_UINT32(cur->info5, ref->info2, device_not_selected_timeout);
617 COMPARE_UINT32(cur->info5, ref->info2, transmission_retry_timeout);*/
624 * - verify that the port of a printer was in the list returned by EnumPorts
630 static BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
631 struct policy_handle *handle)
634 struct spoolss_GetPrinter r;
635 uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
639 for (i=0;i<ARRAY_SIZE(levels);i++) {
640 uint32_t buf_size = 0;
641 r.in.handle = handle;
642 r.in.level = levels[i];
644 r.in.buf_size = &buf_size;
645 r.out.buf_size = &buf_size;
647 printf("Testing GetPrinter level %u\n", r.in.level);
649 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
650 if (!NT_STATUS_IS_OK(status)) {
651 printf("GetPrinter failed - %s\n", nt_errstr(status));
656 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
657 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
658 data_blob_clear(&blob);
660 status = dcerpc_spoolss_GetPrinter(p, mem_ctx, &r);
663 if (!NT_STATUS_IS_OK(status)) {
664 printf("GetPrinter failed - %s\n", nt_errstr(status));
669 if (!W_ERROR_IS_OK(r.out.result)) {
670 printf("GetPrinter failed - %s\n",
671 win_errstr(r.out.result));
681 static BOOL test_ClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
682 struct policy_handle *handle)
685 struct spoolss_ClosePrinter r;
687 r.in.handle = handle;
688 r.out.handle = handle;
690 printf("Testing ClosePrinter\n");
692 status = dcerpc_spoolss_ClosePrinter(p, mem_ctx, &r);
693 if (!NT_STATUS_IS_OK(status)) {
694 printf("ClosePrinter failed - %s\n", nt_errstr(status));
701 static BOOL test_GetForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
702 struct policy_handle *handle,
703 const char *formname)
706 struct spoolss_GetForm r;
709 r.in.handle = handle;
710 r.in.formname = formname;
714 r.in.buf_size = r.out.buf_size = &buf_size;
716 printf("Testing GetForm\n");
718 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
720 if (!NT_STATUS_IS_OK(status)) {
721 printf("GetForm failed - %s\n", nt_errstr(status));
725 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
726 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
728 data_blob_clear(&blob);
731 status = dcerpc_spoolss_GetForm(p, mem_ctx, &r);
734 printf("No form info returned");
742 static BOOL test_EnumForms(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
743 struct policy_handle *handle)
746 struct spoolss_EnumForms r;
749 r.in.handle = handle;
753 r.in.buf_size = &buf_size;
754 r.out.buf_size = &buf_size;
756 printf("Testing EnumForms\n");
758 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
760 if (!NT_STATUS_IS_OK(status)) {
761 printf("EnumForms failed - %s\n", nt_errstr(status));
765 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
766 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
767 union spoolss_FormInfo *info;
770 data_blob_clear(&blob);
773 status = dcerpc_spoolss_EnumForms(p, mem_ctx, &r);
776 printf("No forms returned");
782 for (j = 0; j < r.out.count; j++) {
783 test_GetForm(p, mem_ctx, handle, info[j].info1.formname);
787 if (!NT_STATUS_IS_OK(status)) {
788 printf("EnumForms failed - %s\n", nt_errstr(status));
792 if (!W_ERROR_IS_OK(r.out.result)) {
793 printf("EnumForms failed - %s\n", win_errstr(r.out.result));
800 static BOOL test_DeleteForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
801 struct policy_handle *handle,
802 const char *formname)
805 struct spoolss_DeleteForm r;
807 r.in.handle = handle;
808 r.in.formname = formname;
810 status = dcerpc_spoolss_DeleteForm(p, mem_ctx, &r);
812 if (!NT_STATUS_IS_OK(status)) {
813 printf("DeleteForm failed - %s\n", nt_errstr(status));
817 if (!W_ERROR_IS_OK(r.out.result)) {
818 printf("DeleteForm failed - %s\n", win_errstr(r.out.result));
825 static BOOL test_AddForm(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
826 struct policy_handle *handle)
828 struct spoolss_AddForm r;
829 struct spoolss_AddFormInfo1 form;
831 const char *formname = "testform3";
834 r.in.handle = handle;
836 form.flags = 2; /* User form */
837 form.formname = formname;
844 r.in.info.info1 = &form;
846 status = dcerpc_spoolss_AddForm(p, mem_ctx, &r);
848 if (!NT_STATUS_IS_OK(status)) {
849 printf("AddForm failed - %s\n", nt_errstr(status));
853 if (!W_ERROR_IS_OK(r.out.result)) {
854 printf("AddForm failed - %s\n", nt_errstr(status));
859 struct spoolss_SetForm sf;
861 sf.in.handle = handle;
862 sf.in.formname = formname;
864 sf.in.info.info1 = &form;
867 status = dcerpc_spoolss_SetForm(p, mem_ctx, &sf);
869 if (!NT_STATUS_IS_OK(status)) {
870 printf("SetForm failed - %s\n", nt_errstr(status));
875 if (!W_ERROR_IS_OK(r.out.result)) {
876 printf("SetForm failed - %s\n",
877 win_errstr(r.out.result));
884 if (!test_DeleteForm(p, mem_ctx, handle, formname)) {
885 printf("DeleteForm failed\n");
892 static BOOL test_EnumPorts_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
895 struct spoolss_EnumPorts r;
898 r.in.servername = talloc_asprintf(mem_ctx, "\\\\%s",
899 dcerpc_server_name(p));
903 r.in.buf_size = &buf_size;
904 r.out.buf_size = &buf_size;
906 printf("Testing EnumPorts\n");
908 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
910 if (!NT_STATUS_IS_OK(status)) {
911 printf("EnumPorts failed - %s\n", nt_errstr(status));
915 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
916 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
918 data_blob_clear(&blob);
921 status = dcerpc_spoolss_EnumPorts(p, mem_ctx, &r);
923 if (!NT_STATUS_IS_OK(status)) {
924 printf("EnumPorts failed - %s\n", nt_errstr(status));
929 printf("No ports returned");
937 static BOOL test_AddPort(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
940 struct spoolss_AddPort r;
942 r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s",
943 dcerpc_server_name(p));
945 r.in.monitor_name = "foo";
947 printf ("Testing AddPort\n");
949 status = dcerpc_spoolss_AddPort(p, mem_ctx, &r);
951 if (!NT_STATUS_IS_OK(status)) {
952 printf("AddPort failed - %s\n", nt_errstr(status));
956 /* win2k3 returns WERR_NOT_SUPPORTED */
960 if (!W_ERROR_IS_OK(r.out.result)) {
961 printf("AddPort failed - %s\n", win_errstr(r.out.result));
970 static BOOL test_GetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
971 struct policy_handle *handle, uint32_t job_id)
974 struct spoolss_GetJob r;
977 r.in.handle = handle;
978 r.in.job_id = job_id;
982 r.in.buf_size = r.out.buf_size = &buf_size;
984 printf("Testing GetJob\n");
986 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
988 if (!NT_STATUS_IS_OK(status)) {
989 printf("GetJob failed - %s\n", nt_errstr(status));
993 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
994 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
996 data_blob_clear(&blob);
999 status = dcerpc_spoolss_GetJob(p, mem_ctx, &r);
1002 printf("No job info returned");
1010 static BOOL test_SetJob(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1011 struct policy_handle *handle, uint32_t job_id, uint32_t command)
1014 struct spoolss_SetJob r;
1016 r.in.handle = handle;
1017 r.in.job_id = job_id;
1019 r.in.command = command;
1021 printf("Testing SetJob\n");
1023 status = dcerpc_spoolss_SetJob(p, mem_ctx, &r);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 printf("SetJob failed - %s\n", nt_errstr(status));
1033 static BOOL test_EnumJobs(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1034 struct policy_handle *handle)
1037 struct spoolss_EnumJobs r;
1040 r.in.handle = handle;
1042 r.in.numjobs = 0xffffffff;
1046 r.in.buf_size = &buf_size;
1047 r.out.buf_size = &buf_size;
1049 printf("Testing EnumJobs\n");
1051 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 printf("EnumJobs failed - %s\n", nt_errstr(status));
1058 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1059 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
1060 union spoolss_JobInfo *info;
1063 data_blob_clear(&blob);
1064 r.in.buffer = &blob;
1066 status = dcerpc_spoolss_EnumJobs(p, mem_ctx, &r);
1069 printf("No jobs returned");
1075 for (j = 0; j < r.out.count; j++) {
1076 test_GetJob(p, mem_ctx, handle, info[j].info1.job_id);
1077 test_SetJob(p, mem_ctx, handle, info[j].info1.job_id, 1);
1080 } else if (!W_ERROR_IS_OK(r.out.result)) {
1081 printf("EnumJobs failed - %s\n", win_errstr(r.out.result));
1088 static BOOL test_GetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1089 struct policy_handle *handle,
1090 const char *value_name)
1093 struct spoolss_GetPrinterData r;
1096 r.in.handle = handle;
1097 r.in.value_name = value_name;
1099 r.in.buf_size = r.out.buf_size = &buf_size;
1101 printf("Testing GetPrinterData\n");
1103 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1105 if (!NT_STATUS_IS_OK(status)) {
1106 printf("GetPrinterData failed - %s\n", nt_errstr(status));
1110 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1112 status = dcerpc_spoolss_GetPrinterData(p, mem_ctx, &r);
1114 if (!NT_STATUS_IS_OK(status)) {
1115 printf("GetPrinterData failed - %s\n",
1120 if (!W_ERROR_IS_OK(r.out.result)) {
1121 printf("GetPrinterData failed - %s\n",
1122 win_errstr(r.out.result));
1130 static BOOL test_GetPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1131 struct policy_handle *handle,
1132 const char *key_name,
1133 const char *value_name)
1136 struct spoolss_GetPrinterDataEx r;
1139 r.in.handle = handle;
1140 r.in.key_name = key_name;
1141 r.in.value_name = value_name;
1143 r.in.buf_size = r.out.buf_size = &buf_size;
1145 printf("Testing GetPrinterDataEx\n");
1147 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1148 if (!NT_STATUS_IS_OK(status)) {
1149 if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
1150 p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1151 printf("GetPrinterDataEx not supported by server\n");
1154 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status));
1158 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1160 status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
1162 if (!NT_STATUS_IS_OK(status)) {
1163 printf("GetPrinterDataEx failed - %s\n",
1168 if (!W_ERROR_IS_OK(r.out.result)) {
1169 printf("GetPrinterDataEx failed - %s\n",
1170 win_errstr(r.out.result));
1178 static BOOL test_EnumPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1179 struct policy_handle *handle)
1182 struct spoolss_EnumPrinterData r;
1184 r.in.handle = handle;
1185 r.in.enum_index = 0;
1190 r.in.value_offered = 0;
1192 r.in.data_size = &data_size;
1193 r.out.data_size = &data_size;
1195 printf("Testing EnumPrinterData\n");
1197 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1199 if (!NT_STATUS_IS_OK(status)) {
1200 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1204 r.in.value_offered = r.out.value_needed;
1206 status = dcerpc_spoolss_EnumPrinterData(p, mem_ctx, &r);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 printf("EnumPrinterData failed - %s\n", nt_errstr(status));
1213 test_GetPrinterData(p, mem_ctx, handle, r.out.value_name);
1215 test_GetPrinterDataEx(
1216 p, mem_ctx, handle, "PrinterDriverData",
1221 } while (W_ERROR_IS_OK(r.out.result));
1226 static BOOL test_EnumPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1227 struct policy_handle *handle)
1230 struct spoolss_EnumPrinterDataEx r;
1232 r.in.handle = handle;
1233 r.in.key_name = "PrinterDriverData";
1236 printf("Testing EnumPrinterDataEx\n");
1238 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1245 r.in.buf_size = r.out.buf_size;
1247 status = dcerpc_spoolss_EnumPrinterDataEx(p, mem_ctx, &r);
1249 if (!NT_STATUS_IS_OK(status)) {
1250 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status));
1258 static BOOL test_DeletePrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1259 struct policy_handle *handle,
1260 const char *value_name)
1263 struct spoolss_DeletePrinterData r;
1265 r.in.handle = handle;
1266 r.in.value_name = value_name;
1268 printf("Testing DeletePrinterData\n");
1270 status = dcerpc_spoolss_DeletePrinterData(p, mem_ctx, &r);
1272 if (!NT_STATUS_IS_OK(status)) {
1273 printf("DeletePrinterData failed - %s\n", nt_errstr(status));
1280 static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1281 struct policy_handle *handle)
1284 struct spoolss_SetPrinterData r;
1285 const char *value_name = "spottyfoot";
1287 r.in.handle = handle;
1288 r.in.value_name = value_name;
1290 r.in.buffer = data_blob_talloc(mem_ctx, "dog", 4);
1293 printf("Testing SetPrinterData\n");
1295 status = dcerpc_spoolss_SetPrinterData(p, mem_ctx, &r);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 printf("SetPrinterData failed - %s\n", nt_errstr(status));
1302 if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) {
1309 static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1310 struct policy_handle *handle)
1313 struct dcerpc_binding *b;
1314 struct dcerpc_pipe *p2;
1317 /* only makes sense on SMB */
1318 if (p->conn->transport.transport != NCACN_NP) {
1322 printf("testing close on secondary pipe\n");
1324 status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
1325 if (!NT_STATUS_IS_OK(status)) {
1326 printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
1330 status = dcerpc_secondary_connection(p, &p2, b);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 printf("Failed to create secondary connection\n");
1336 status = dcerpc_bind_auth_none(p2, DCERPC_SPOOLSS_UUID,
1337 DCERPC_SPOOLSS_VERSION);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 printf("Failed to create bind on secondary connection\n");
1345 if (test_ClosePrinter(p2, mem_ctx, handle)) {
1346 printf("ERROR: Allowed close on secondary connection!\n");
1350 if (p2->last_fault_code != DCERPC_FAULT_CONTEXT_MISMATCH) {
1351 printf("Unexpected fault code 0x%x - expected 0x%x\n",
1352 p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH);
1361 static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
1364 struct spoolss_OpenPrinter op;
1365 struct spoolss_OpenPrinterEx opEx;
1366 struct policy_handle handle;
1369 op.in.printername = name;
1370 op.in.datatype = NULL;
1371 op.in.devmode_ctr.size = 0;
1372 op.in.devmode_ctr.devmode= NULL;
1373 op.in.access_mask = 0;
1374 op.out.handle = &handle;
1376 printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
1378 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
1379 if (!NT_STATUS_IS_OK(status)) {
1380 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1383 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
1384 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1385 name, win_errstr(op.out.result));
1388 if (W_ERROR_IS_OK(op.out.result)) {
1389 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1392 opEx.in.printername = name;
1393 opEx.in.datatype = NULL;
1394 opEx.in.devmode_ctr.size = 0;
1395 opEx.in.devmode_ctr.devmode = NULL;
1396 opEx.in.access_mask = 0;
1398 opEx.in.userlevel.level1 = NULL;
1399 opEx.out.handle = &handle;
1401 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
1403 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
1404 if (!NT_STATUS_IS_OK(status)) {
1405 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1408 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
1409 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1410 name, win_errstr(opEx.out.result));
1413 if (W_ERROR_IS_OK(opEx.out.result)) {
1414 ret &=test_ClosePrinter(p, mem_ctx, &handle);
1420 static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1425 ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
1426 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
1427 ret &= test_OpenPrinter_badname(p, mem_ctx, "");
1428 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
1429 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
1431 name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
1432 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1435 name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
1436 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
1442 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1446 struct spoolss_OpenPrinter r;
1447 struct policy_handle handle;
1450 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
1451 r.in.datatype = NULL;
1452 r.in.devmode_ctr.size = 0;
1453 r.in.devmode_ctr.devmode= NULL;
1454 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1455 r.out.handle = &handle;
1457 printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
1459 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 printf("OpenPrinter failed - %s\n", nt_errstr(status));
1466 if (!W_ERROR_IS_OK(r.out.result)) {
1467 printf("OpenPrinter failed - %s\n", win_errstr(r.out.result));
1471 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1475 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1479 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1486 static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1487 const char *name, struct policy_handle *handle)
1489 struct spoolss_OpenPrinterEx r;
1490 struct spoolss_UserLevel1 userlevel1;
1493 if (name && name[0]) {
1494 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
1495 dcerpc_server_name(p), name);
1497 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
1498 dcerpc_server_name(p));
1501 r.in.datatype = NULL;
1502 r.in.devmode_ctr.size = 0;
1503 r.in.devmode_ctr.devmode= NULL;
1504 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1506 r.in.userlevel.level1 = &userlevel1;
1507 r.out.handle = handle;
1509 userlevel1.size = 1234;
1510 userlevel1.client = "hello";
1511 userlevel1.user = "spottyfoot!";
1512 userlevel1.build = 1;
1513 userlevel1.major = 2;
1514 userlevel1.minor = 3;
1515 userlevel1.processor = 4;
1517 printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
1519 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
1521 if (!NT_STATUS_IS_OK(status)) {
1522 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
1526 if (!W_ERROR_IS_OK(r.out.result)) {
1527 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
1534 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1537 struct policy_handle handle;
1540 if (!call_OpenPrinterEx(p, mem_ctx, name, &handle)) {
1544 if (!test_GetPrinter(p, mem_ctx, &handle)) {
1548 if (!test_EnumForms(p, mem_ctx, &handle)) {
1552 if (!test_AddForm(p, mem_ctx, &handle)) {
1556 if (!test_EnumPrinterData(p, mem_ctx, &handle)) {
1560 if (!test_EnumPrinterDataEx(p, mem_ctx, &handle)) {
1564 if (!test_EnumJobs(p, mem_ctx, &handle)) {
1568 if (!test_SetPrinterData(p, mem_ctx, &handle)) {
1572 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
1576 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
1583 static BOOL test_EnumPrinters_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1585 struct spoolss_EnumPrinters r;
1587 uint16_t levels[] = {1, 2, 4, 5};
1591 for (i=0;i<ARRAY_SIZE(levels);i++) {
1592 uint32_t buf_size = 0;
1593 union spoolss_PrinterInfo *info;
1596 r.in.flags = PRINTER_ENUM_LOCAL;
1598 r.in.level = levels[i];
1600 r.in.buf_size = &buf_size;
1601 r.out.buf_size = &buf_size;
1603 printf("\nTesting EnumPrinters level %u\n", r.in.level);
1605 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1606 if (!NT_STATUS_IS_OK(status)) {
1607 printf("EnumPrinters failed - %s\n", nt_errstr(status));
1612 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1613 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
1614 data_blob_clear(&blob);
1615 r.in.buffer = &blob;
1616 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
1619 if (!NT_STATUS_IS_OK(status)) {
1620 printf("EnumPrinters failed - %s\n",
1625 if (!W_ERROR_IS_OK(r.out.result)) {
1626 printf("EnumPrinters failed - %s\n",
1627 win_errstr(r.out.result));
1632 printf("No printers returned");
1638 for (j=0;j<r.out.count;j++) {
1639 if (r.in.level == 1) {
1640 /* the names appear to be comma-separated name lists? */
1641 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
1642 char *comma = strchr(name, ',');
1643 if (comma) *comma = 0;
1644 if (!test_OpenPrinter(p, mem_ctx, name)) {
1647 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
1658 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1659 struct policy_handle *handle,
1660 const char *driver_name)
1663 struct spoolss_GetPrinterDriver2 r;
1666 r.in.handle = handle;
1667 r.in.architecture = "W32X86";
1671 r.in.buf_size = r.out.buf_size = &buf_size;
1672 r.in.client_major_version = 0;
1673 r.in.client_minor_version = 0;
1675 printf("Testing GetPrinterDriver2\n");
1677 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1679 if (!NT_STATUS_IS_OK(status)) {
1680 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1684 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1685 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1688 if (!NT_STATUS_IS_OK(status)) {
1689 printf("GetPrinterDriver2 failed - %s\n",
1694 if (!W_ERROR_IS_OK(r.out.result)) {
1695 printf("GetPrinterDriver2 failed - %s\n",
1696 win_errstr(r.out.result));
1704 static BOOL test_EnumPrinterDrivers_old(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1706 struct spoolss_EnumPrinterDrivers r;
1708 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
1712 for (i=0;i<ARRAY_SIZE(levels);i++) {
1715 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1716 r.in.environment = "Windows NT x86";
1717 r.in.level = levels[i];
1720 r.in.buf_size = &buf_size;
1721 r.out.buf_size = &buf_size;
1723 printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
1725 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
1727 if (!NT_STATUS_IS_OK(status)) {
1728 printf("EnumPrinterDrivers failed - %s\n",
1734 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1735 DATA_BLOB blob = data_blob_talloc(
1736 mem_ctx, NULL, buf_size);
1738 data_blob_clear(&blob);
1739 r.in.buffer = &blob;
1740 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
1743 if (!NT_STATUS_IS_OK(status)) {
1744 printf("EnumPrinterDrivers failed - %s\n",
1750 if (!W_ERROR_IS_OK(r.out.result)) {
1751 printf("EnumPrinterDrivers failed - %s\n",
1752 win_errstr(r.out.result));
1758 printf("No printer drivers returned");
1766 BOOL torture_rpc_spoolss(void)
1769 struct dcerpc_pipe *p;
1770 TALLOC_CTX *mem_ctx;
1772 struct test_spoolss_context *ctx;
1774 mem_ctx = talloc_init("torture_rpc_spoolss");
1776 status = torture_rpc_connection(mem_ctx,
1778 DCERPC_SPOOLSS_NAME,
1779 DCERPC_SPOOLSS_UUID,
1780 DCERPC_SPOOLSS_VERSION);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 talloc_free(mem_ctx);
1786 ctx = talloc_zero(mem_ctx, struct test_spoolss_context);
1789 ret &= test_EnumPorts(ctx);
1791 ret &= test_EnumPrinterDrivers(ctx);
1793 ret &= test_EnumMonitors(ctx);
1795 ret &= test_EnumPrintProcessors(ctx);
1797 ret &= test_EnumPrinters(ctx);
1799 ret &= test_OpenPrinter_badnames(p, mem_ctx);
1801 ret &= test_AddPort(p, mem_ctx);
1803 ret &= test_EnumPorts_old(p, mem_ctx);
1805 ret &= test_EnumPrinters_old(p, mem_ctx);
1807 ret &= test_EnumPrinterDrivers_old(p, mem_ctx);
1809 talloc_free(mem_ctx);