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
));
153 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
154 printf("EnumPorts unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
155 win_errstr(r
.out
.result
));
160 blob
= data_blob_talloc(ctx
, NULL
, buf_size
);
161 data_blob_clear(&blob
);
164 status
= dcerpc_spoolss_EnumPorts(ctx
->p
, ctx
, &r
);
165 if (!NT_STATUS_IS_OK(status
)) {
166 printf("dcerpc_spoolss_EnumPorts failed - %s\n", nt_errstr(status
));
171 if (!W_ERROR_IS_OK(r
.out
.result
)) {
172 printf("EnumPorts failed - %s\n",
173 win_errstr(r
.out
.result
));
178 ctx
->port_count
[level
] = r
.out
.count
;
179 ctx
->ports
[level
] = r
.out
.info
;
182 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
183 int level
= levels
[i
];
184 int old_level
= levels
[i
-1];
185 if (ctx
->port_count
[level
] != ctx
->port_count
[old_level
]) {
186 printf("EnumPorts level[%d] returns [%u] ports, but level[%d] returns [%u]\n",
187 level
, ctx
->port_count
[level
], old_level
, ctx
->port_count
[old_level
]);
191 /* if the array sizes are not the same we would maybe segfault in the following code */
192 if (!ret
) return ret
;
194 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
195 int level
= levels
[i
];
196 for (j
=0;j
<ctx
->port_count
[level
];j
++) {
197 union spoolss_PortInfo
*cur
= &ctx
->ports
[level
][0][j
];
198 union spoolss_PortInfo
*ref
= &ctx
->ports
[2][0][j
];
201 COMPARE_STRING(cur
->info1
, ref
->info2
, port_name
);
204 /* level 2 is our reference, and it makes no sense to compare it to itself */
213 static BOOL
test_EnumPrinterDrivers(struct test_spoolss_context
*ctx
)
216 struct spoolss_EnumPrinterDrivers r
;
217 uint16_t levels
[] = { 1, 2, 3, 4, 5, 6 };
221 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
222 int level
= levels
[i
];
224 uint32_t buf_size
= 0;
227 r
.in
.environment
= "Windows NT x86";
231 r
.in
.buf_size
= &buf_size
;
232 r
.out
.buf_size
= &buf_size
;
234 printf("Testing EnumPrinterDrivers level %u\n", r
.in
.level
);
236 status
= dcerpc_spoolss_EnumPrinterDrivers(ctx
->p
, ctx
, &r
);
237 if (!NT_STATUS_IS_OK(status
)) {
238 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status
));
243 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
244 printf("EnumPrinterDrivers unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
245 win_errstr(r
.out
.result
));
250 blob
= data_blob_talloc(ctx
, NULL
, buf_size
);
251 data_blob_clear(&blob
);
254 status
= dcerpc_spoolss_EnumPrinterDrivers(ctx
->p
, ctx
, &r
);
255 if (!NT_STATUS_IS_OK(status
)) {
256 printf("dcerpc_spoolss_EnumPrinterDrivers failed - %s\n", nt_errstr(status
));
261 if (!W_ERROR_IS_OK(r
.out
.result
)) {
262 printf("EnumPrinterDrivers failed - %s\n",
263 win_errstr(r
.out
.result
));
268 ctx
->driver_count
[level
] = r
.out
.count
;
269 ctx
->drivers
[level
] = r
.out
.info
;
272 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
273 int level
= levels
[i
];
274 int old_level
= levels
[i
-1];
275 if (ctx
->driver_count
[level
] != ctx
->driver_count
[old_level
]) {
276 printf("EnumPrinterDrivers level[%d] returns [%u] drivers, but level[%d] returns [%u]\n",
277 level
, ctx
->driver_count
[level
], old_level
, ctx
->driver_count
[old_level
]);
281 /* if the array sizes are not the same we would maybe segfault in the following code */
282 if (!ret
) return ret
;
284 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
285 int level
= levels
[i
];
286 for (j
=0;j
<ctx
->driver_count
[level
];j
++) {
287 union spoolss_DriverInfo
*cur
= &ctx
->drivers
[level
][0][j
];
288 union spoolss_DriverInfo
*ref
= &ctx
->drivers
[6][0][j
];
291 COMPARE_STRING(cur
->info1
, ref
->info6
, driver_name
);
294 COMPARE_UINT32(cur
->info2
, ref
->info6
, version
);
295 COMPARE_STRING(cur
->info2
, ref
->info6
, driver_name
);
296 COMPARE_STRING(cur
->info2
, ref
->info6
, architecture
);
297 COMPARE_STRING(cur
->info2
, ref
->info6
, driver_path
);
298 COMPARE_STRING(cur
->info2
, ref
->info6
, data_file
);
299 COMPARE_STRING(cur
->info2
, ref
->info6
, config_file
);
302 COMPARE_UINT32(cur
->info3
, ref
->info6
, version
);
303 COMPARE_STRING(cur
->info3
, ref
->info6
, driver_name
);
304 COMPARE_STRING(cur
->info3
, ref
->info6
, architecture
);
305 COMPARE_STRING(cur
->info3
, ref
->info6
, driver_path
);
306 COMPARE_STRING(cur
->info3
, ref
->info6
, data_file
);
307 COMPARE_STRING(cur
->info3
, ref
->info6
, config_file
);
308 COMPARE_STRING(cur
->info3
, ref
->info6
, help_file
);
309 COMPARE_STRING_ARRAY(cur
->info3
, ref
->info6
, dependent_files
);
310 COMPARE_STRING(cur
->info3
, ref
->info6
, monitor_name
);
311 COMPARE_STRING(cur
->info3
, ref
->info6
, default_datatype
);
314 COMPARE_UINT32(cur
->info4
, ref
->info6
, version
);
315 COMPARE_STRING(cur
->info4
, ref
->info6
, driver_name
);
316 COMPARE_STRING(cur
->info4
, ref
->info6
, architecture
);
317 COMPARE_STRING(cur
->info4
, ref
->info6
, driver_path
);
318 COMPARE_STRING(cur
->info4
, ref
->info6
, data_file
);
319 COMPARE_STRING(cur
->info4
, ref
->info6
, config_file
);
320 COMPARE_STRING(cur
->info4
, ref
->info6
, help_file
);
321 COMPARE_STRING_ARRAY(cur
->info4
, ref
->info6
, dependent_files
);
322 COMPARE_STRING(cur
->info4
, ref
->info6
, monitor_name
);
323 COMPARE_STRING(cur
->info4
, ref
->info6
, default_datatype
);
324 COMPARE_STRING_ARRAY(cur
->info4
, ref
->info6
, previous_names
);
327 COMPARE_UINT32(cur
->info5
, ref
->info6
, version
);
328 COMPARE_STRING(cur
->info5
, ref
->info6
, driver_name
);
329 COMPARE_STRING(cur
->info5
, ref
->info6
, architecture
);
330 COMPARE_STRING(cur
->info5
, ref
->info6
, driver_path
);
331 COMPARE_STRING(cur
->info5
, ref
->info6
, data_file
);
332 COMPARE_STRING(cur
->info5
, ref
->info6
, config_file
);
333 /*COMPARE_UINT32(cur->info5, ref->info6, driver_attributes);*/
334 /*COMPARE_UINT32(cur->info5, ref->info6, config_version);*/
335 /*TODO: ! COMPARE_UINT32(cur->info5, ref->info6, driver_version); */
338 /* level 6 is our reference, and it makes no sense to compare it to itself */
347 static BOOL
test_EnumMonitors(struct test_spoolss_context
*ctx
)
350 struct spoolss_EnumMonitors r
;
351 uint16_t levels
[] = { 1, 2 };
355 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
356 int level
= levels
[i
];
358 uint32_t buf_size
= 0;
360 r
.in
.servername
= "";
364 r
.in
.buf_size
= &buf_size
;
365 r
.out
.buf_size
= &buf_size
;
367 printf("Testing EnumMonitors level %u\n", r
.in
.level
);
369 status
= dcerpc_spoolss_EnumMonitors(ctx
->p
, ctx
, &r
);
370 if (!NT_STATUS_IS_OK(status
)) {
371 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status
));
376 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
377 printf("EnumMonitors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
378 win_errstr(r
.out
.result
));
383 blob
= data_blob_talloc(ctx
, NULL
, buf_size
);
384 data_blob_clear(&blob
);
387 status
= dcerpc_spoolss_EnumMonitors(ctx
->p
, ctx
, &r
);
388 if (!NT_STATUS_IS_OK(status
)) {
389 printf("dcerpc_spoolss_EnumMonitors failed - %s\n", nt_errstr(status
));
394 if (!W_ERROR_IS_OK(r
.out
.result
)) {
395 printf("EnumMonitors failed - %s\n",
396 win_errstr(r
.out
.result
));
401 ctx
->monitor_count
[level
] = r
.out
.count
;
402 ctx
->monitors
[level
] = r
.out
.info
;
405 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
406 int level
= levels
[i
];
407 int old_level
= levels
[i
-1];
408 if (ctx
->monitor_count
[level
] != ctx
->monitor_count
[old_level
]) {
409 printf("EnumMonitors level[%d] returns [%u] monitors, but level[%d] returns [%u]\n",
410 level
, ctx
->monitor_count
[level
], old_level
, ctx
->monitor_count
[old_level
]);
414 /* if the array sizes are not the same we would maybe segfault in the following code */
415 if (!ret
) return ret
;
417 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
418 int level
= levels
[i
];
419 for (j
=0;j
<ctx
->monitor_count
[level
];j
++) {
420 union spoolss_MonitorInfo
*cur
= &ctx
->monitors
[level
][0][j
];
421 union spoolss_MonitorInfo
*ref
= &ctx
->monitors
[2][0][j
];
424 COMPARE_STRING(cur
->info1
, ref
->info2
, monitor_name
);
427 /* level 2 is our reference, and it makes no sense to compare it to itself */
436 static BOOL
test_EnumPrintProcessors(struct test_spoolss_context
*ctx
)
439 struct spoolss_EnumPrintProcessors r
;
440 uint16_t levels
[] = { 1 };
444 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
445 int level
= levels
[i
];
447 uint32_t buf_size
= 0;
449 r
.in
.servername
= "";
450 r
.in
.environment
= "Windows NT x86";
454 r
.in
.buf_size
= &buf_size
;
455 r
.out
.buf_size
= &buf_size
;
457 printf("Testing EnumPrintProcessors level %u\n", r
.in
.level
);
459 status
= dcerpc_spoolss_EnumPrintProcessors(ctx
->p
, ctx
, &r
);
460 if (!NT_STATUS_IS_OK(status
)) {
461 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status
));
466 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
467 printf("EnumPrintProcessors unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
468 win_errstr(r
.out
.result
));
473 blob
= data_blob_talloc(ctx
, NULL
, buf_size
);
474 data_blob_clear(&blob
);
477 status
= dcerpc_spoolss_EnumPrintProcessors(ctx
->p
, ctx
, &r
);
478 if (!NT_STATUS_IS_OK(status
)) {
479 printf("dcerpc_spoolss_EnumPrintProcessors failed - %s\n", nt_errstr(status
));
484 if (!W_ERROR_IS_OK(r
.out
.result
)) {
485 printf("EnumPrintProcessors failed - %s\n",
486 win_errstr(r
.out
.result
));
491 ctx
->print_processor_count
[level
] = r
.out
.count
;
492 ctx
->print_processors
[level
] = r
.out
.info
;
495 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
496 int level
= levels
[i
];
497 int old_level
= levels
[i
-1];
498 if (ctx
->print_processor_count
[level
] != ctx
->print_processor_count
[old_level
]) {
499 printf("EnumPrintProcessors level[%d] returns [%u] print_processors, but level[%d] returns [%u]\n",
500 level
, ctx
->print_processor_count
[level
], old_level
, ctx
->print_processor_count
[old_level
]);
504 /* if the array sizes are not the same we would maybe segfault in the following code */
505 if (!ret
) return ret
;
507 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
508 int level
= levels
[i
];
509 for (j
=0;j
<ctx
->print_processor_count
[level
];j
++) {
511 union spoolss_PrintProcessorInfo
*cur
= &ctx
->print_processors
[level
][0][j
];
512 union spoolss_PrintProcessorInfo
*ref
= &ctx
->print_processors
[1][0][j
];
516 /* level 1 is our reference, and it makes no sense to compare it to itself */
525 static BOOL
test_EnumPrinters(struct test_spoolss_context
*ctx
)
527 struct spoolss_EnumPrinters r
;
529 uint16_t levels
[] = { 0, 1, 2, 4, 5 };
533 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
534 int level
= levels
[i
];
536 uint32_t buf_size
= 0;
538 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
542 r
.in
.buf_size
= &buf_size
;
543 r
.out
.buf_size
= &buf_size
;
545 printf("\nTesting EnumPrinters level %u\n", r
.in
.level
);
547 status
= dcerpc_spoolss_EnumPrinters(ctx
->p
, ctx
, &r
);
548 if (!NT_STATUS_IS_OK(status
)) {
549 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status
));
554 if (!W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
555 printf("EnumPrinters unexspected return code %s, should be WERR_INSUFFICIENT_BUFFER\n",
556 win_errstr(r
.out
.result
));
561 blob
= data_blob_talloc(ctx
, NULL
, buf_size
);
562 data_blob_clear(&blob
);
564 status
= dcerpc_spoolss_EnumPrinters(ctx
->p
, ctx
, &r
);
565 if (!NT_STATUS_IS_OK(status
)) {
566 printf("dcerpc_spoolss_EnumPrinters failed - %s\n", nt_errstr(status
));
571 if (!W_ERROR_IS_OK(r
.out
.result
)) {
572 printf("EnumPrinters failed - %s\n",
573 win_errstr(r
.out
.result
));
577 ctx
->printer_count
[level
] = r
.out
.count
;
578 ctx
->printers
[level
] = r
.out
.info
;
581 for (i
=1;i
<ARRAY_SIZE(levels
);i
++) {
582 int level
= levels
[i
];
583 int old_level
= levels
[i
-1];
584 if (ctx
->printer_count
[level
] != ctx
->printer_count
[old_level
]) {
585 printf("EnumPrinters level[%d] returns [%u] printers, but level[%d] returns [%u]\n",
586 level
, ctx
->printer_count
[level
], old_level
, ctx
->printer_count
[old_level
]);
590 /* if the array sizes are not the same we would maybe segfault in the following code */
591 if (!ret
) return ret
;
593 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
594 int level
= levels
[i
];
595 for (j
=0;j
<ctx
->printer_count
[level
];j
++) {
596 union spoolss_PrinterInfo
*cur
= &ctx
->printers
[level
][0][j
];
597 union spoolss_PrinterInfo
*ref
= &ctx
->printers
[2][0][j
];
600 COMPARE_STRING(cur
->info0
, ref
->info2
, printername
);
601 COMPARE_STRING(cur
->info0
, ref
->info2
, servername
);
602 COMPARE_UINT32(cur
->info0
, ref
->info2
, cjobs
);
603 /*COMPARE_UINT32(cur->info0, ref->info2, total_jobs);
604 COMPARE_UINT32(cur->info0, ref->info2, total_bytes);
605 COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time);
606 COMPARE_UINT32(cur->info0, ref->info2, global_counter);
607 COMPARE_UINT32(cur->info0, ref->info2, total_pages);
608 COMPARE_UINT32(cur->info0, ref->info2, version);
609 COMPARE_UINT32(cur->info0, ref->info2, unknown10);
610 COMPARE_UINT32(cur->info0, ref->info2, unknown11);
611 COMPARE_UINT32(cur->info0, ref->info2, unknown12);
612 COMPARE_UINT32(cur->info0, ref->info2, session_counter);
613 COMPARE_UINT32(cur->info0, ref->info2, unknown14);
614 COMPARE_UINT32(cur->info0, ref->info2, printer_errors);
615 COMPARE_UINT32(cur->info0, ref->info2, unknown16);
616 COMPARE_UINT32(cur->info0, ref->info2, unknown17);
617 COMPARE_UINT32(cur->info0, ref->info2, unknown18);
618 COMPARE_UINT32(cur->info0, ref->info2, unknown19);
619 COMPARE_UINT32(cur->info0, ref->info2, change_id);
620 COMPARE_UINT32(cur->info0, ref->info2, unknown21);*/
621 COMPARE_UINT32(cur
->info0
, ref
->info2
, status
);
622 /*COMPARE_UINT32(cur->info0, ref->info2, unknown23);
623 COMPARE_UINT32(cur->info0, ref->info2, c_setprinter);
624 COMPARE_UINT16(cur->info0, ref->info2, unknown25);
625 COMPARE_UINT16(cur->info0, ref->info2, unknown26);
626 COMPARE_UINT32(cur->info0, ref->info2, unknown27);
627 COMPARE_UINT32(cur->info0, ref->info2, unknown28);
628 COMPARE_UINT32(cur->info0, ref->info2, unknown29);*/
631 /*COMPARE_UINT32(cur->info1, ref->info2, flags);*/
632 /*COMPARE_STRING(cur->info1, ref->info2, name);*/
633 /*COMPARE_STRING(cur->info1, ref->info2, description);*/
634 COMPARE_STRING(cur
->info1
, ref
->info2
, comment
);
637 /* level 2 is our reference, and it makes no sense to compare it to itself */
640 COMPARE_STRING(cur
->info4
, ref
->info2
, printername
);
641 COMPARE_STRING(cur
->info4
, ref
->info2
, servername
);
642 COMPARE_UINT32(cur
->info4
, ref
->info2
, attributes
);
645 COMPARE_STRING(cur
->info5
, ref
->info2
, printername
);
646 COMPARE_STRING(cur
->info5
, ref
->info2
, portname
);
647 COMPARE_UINT32(cur
->info5
, ref
->info2
, attributes
);
648 /*COMPARE_UINT32(cur->info5, ref->info2, device_not_selected_timeout);
649 COMPARE_UINT32(cur->info5, ref->info2, transmission_retry_timeout);*/
656 * - verify that the port of a printer was in the list returned by EnumPorts
662 static BOOL
test_GetPrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
663 struct policy_handle
*handle
)
666 struct spoolss_GetPrinter r
;
667 uint16_t levels
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
671 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
672 uint32_t buf_size
= 0;
673 r
.in
.handle
= handle
;
674 r
.in
.level
= levels
[i
];
676 r
.in
.buf_size
= &buf_size
;
677 r
.out
.buf_size
= &buf_size
;
679 printf("Testing GetPrinter level %u\n", r
.in
.level
);
681 status
= dcerpc_spoolss_GetPrinter(p
, mem_ctx
, &r
);
682 if (!NT_STATUS_IS_OK(status
)) {
683 printf("GetPrinter failed - %s\n", nt_errstr(status
));
688 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
689 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
690 data_blob_clear(&blob
);
692 status
= dcerpc_spoolss_GetPrinter(p
, mem_ctx
, &r
);
695 if (!NT_STATUS_IS_OK(status
)) {
696 printf("GetPrinter failed - %s\n", nt_errstr(status
));
701 if (!W_ERROR_IS_OK(r
.out
.result
)) {
702 printf("GetPrinter failed - %s\n",
703 win_errstr(r
.out
.result
));
713 static BOOL
test_ClosePrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
714 struct policy_handle
*handle
)
717 struct spoolss_ClosePrinter r
;
719 r
.in
.handle
= handle
;
720 r
.out
.handle
= handle
;
722 printf("Testing ClosePrinter\n");
724 status
= dcerpc_spoolss_ClosePrinter(p
, mem_ctx
, &r
);
725 if (!NT_STATUS_IS_OK(status
)) {
726 printf("ClosePrinter failed - %s\n", nt_errstr(status
));
733 static BOOL
test_GetForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
734 struct policy_handle
*handle
,
735 const char *form_name
)
738 struct spoolss_GetForm r
;
741 r
.in
.handle
= handle
;
742 r
.in
.form_name
= form_name
;
746 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
748 printf("Testing GetForm\n");
750 status
= dcerpc_spoolss_GetForm(p
, mem_ctx
, &r
);
752 if (!NT_STATUS_IS_OK(status
)) {
753 printf("GetForm failed - %s\n", nt_errstr(status
));
757 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
758 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
760 data_blob_clear(&blob
);
763 status
= dcerpc_spoolss_GetForm(p
, mem_ctx
, &r
);
766 printf("No form info returned");
774 static BOOL
test_EnumForms(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
775 struct policy_handle
*handle
)
778 struct spoolss_EnumForms r
;
781 r
.in
.handle
= handle
;
785 r
.in
.buf_size
= &buf_size
;
786 r
.out
.buf_size
= &buf_size
;
788 printf("Testing EnumForms\n");
790 status
= dcerpc_spoolss_EnumForms(p
, mem_ctx
, &r
);
792 if (!NT_STATUS_IS_OK(status
)) {
793 printf("EnumForms failed - %s\n", nt_errstr(status
));
797 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
798 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
799 union spoolss_FormInfo
*info
;
802 data_blob_clear(&blob
);
805 status
= dcerpc_spoolss_EnumForms(p
, mem_ctx
, &r
);
808 printf("No forms returned");
814 for (j
= 0; j
< r
.out
.count
; j
++) {
815 test_GetForm(p
, mem_ctx
, handle
, info
[j
].info1
.form_name
);
819 if (!NT_STATUS_IS_OK(status
)) {
820 printf("EnumForms failed - %s\n", nt_errstr(status
));
824 if (!W_ERROR_IS_OK(r
.out
.result
)) {
825 printf("EnumForms failed - %s\n", win_errstr(r
.out
.result
));
832 static BOOL
test_DeleteForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
833 struct policy_handle
*handle
,
834 const char *form_name
)
837 struct spoolss_DeleteForm r
;
839 r
.in
.handle
= handle
;
840 r
.in
.form_name
= form_name
;
842 status
= dcerpc_spoolss_DeleteForm(p
, mem_ctx
, &r
);
844 if (!NT_STATUS_IS_OK(status
)) {
845 printf("DeleteForm failed - %s\n", nt_errstr(status
));
849 if (!W_ERROR_IS_OK(r
.out
.result
)) {
850 printf("DeleteForm failed - %s\n", win_errstr(r
.out
.result
));
857 static BOOL
test_AddForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
858 struct policy_handle
*handle
)
860 struct spoolss_AddForm r
;
861 struct spoolss_AddFormInfo1 addform
;
862 const char *form_name
= "testform3";
866 r
.in
.handle
= handle
;
868 r
.in
.info
.info1
= &addform
;
869 addform
.flags
= SPOOLSS_FORM_USER
;
870 addform
.form_name
= form_name
;
871 addform
.size
.width
= 50;
872 addform
.size
.height
= 25;
873 addform
.area
.left
= 5;
874 addform
.area
.top
= 10;
875 addform
.area
.right
= 45;
876 addform
.area
.bottom
= 15;
878 status
= dcerpc_spoolss_AddForm(p
, mem_ctx
, &r
);
880 if (!NT_STATUS_IS_OK(status
)) {
881 printf("AddForm failed - %s\n", nt_errstr(status
));
885 if (!W_ERROR_IS_OK(r
.out
.result
)) {
886 printf("AddForm failed - %s\n", nt_errstr(status
));
891 struct spoolss_SetForm sf
;
892 struct spoolss_SetFormInfo1 setform
;
894 sf
.in
.handle
= handle
;
895 sf
.in
.form_name
= form_name
;
897 sf
.in
.info
.info1
= &setform
;
898 setform
.flags
= addform
.flags
;
899 setform
.form_name
= addform
.form_name
;
900 setform
.size
= addform
.size
;
901 setform
.area
= addform
.area
;
903 setform
.size
.width
= 1234;
905 status
= dcerpc_spoolss_SetForm(p
, mem_ctx
, &sf
);
907 if (!NT_STATUS_IS_OK(status
)) {
908 printf("SetForm failed - %s\n", nt_errstr(status
));
913 if (!W_ERROR_IS_OK(r
.out
.result
)) {
914 printf("SetForm failed - %s\n",
915 win_errstr(r
.out
.result
));
922 if (!test_DeleteForm(p
, mem_ctx
, handle
, form_name
)) {
923 printf("DeleteForm failed\n");
930 static BOOL
test_EnumPorts_old(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
933 struct spoolss_EnumPorts r
;
936 r
.in
.servername
= talloc_asprintf(mem_ctx
, "\\\\%s",
937 dcerpc_server_name(p
));
941 r
.in
.buf_size
= &buf_size
;
942 r
.out
.buf_size
= &buf_size
;
944 printf("Testing EnumPorts\n");
946 status
= dcerpc_spoolss_EnumPorts(p
, mem_ctx
, &r
);
948 if (!NT_STATUS_IS_OK(status
)) {
949 printf("EnumPorts failed - %s\n", nt_errstr(status
));
953 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
954 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
956 data_blob_clear(&blob
);
959 status
= dcerpc_spoolss_EnumPorts(p
, mem_ctx
, &r
);
961 if (!NT_STATUS_IS_OK(status
)) {
962 printf("EnumPorts failed - %s\n", nt_errstr(status
));
967 printf("No ports returned");
975 static BOOL
test_AddPort(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
978 struct spoolss_AddPort r
;
980 r
.in
.server_name
= talloc_asprintf(mem_ctx
, "\\\\%s",
981 dcerpc_server_name(p
));
983 r
.in
.monitor_name
= "foo";
985 printf ("Testing AddPort\n");
987 status
= dcerpc_spoolss_AddPort(p
, mem_ctx
, &r
);
989 if (!NT_STATUS_IS_OK(status
)) {
990 printf("AddPort failed - %s\n", nt_errstr(status
));
994 /* win2k3 returns WERR_NOT_SUPPORTED */
998 if (!W_ERROR_IS_OK(r
.out
.result
)) {
999 printf("AddPort failed - %s\n", win_errstr(r
.out
.result
));
1008 static BOOL
test_GetJob(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1009 struct policy_handle
*handle
, uint32_t job_id
)
1012 struct spoolss_GetJob r
;
1015 r
.in
.handle
= handle
;
1016 r
.in
.job_id
= job_id
;
1020 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
1022 printf("Testing GetJob\n");
1024 status
= dcerpc_spoolss_GetJob(p
, mem_ctx
, &r
);
1026 if (!NT_STATUS_IS_OK(status
)) {
1027 printf("GetJob failed - %s\n", nt_errstr(status
));
1031 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1032 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
1034 data_blob_clear(&blob
);
1035 r
.in
.buffer
= &blob
;
1037 status
= dcerpc_spoolss_GetJob(p
, mem_ctx
, &r
);
1040 printf("No job info returned");
1048 static BOOL
test_SetJob(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1049 struct policy_handle
*handle
, uint32_t job_id
, uint32_t command
)
1052 struct spoolss_SetJob r
;
1054 r
.in
.handle
= handle
;
1055 r
.in
.job_id
= job_id
;
1057 r
.in
.command
= command
;
1059 printf("Testing SetJob\n");
1061 status
= dcerpc_spoolss_SetJob(p
, mem_ctx
, &r
);
1063 if (!NT_STATUS_IS_OK(status
)) {
1064 printf("SetJob failed - %s\n", nt_errstr(status
));
1071 static BOOL
test_EnumJobs(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1072 struct policy_handle
*handle
)
1075 struct spoolss_EnumJobs r
;
1078 r
.in
.handle
= handle
;
1080 r
.in
.numjobs
= 0xffffffff;
1084 r
.in
.buf_size
= &buf_size
;
1085 r
.out
.buf_size
= &buf_size
;
1087 printf("Testing EnumJobs\n");
1089 status
= dcerpc_spoolss_EnumJobs(p
, mem_ctx
, &r
);
1091 if (!NT_STATUS_IS_OK(status
)) {
1092 printf("EnumJobs failed - %s\n", nt_errstr(status
));
1096 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1097 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
1098 union spoolss_JobInfo
*info
;
1101 data_blob_clear(&blob
);
1102 r
.in
.buffer
= &blob
;
1104 status
= dcerpc_spoolss_EnumJobs(p
, mem_ctx
, &r
);
1107 printf("No jobs returned");
1113 for (j
= 0; j
< r
.out
.count
; j
++) {
1114 test_GetJob(p
, mem_ctx
, handle
, info
[j
].info1
.job_id
);
1115 test_SetJob(p
, mem_ctx
, handle
, info
[j
].info1
.job_id
, 1);
1118 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
1119 printf("EnumJobs failed - %s\n", win_errstr(r
.out
.result
));
1126 static BOOL
test_GetPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1127 struct policy_handle
*handle
,
1128 const char *value_name
)
1131 struct spoolss_GetPrinterData r
;
1134 r
.in
.handle
= handle
;
1135 r
.in
.value_name
= value_name
;
1137 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
1139 printf("Testing GetPrinterData\n");
1141 status
= dcerpc_spoolss_GetPrinterData(p
, mem_ctx
, &r
);
1143 if (!NT_STATUS_IS_OK(status
)) {
1144 printf("GetPrinterData failed - %s\n", nt_errstr(status
));
1148 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
1150 status
= dcerpc_spoolss_GetPrinterData(p
, mem_ctx
, &r
);
1152 if (!NT_STATUS_IS_OK(status
)) {
1153 printf("GetPrinterData failed - %s\n",
1158 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1159 printf("GetPrinterData failed - %s\n",
1160 win_errstr(r
.out
.result
));
1168 static BOOL
test_GetPrinterDataEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1169 struct policy_handle
*handle
,
1170 const char *key_name
,
1171 const char *value_name
)
1174 struct spoolss_GetPrinterDataEx r
;
1177 r
.in
.handle
= handle
;
1178 r
.in
.key_name
= key_name
;
1179 r
.in
.value_name
= value_name
;
1181 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
1183 printf("Testing GetPrinterDataEx\n");
1185 status
= dcerpc_spoolss_GetPrinterDataEx(p
, mem_ctx
, &r
);
1186 if (!NT_STATUS_IS_OK(status
)) {
1187 if (NT_STATUS_EQUAL(status
,NT_STATUS_NET_WRITE_FAULT
) &&
1188 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
1189 printf("GetPrinterDataEx not supported by server\n");
1192 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status
));
1196 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
1198 status
= dcerpc_spoolss_GetPrinterDataEx(p
, mem_ctx
, &r
);
1200 if (!NT_STATUS_IS_OK(status
)) {
1201 printf("GetPrinterDataEx failed - %s\n",
1206 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1207 printf("GetPrinterDataEx failed - %s\n",
1208 win_errstr(r
.out
.result
));
1216 static BOOL
test_EnumPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1217 struct policy_handle
*handle
)
1220 struct spoolss_EnumPrinterData r
;
1222 r
.in
.handle
= handle
;
1223 r
.in
.enum_index
= 0;
1228 r
.in
.value_offered
= 0;
1230 r
.in
.data_size
= &data_size
;
1231 r
.out
.data_size
= &data_size
;
1233 printf("Testing EnumPrinterData\n");
1235 status
= dcerpc_spoolss_EnumPrinterData(p
, mem_ctx
, &r
);
1237 if (!NT_STATUS_IS_OK(status
)) {
1238 printf("EnumPrinterData failed - %s\n", nt_errstr(status
));
1242 r
.in
.value_offered
= r
.out
.value_needed
;
1244 status
= dcerpc_spoolss_EnumPrinterData(p
, mem_ctx
, &r
);
1246 if (!NT_STATUS_IS_OK(status
)) {
1247 printf("EnumPrinterData failed - %s\n", nt_errstr(status
));
1251 test_GetPrinterData(p
, mem_ctx
, handle
, r
.out
.value_name
);
1253 test_GetPrinterDataEx(
1254 p
, mem_ctx
, handle
, "PrinterDriverData",
1259 } while (W_ERROR_IS_OK(r
.out
.result
));
1264 static BOOL
test_EnumPrinterDataEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1265 struct policy_handle
*handle
)
1268 struct spoolss_EnumPrinterDataEx r
;
1270 r
.in
.handle
= handle
;
1271 r
.in
.key_name
= "PrinterDriverData";
1274 printf("Testing EnumPrinterDataEx\n");
1276 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, mem_ctx
, &r
);
1278 if (!NT_STATUS_IS_OK(status
)) {
1279 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status
));
1283 r
.in
.buf_size
= r
.out
.buf_size
;
1285 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, mem_ctx
, &r
);
1287 if (!NT_STATUS_IS_OK(status
)) {
1288 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status
));
1296 static BOOL
test_DeletePrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1297 struct policy_handle
*handle
,
1298 const char *value_name
)
1301 struct spoolss_DeletePrinterData r
;
1303 r
.in
.handle
= handle
;
1304 r
.in
.value_name
= value_name
;
1306 printf("Testing DeletePrinterData\n");
1308 status
= dcerpc_spoolss_DeletePrinterData(p
, mem_ctx
, &r
);
1310 if (!NT_STATUS_IS_OK(status
)) {
1311 printf("DeletePrinterData failed - %s\n", nt_errstr(status
));
1318 static BOOL
test_SetPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1319 struct policy_handle
*handle
)
1322 struct spoolss_SetPrinterData r
;
1323 const char *value_name
= "spottyfoot";
1325 r
.in
.handle
= handle
;
1326 r
.in
.value_name
= value_name
;
1328 r
.in
.buffer
= data_blob_talloc(mem_ctx
, "dog", 4);
1331 printf("Testing SetPrinterData\n");
1333 status
= dcerpc_spoolss_SetPrinterData(p
, mem_ctx
, &r
);
1335 if (!NT_STATUS_IS_OK(status
)) {
1336 printf("SetPrinterData failed - %s\n", nt_errstr(status
));
1340 if (!test_DeletePrinterData(p
, mem_ctx
, handle
, value_name
)) {
1347 static BOOL
test_SecondaryClosePrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1348 struct policy_handle
*handle
)
1351 struct dcerpc_binding
*b
;
1352 struct dcerpc_pipe
*p2
;
1355 /* only makes sense on SMB */
1356 if (p
->conn
->transport
.transport
!= NCACN_NP
) {
1360 printf("testing close on secondary pipe\n");
1362 status
= dcerpc_parse_binding(mem_ctx
, p
->conn
->binding_string
, &b
);
1363 if (!NT_STATUS_IS_OK(status
)) {
1364 printf("Failed to parse dcerpc binding '%s'\n", p
->conn
->binding_string
);
1368 status
= dcerpc_secondary_connection(p
, &p2
, b
);
1369 if (!NT_STATUS_IS_OK(status
)) {
1370 printf("Failed to create secondary connection\n");
1374 status
= dcerpc_bind_auth_none(p2
, DCERPC_SPOOLSS_UUID
,
1375 DCERPC_SPOOLSS_VERSION
);
1376 if (!NT_STATUS_IS_OK(status
)) {
1377 printf("Failed to create bind on secondary connection\n");
1383 if (test_ClosePrinter(p2
, mem_ctx
, handle
)) {
1384 printf("ERROR: Allowed close on secondary connection!\n");
1388 if (p2
->last_fault_code
!= DCERPC_FAULT_CONTEXT_MISMATCH
) {
1389 printf("Unexpected fault code 0x%x - expected 0x%x\n",
1390 p2
->last_fault_code
, DCERPC_FAULT_CONTEXT_MISMATCH
);
1399 static BOOL
test_OpenPrinter_badname(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
, const char *name
)
1402 struct spoolss_OpenPrinter op
;
1403 struct spoolss_OpenPrinterEx opEx
;
1404 struct policy_handle handle
;
1407 op
.in
.printername
= name
;
1408 op
.in
.datatype
= NULL
;
1409 op
.in
.devmode_ctr
.size
= 0;
1410 op
.in
.devmode_ctr
.devmode
= NULL
;
1411 op
.in
.access_mask
= 0;
1412 op
.out
.handle
= &handle
;
1414 printf("\nTesting OpenPrinter(%s) with bad name\n", op
.in
.printername
);
1416 status
= dcerpc_spoolss_OpenPrinter(p
, mem_ctx
, &op
);
1417 if (!NT_STATUS_IS_OK(status
)) {
1418 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
1421 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,op
.out
.result
)) {
1422 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1423 name
, win_errstr(op
.out
.result
));
1426 if (W_ERROR_IS_OK(op
.out
.result
)) {
1427 ret
&=test_ClosePrinter(p
, mem_ctx
, &handle
);
1430 opEx
.in
.printername
= name
;
1431 opEx
.in
.datatype
= NULL
;
1432 opEx
.in
.devmode_ctr
.size
= 0;
1433 opEx
.in
.devmode_ctr
.devmode
= NULL
;
1434 opEx
.in
.access_mask
= 0;
1436 opEx
.in
.userlevel
.level1
= NULL
;
1437 opEx
.out
.handle
= &handle
;
1439 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx
.in
.printername
);
1441 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &opEx
);
1442 if (!NT_STATUS_IS_OK(status
)) {
1443 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
1446 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,opEx
.out
.result
)) {
1447 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
1448 name
, win_errstr(opEx
.out
.result
));
1451 if (W_ERROR_IS_OK(opEx
.out
.result
)) {
1452 ret
&=test_ClosePrinter(p
, mem_ctx
, &handle
);
1458 static BOOL
test_OpenPrinter_badnames(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
1463 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "__INVALID_PRINTER__");
1464 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\__INVALID_HOST__");
1465 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "");
1466 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\\\");
1467 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\\\__INVALID_PRINTER__");
1469 name
= talloc_asprintf(mem_ctx
, "\\\\%s\\", dcerpc_server_name(p
));
1470 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, name
);
1473 name
= talloc_asprintf(mem_ctx
, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p
));
1474 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, name
);
1480 static BOOL
test_OpenPrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1484 struct spoolss_OpenPrinter r
;
1485 struct policy_handle handle
;
1488 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s", dcerpc_server_name(p
), name
);
1489 r
.in
.datatype
= NULL
;
1490 r
.in
.devmode_ctr
.size
= 0;
1491 r
.in
.devmode_ctr
.devmode
= NULL
;
1492 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1493 r
.out
.handle
= &handle
;
1495 printf("\nTesting OpenPrinter(%s)\n", r
.in
.printername
);
1497 status
= dcerpc_spoolss_OpenPrinter(p
, mem_ctx
, &r
);
1499 if (!NT_STATUS_IS_OK(status
)) {
1500 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
1504 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1505 printf("OpenPrinter failed - %s\n", win_errstr(r
.out
.result
));
1509 if (!test_GetPrinter(p
, mem_ctx
, &handle
)) {
1513 if (!test_SecondaryClosePrinter(p
, mem_ctx
, &handle
)) {
1517 if (!test_ClosePrinter(p
, mem_ctx
, &handle
)) {
1524 static BOOL
call_OpenPrinterEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1525 const char *name
, struct policy_handle
*handle
)
1527 struct spoolss_OpenPrinterEx r
;
1528 struct spoolss_UserLevel1 userlevel1
;
1531 if (name
&& name
[0]) {
1532 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
1533 dcerpc_server_name(p
), name
);
1535 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s",
1536 dcerpc_server_name(p
));
1539 r
.in
.datatype
= NULL
;
1540 r
.in
.devmode_ctr
.size
= 0;
1541 r
.in
.devmode_ctr
.devmode
= NULL
;
1542 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1544 r
.in
.userlevel
.level1
= &userlevel1
;
1545 r
.out
.handle
= handle
;
1547 userlevel1
.size
= 1234;
1548 userlevel1
.client
= "hello";
1549 userlevel1
.user
= "spottyfoot!";
1550 userlevel1
.build
= 1;
1551 userlevel1
.major
= 2;
1552 userlevel1
.minor
= 3;
1553 userlevel1
.processor
= 4;
1555 printf("Testing OpenPrinterEx(%s)\n", r
.in
.printername
);
1557 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &r
);
1559 if (!NT_STATUS_IS_OK(status
)) {
1560 printf("OpenPrinterEx failed - %s\n", nt_errstr(status
));
1564 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1565 printf("OpenPrinterEx failed - %s\n", win_errstr(r
.out
.result
));
1572 static BOOL
test_OpenPrinterEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1575 struct policy_handle handle
;
1578 if (!call_OpenPrinterEx(p
, mem_ctx
, name
, &handle
)) {
1582 if (!test_GetPrinter(p
, mem_ctx
, &handle
)) {
1586 if (!test_EnumForms(p
, mem_ctx
, &handle
)) {
1590 if (!test_AddForm(p
, mem_ctx
, &handle
)) {
1594 if (!test_EnumPrinterData(p
, mem_ctx
, &handle
)) {
1598 if (!test_EnumPrinterDataEx(p
, mem_ctx
, &handle
)) {
1602 if (!test_EnumJobs(p
, mem_ctx
, &handle
)) {
1606 if (!test_SetPrinterData(p
, mem_ctx
, &handle
)) {
1610 if (!test_SecondaryClosePrinter(p
, mem_ctx
, &handle
)) {
1614 if (!test_ClosePrinter(p
, mem_ctx
, &handle
)) {
1621 static BOOL
test_EnumPrinters_old(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
1623 struct spoolss_EnumPrinters r
;
1625 uint16_t levels
[] = {1, 2, 4, 5};
1629 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1630 uint32_t buf_size
= 0;
1631 union spoolss_PrinterInfo
*info
;
1634 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
1636 r
.in
.level
= levels
[i
];
1638 r
.in
.buf_size
= &buf_size
;
1639 r
.out
.buf_size
= &buf_size
;
1641 printf("\nTesting EnumPrinters level %u\n", r
.in
.level
);
1643 status
= dcerpc_spoolss_EnumPrinters(p
, mem_ctx
, &r
);
1644 if (!NT_STATUS_IS_OK(status
)) {
1645 printf("EnumPrinters failed - %s\n", nt_errstr(status
));
1650 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1651 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
1652 data_blob_clear(&blob
);
1653 r
.in
.buffer
= &blob
;
1654 status
= dcerpc_spoolss_EnumPrinters(p
, mem_ctx
, &r
);
1657 if (!NT_STATUS_IS_OK(status
)) {
1658 printf("EnumPrinters failed - %s\n",
1663 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1664 printf("EnumPrinters failed - %s\n",
1665 win_errstr(r
.out
.result
));
1670 printf("No printers returned");
1676 for (j
=0;j
<r
.out
.count
;j
++) {
1677 if (r
.in
.level
== 1) {
1678 /* the names appear to be comma-separated name lists? */
1679 char *name
= talloc_strdup(mem_ctx
, info
[j
].info1
.name
);
1680 char *comma
= strchr(name
, ',');
1681 if (comma
) *comma
= 0;
1682 if (!test_OpenPrinter(p
, mem_ctx
, name
)) {
1685 if (!test_OpenPrinterEx(p
, mem_ctx
, name
)) {
1696 static BOOL
test_GetPrinterDriver2(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1697 struct policy_handle
*handle
,
1698 const char *driver_name
)
1701 struct spoolss_GetPrinterDriver2 r
;
1704 r
.in
.handle
= handle
;
1705 r
.in
.architecture
= "W32X86";
1709 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
1710 r
.in
.client_major_version
= 0;
1711 r
.in
.client_minor_version
= 0;
1713 printf("Testing GetPrinterDriver2\n");
1715 status
= dcerpc_spoolss_GetPrinterDriver2(p
, mem_ctx
, &r
);
1717 if (!NT_STATUS_IS_OK(status
)) {
1718 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status
));
1722 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1723 status
= dcerpc_spoolss_GetPrinterDriver2(p
, mem_ctx
, &r
);
1726 if (!NT_STATUS_IS_OK(status
)) {
1727 printf("GetPrinterDriver2 failed - %s\n",
1732 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1733 printf("GetPrinterDriver2 failed - %s\n",
1734 win_errstr(r
.out
.result
));
1742 static BOOL
test_EnumPrinterDrivers_old(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
1744 struct spoolss_EnumPrinterDrivers r
;
1746 uint16_t levels
[] = {1, 2, 3, 4, 5, 6};
1750 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1753 r
.in
.server
= talloc_asprintf(mem_ctx
, "\\\\%s", dcerpc_server_name(p
));
1754 r
.in
.environment
= "Windows NT x86";
1755 r
.in
.level
= levels
[i
];
1758 r
.in
.buf_size
= &buf_size
;
1759 r
.out
.buf_size
= &buf_size
;
1761 printf("\nTesting EnumPrinterDrivers level %u\n", r
.in
.level
);
1763 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, mem_ctx
, &r
);
1765 if (!NT_STATUS_IS_OK(status
)) {
1766 printf("EnumPrinterDrivers failed - %s\n",
1772 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1773 DATA_BLOB blob
= data_blob_talloc(
1774 mem_ctx
, NULL
, buf_size
);
1776 data_blob_clear(&blob
);
1777 r
.in
.buffer
= &blob
;
1778 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, mem_ctx
, &r
);
1781 if (!NT_STATUS_IS_OK(status
)) {
1782 printf("EnumPrinterDrivers failed - %s\n",
1788 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1789 printf("EnumPrinterDrivers failed - %s\n",
1790 win_errstr(r
.out
.result
));
1796 printf("No printer drivers returned");
1804 BOOL
torture_rpc_spoolss(void)
1807 struct dcerpc_pipe
*p
;
1808 TALLOC_CTX
*mem_ctx
;
1810 struct test_spoolss_context
*ctx
;
1812 mem_ctx
= talloc_init("torture_rpc_spoolss");
1814 status
= torture_rpc_connection(mem_ctx
,
1816 DCERPC_SPOOLSS_NAME
,
1817 DCERPC_SPOOLSS_UUID
,
1818 DCERPC_SPOOLSS_VERSION
);
1819 if (!NT_STATUS_IS_OK(status
)) {
1820 talloc_free(mem_ctx
);
1824 ctx
= talloc_zero(mem_ctx
, struct test_spoolss_context
);
1827 ret
&= test_OpenPrinter_server(ctx
);
1829 ret
&= test_GetPrinterData(ctx
->p
, ctx
, &ctx
->server_handle
, SPOOLSS_ARCHITECTURE_NT_X86
);
1831 ret
&= test_GetPrinterData(ctx
->p
, ctx
, &ctx
->server_handle
, "DefaultSpoolDirectory");
1833 ret
&= test_EnumPorts(ctx
);
1835 ret
&= test_EnumPrinterDrivers(ctx
);
1837 ret
&= test_EnumMonitors(ctx
);
1839 ret
&= test_EnumPrintProcessors(ctx
);
1841 ret
&= test_EnumPrinters(ctx
);
1843 ret
&= test_OpenPrinter_badnames(p
, mem_ctx
);
1845 ret
&= test_AddPort(p
, mem_ctx
);
1847 ret
&= test_EnumPorts_old(p
, mem_ctx
);
1849 ret
&= test_EnumPrinters_old(p
, mem_ctx
);
1851 ret
&= test_EnumPrinterDrivers_old(p
, mem_ctx
);
1853 talloc_free(mem_ctx
);