2 Unix SMB/CIFS implementation.
3 test suite for spoolss rpc operations
5 Copyright (C) Tim Potter 2003
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "librpc/gen_ndr/ndr_spoolss.h"
25 static BOOL
test_GetPrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
26 struct policy_handle
*handle
)
29 struct spoolss_GetPrinter r
;
30 uint16_t levels
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
34 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
35 uint32_t buf_size
= 0;
37 r
.in
.level
= levels
[i
];
39 r
.in
.buf_size
= &buf_size
;
40 r
.out
.buf_size
= &buf_size
;
42 printf("Testing GetPrinter level %u\n", r
.in
.level
);
44 status
= dcerpc_spoolss_GetPrinter(p
, mem_ctx
, &r
);
45 if (!NT_STATUS_IS_OK(status
)) {
46 printf("GetPrinter failed - %s\n", nt_errstr(status
));
51 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
52 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
53 data_blob_clear(&blob
);
55 status
= dcerpc_spoolss_GetPrinter(p
, mem_ctx
, &r
);
58 if (!NT_STATUS_IS_OK(status
)) {
59 printf("GetPrinter failed - %s\n", nt_errstr(status
));
64 if (!W_ERROR_IS_OK(r
.out
.result
)) {
65 printf("GetPrinter failed - %s\n",
66 win_errstr(r
.out
.result
));
76 static BOOL
test_ClosePrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
77 struct policy_handle
*handle
)
80 struct spoolss_ClosePrinter r
;
83 r
.out
.handle
= handle
;
85 printf("Testing ClosePrinter\n");
87 status
= dcerpc_spoolss_ClosePrinter(p
, mem_ctx
, &r
);
88 if (!NT_STATUS_IS_OK(status
)) {
89 printf("ClosePrinter failed - %s\n", nt_errstr(status
));
96 static BOOL
test_GetForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
97 struct policy_handle
*handle
,
101 struct spoolss_GetForm r
;
104 r
.in
.handle
= handle
;
105 r
.in
.formname
= formname
;
109 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
111 printf("Testing GetForm\n");
113 status
= dcerpc_spoolss_GetForm(p
, mem_ctx
, &r
);
115 if (!NT_STATUS_IS_OK(status
)) {
116 printf("GetForm failed - %s\n", nt_errstr(status
));
120 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
121 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
123 data_blob_clear(&blob
);
126 status
= dcerpc_spoolss_GetForm(p
, mem_ctx
, &r
);
129 printf("No form info returned");
137 static BOOL
test_EnumForms(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
138 struct policy_handle
*handle
)
141 struct spoolss_EnumForms r
;
144 r
.in
.handle
= handle
;
148 r
.in
.buf_size
= &buf_size
;
149 r
.out
.buf_size
= &buf_size
;
151 printf("Testing EnumForms\n");
153 status
= dcerpc_spoolss_EnumForms(p
, mem_ctx
, &r
);
155 if (!NT_STATUS_IS_OK(status
)) {
156 printf("EnumForms failed - %s\n", nt_errstr(status
));
160 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
161 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
162 union spoolss_FormInfo
*info
;
165 data_blob_clear(&blob
);
168 status
= dcerpc_spoolss_EnumForms(p
, mem_ctx
, &r
);
171 printf("No forms returned");
177 for (j
= 0; j
< r
.out
.count
; j
++) {
178 test_GetForm(p
, mem_ctx
, handle
, info
[j
].info1
.formname
);
182 if (!NT_STATUS_IS_OK(status
)) {
183 printf("EnumForms failed - %s\n", nt_errstr(status
));
187 if (!W_ERROR_IS_OK(r
.out
.result
)) {
188 printf("EnumForms failed - %s\n", win_errstr(r
.out
.result
));
195 static BOOL
test_DeleteForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
196 struct policy_handle
*handle
,
197 const char *formname
)
200 struct spoolss_DeleteForm r
;
202 r
.in
.handle
= handle
;
203 r
.in
.formname
= formname
;
205 status
= dcerpc_spoolss_DeleteForm(p
, mem_ctx
, &r
);
207 if (!NT_STATUS_IS_OK(status
)) {
208 printf("DeleteForm failed - %s\n", nt_errstr(status
));
212 if (!W_ERROR_IS_OK(r
.out
.result
)) {
213 printf("DeleteForm failed - %s\n", win_errstr(r
.out
.result
));
220 static BOOL
test_AddForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
221 struct policy_handle
*handle
)
223 struct spoolss_AddForm r
;
224 struct spoolss_AddFormInfo1 form
;
226 const char *formname
= "testform3";
229 r
.in
.handle
= handle
;
231 form
.flags
= 2; /* User form */
232 form
.formname
= formname
;
239 r
.in
.info
.info1
= &form
;
241 status
= dcerpc_spoolss_AddForm(p
, mem_ctx
, &r
);
243 if (!NT_STATUS_IS_OK(status
)) {
244 printf("AddForm failed - %s\n", nt_errstr(status
));
248 if (!W_ERROR_IS_OK(r
.out
.result
)) {
249 printf("AddForm failed - %s\n", nt_errstr(status
));
254 struct spoolss_SetForm sf
;
256 sf
.in
.handle
= handle
;
257 sf
.in
.formname
= formname
;
259 sf
.in
.info
.info1
= &form
;
262 status
= dcerpc_spoolss_SetForm(p
, mem_ctx
, &sf
);
264 if (!NT_STATUS_IS_OK(status
)) {
265 printf("SetForm failed - %s\n", nt_errstr(status
));
270 if (!W_ERROR_IS_OK(r
.out
.result
)) {
271 printf("SetForm failed - %s\n",
272 win_errstr(r
.out
.result
));
279 if (!test_DeleteForm(p
, mem_ctx
, handle
, formname
)) {
280 printf("DeleteForm failed\n");
287 static BOOL
test_EnumPorts(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
290 struct spoolss_EnumPorts r
;
293 r
.in
.servername
= talloc_asprintf(mem_ctx
, "\\\\%s",
294 dcerpc_server_name(p
));
298 r
.in
.buf_size
= &buf_size
;
299 r
.out
.buf_size
= &buf_size
;
301 printf("Testing EnumPorts\n");
303 status
= dcerpc_spoolss_EnumPorts(p
, mem_ctx
, &r
);
305 if (!NT_STATUS_IS_OK(status
)) {
306 printf("EnumPorts failed - %s\n", nt_errstr(status
));
310 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
311 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
313 data_blob_clear(&blob
);
316 status
= dcerpc_spoolss_EnumPorts(p
, mem_ctx
, &r
);
318 if (!NT_STATUS_IS_OK(status
)) {
319 printf("EnumPorts failed - %s\n", nt_errstr(status
));
324 printf("No ports returned");
332 static BOOL
test_AddPort(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
335 struct spoolss_AddPort r
;
337 r
.in
.server_name
= talloc_asprintf(mem_ctx
, "\\\\%s",
338 dcerpc_server_name(p
));
340 r
.in
.monitor_name
= "foo";
342 printf ("Testing AddPort\n");
344 status
= dcerpc_spoolss_AddPort(p
, mem_ctx
, &r
);
346 if (!NT_STATUS_IS_OK(status
)) {
347 printf("AddPort failed - %s\n", nt_errstr(status
));
351 /* win2k3 returns WERR_NOT_SUPPORTED */
355 if (!W_ERROR_IS_OK(r
.out
.result
)) {
356 printf("AddPort failed - %s\n", win_errstr(r
.out
.result
));
365 static BOOL
test_GetJob(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
366 struct policy_handle
*handle
, uint32_t job_id
)
369 struct spoolss_GetJob r
;
372 r
.in
.handle
= handle
;
373 r
.in
.job_id
= job_id
;
377 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
379 printf("Testing GetJob\n");
381 status
= dcerpc_spoolss_GetJob(p
, mem_ctx
, &r
);
383 if (!NT_STATUS_IS_OK(status
)) {
384 printf("GetJob failed - %s\n", nt_errstr(status
));
388 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
389 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
391 data_blob_clear(&blob
);
394 status
= dcerpc_spoolss_GetJob(p
, mem_ctx
, &r
);
397 printf("No job info returned");
405 static BOOL
test_SetJob(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
406 struct policy_handle
*handle
, uint32_t job_id
, uint32_t command
)
409 struct spoolss_SetJob r
;
411 r
.in
.handle
= handle
;
412 r
.in
.job_id
= job_id
;
414 r
.in
.command
= command
;
416 printf("Testing SetJob\n");
418 status
= dcerpc_spoolss_SetJob(p
, mem_ctx
, &r
);
420 if (!NT_STATUS_IS_OK(status
)) {
421 printf("SetJob failed - %s\n", nt_errstr(status
));
428 static BOOL
test_EnumJobs(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
429 struct policy_handle
*handle
)
432 struct spoolss_EnumJobs r
;
435 r
.in
.handle
= handle
;
437 r
.in
.numjobs
= 0xffffffff;
441 r
.in
.buf_size
= &buf_size
;
442 r
.out
.buf_size
= &buf_size
;
444 printf("Testing EnumJobs\n");
446 status
= dcerpc_spoolss_EnumJobs(p
, mem_ctx
, &r
);
448 if (!NT_STATUS_IS_OK(status
)) {
449 printf("EnumJobs failed - %s\n", nt_errstr(status
));
453 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
454 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
455 union spoolss_JobInfo
*info
;
458 data_blob_clear(&blob
);
461 status
= dcerpc_spoolss_EnumJobs(p
, mem_ctx
, &r
);
464 printf("No jobs returned");
470 for (j
= 0; j
< r
.out
.count
; j
++) {
471 test_GetJob(p
, mem_ctx
, handle
, info
[j
].info1
.job_id
);
472 test_SetJob(p
, mem_ctx
, handle
, info
[j
].info1
.job_id
, 1);
475 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
476 printf("EnumJobs failed - %s\n", win_errstr(r
.out
.result
));
483 static BOOL
test_GetPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
484 struct policy_handle
*handle
,
485 const char *value_name
)
488 struct spoolss_GetPrinterData r
;
491 r
.in
.handle
= handle
;
492 r
.in
.value_name
= value_name
;
494 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
496 printf("Testing GetPrinterData\n");
498 status
= dcerpc_spoolss_GetPrinterData(p
, mem_ctx
, &r
);
500 if (!NT_STATUS_IS_OK(status
)) {
501 printf("GetPrinterData failed - %s\n", nt_errstr(status
));
505 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
507 status
= dcerpc_spoolss_GetPrinterData(p
, mem_ctx
, &r
);
509 if (!NT_STATUS_IS_OK(status
)) {
510 printf("GetPrinterData failed - %s\n",
515 if (!W_ERROR_IS_OK(r
.out
.result
)) {
516 printf("GetPrinterData failed - %s\n",
517 win_errstr(r
.out
.result
));
525 static BOOL
test_GetPrinterDataEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
526 struct policy_handle
*handle
,
527 const char *key_name
,
528 const char *value_name
)
531 struct spoolss_GetPrinterDataEx r
;
534 r
.in
.handle
= handle
;
535 r
.in
.key_name
= key_name
;
536 r
.in
.value_name
= value_name
;
538 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
540 printf("Testing GetPrinterDataEx\n");
542 status
= dcerpc_spoolss_GetPrinterDataEx(p
, mem_ctx
, &r
);
543 if (!NT_STATUS_IS_OK(status
)) {
544 if (NT_STATUS_EQUAL(status
,NT_STATUS_NET_WRITE_FAULT
) &&
545 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
546 printf("GetPrinterDataEx not supported by server\n");
549 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status
));
553 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
555 status
= dcerpc_spoolss_GetPrinterDataEx(p
, mem_ctx
, &r
);
557 if (!NT_STATUS_IS_OK(status
)) {
558 printf("GetPrinterDataEx failed - %s\n",
563 if (!W_ERROR_IS_OK(r
.out
.result
)) {
564 printf("GetPrinterDataEx failed - %s\n",
565 win_errstr(r
.out
.result
));
573 static BOOL
test_EnumPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
574 struct policy_handle
*handle
)
577 struct spoolss_EnumPrinterData r
;
579 r
.in
.handle
= handle
;
585 r
.in
.value_offered
= 0;
587 r
.in
.data_size
= &data_size
;
588 r
.out
.data_size
= &data_size
;
590 printf("Testing EnumPrinterData\n");
592 status
= dcerpc_spoolss_EnumPrinterData(p
, mem_ctx
, &r
);
594 if (!NT_STATUS_IS_OK(status
)) {
595 printf("EnumPrinterData failed - %s\n", nt_errstr(status
));
599 r
.in
.value_offered
= r
.out
.value_needed
;
601 status
= dcerpc_spoolss_EnumPrinterData(p
, mem_ctx
, &r
);
603 if (!NT_STATUS_IS_OK(status
)) {
604 printf("EnumPrinterData failed - %s\n", nt_errstr(status
));
608 test_GetPrinterData(p
, mem_ctx
, handle
, r
.out
.value_name
);
610 test_GetPrinterDataEx(
611 p
, mem_ctx
, handle
, "PrinterDriverData",
616 } while (W_ERROR_IS_OK(r
.out
.result
));
621 static BOOL
test_EnumPrinterDataEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
622 struct policy_handle
*handle
)
625 struct spoolss_EnumPrinterDataEx r
;
627 r
.in
.handle
= handle
;
628 r
.in
.key_name
= "PrinterDriverData";
631 printf("Testing EnumPrinterDataEx\n");
633 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, mem_ctx
, &r
);
635 if (!NT_STATUS_IS_OK(status
)) {
636 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status
));
640 r
.in
.buf_size
= r
.out
.buf_size
;
642 status
= dcerpc_spoolss_EnumPrinterDataEx(p
, mem_ctx
, &r
);
644 if (!NT_STATUS_IS_OK(status
)) {
645 printf("EnumPrinterDataEx failed - %s\n", nt_errstr(status
));
653 static BOOL
test_DeletePrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
654 struct policy_handle
*handle
,
655 const char *value_name
)
658 struct spoolss_DeletePrinterData r
;
660 r
.in
.handle
= handle
;
661 r
.in
.value_name
= value_name
;
663 printf("Testing DeletePrinterData\n");
665 status
= dcerpc_spoolss_DeletePrinterData(p
, mem_ctx
, &r
);
667 if (!NT_STATUS_IS_OK(status
)) {
668 printf("DeletePrinterData failed - %s\n", nt_errstr(status
));
675 static BOOL
test_SetPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
676 struct policy_handle
*handle
)
679 struct spoolss_SetPrinterData r
;
680 const char *value_name
= "spottyfoot";
682 r
.in
.handle
= handle
;
683 r
.in
.value_name
= value_name
;
685 r
.in
.buffer
= data_blob_talloc(mem_ctx
, "dog", 4);
688 printf("Testing SetPrinterData\n");
690 status
= dcerpc_spoolss_SetPrinterData(p
, mem_ctx
, &r
);
692 if (!NT_STATUS_IS_OK(status
)) {
693 printf("SetPrinterData failed - %s\n", nt_errstr(status
));
697 if (!test_DeletePrinterData(p
, mem_ctx
, handle
, value_name
)) {
704 static BOOL
test_SecondaryClosePrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
705 struct policy_handle
*handle
)
708 struct dcerpc_binding
*b
;
709 struct dcerpc_pipe
*p2
;
712 /* only makes sense on SMB */
713 if (p
->conn
->transport
.transport
!= NCACN_NP
) {
717 printf("testing close on secondary pipe\n");
719 status
= dcerpc_parse_binding(mem_ctx
, p
->conn
->binding_string
, &b
);
720 if (!NT_STATUS_IS_OK(status
)) {
721 printf("Failed to parse dcerpc binding '%s'\n", p
->conn
->binding_string
);
725 status
= dcerpc_secondary_connection(p
, &p2
, b
);
726 if (!NT_STATUS_IS_OK(status
)) {
727 printf("Failed to create secondary connection\n");
731 status
= dcerpc_bind_auth_none(p2
, DCERPC_SPOOLSS_UUID
,
732 DCERPC_SPOOLSS_VERSION
);
733 if (!NT_STATUS_IS_OK(status
)) {
734 printf("Failed to create bind on secondary connection\n");
740 if (test_ClosePrinter(p2
, mem_ctx
, handle
)) {
741 printf("ERROR: Allowed close on secondary connection!\n");
745 if (p2
->last_fault_code
!= DCERPC_FAULT_CONTEXT_MISMATCH
) {
746 printf("Unexpected fault code 0x%x - expected 0x%x\n",
747 p2
->last_fault_code
, DCERPC_FAULT_CONTEXT_MISMATCH
);
756 static BOOL
test_OpenPrinter_badname(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
, const char *name
)
759 struct spoolss_OpenPrinter op
;
760 struct spoolss_OpenPrinterEx opEx
;
761 struct policy_handle handle
;
764 op
.in
.printername
= name
;
765 op
.in
.datatype
= NULL
;
766 op
.in
.devmode_ctr
.size
= 0;
767 op
.in
.devmode_ctr
.devmode
= NULL
;
768 op
.in
.access_mask
= 0;
769 op
.out
.handle
= &handle
;
771 printf("\nTesting OpenPrinter(%s) with bad name\n", op
.in
.printername
);
773 status
= dcerpc_spoolss_OpenPrinter(p
, mem_ctx
, &op
);
774 if (!NT_STATUS_IS_OK(status
)) {
775 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
778 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,op
.out
.result
)) {
779 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
780 name
, win_errstr(op
.out
.result
));
783 if (W_ERROR_IS_OK(op
.out
.result
)) {
784 ret
&=test_ClosePrinter(p
, mem_ctx
, &handle
);
787 opEx
.in
.printername
= name
;
788 opEx
.in
.datatype
= NULL
;
789 opEx
.in
.devmode_ctr
.size
= 0;
790 opEx
.in
.devmode_ctr
.devmode
= NULL
;
791 opEx
.in
.access_mask
= 0;
793 opEx
.in
.userlevel
.level1
= NULL
;
794 opEx
.out
.handle
= &handle
;
796 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx
.in
.printername
);
798 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &opEx
);
799 if (!NT_STATUS_IS_OK(status
)) {
800 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
803 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,opEx
.out
.result
)) {
804 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
805 name
, win_errstr(opEx
.out
.result
));
808 if (W_ERROR_IS_OK(opEx
.out
.result
)) {
809 ret
&=test_ClosePrinter(p
, mem_ctx
, &handle
);
815 static BOOL
test_OpenPrinter_badnames(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
820 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "__INVALID_PRINTER__");
821 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\__INVALID_HOST__");
822 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "");
823 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\\\");
824 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\\\__INVALID_PRINTER__");
826 name
= talloc_asprintf(mem_ctx
, "\\\\%s\\", dcerpc_server_name(p
));
827 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, name
);
830 name
= talloc_asprintf(mem_ctx
, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p
));
831 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, name
);
837 static BOOL
test_OpenPrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
841 struct spoolss_OpenPrinter r
;
842 struct policy_handle handle
;
845 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s", dcerpc_server_name(p
), name
);
846 r
.in
.datatype
= NULL
;
847 r
.in
.devmode_ctr
.size
= 0;
848 r
.in
.devmode_ctr
.devmode
= NULL
;
849 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
850 r
.out
.handle
= &handle
;
852 printf("\nTesting OpenPrinter(%s)\n", r
.in
.printername
);
854 status
= dcerpc_spoolss_OpenPrinter(p
, mem_ctx
, &r
);
856 if (!NT_STATUS_IS_OK(status
)) {
857 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
861 if (!W_ERROR_IS_OK(r
.out
.result
)) {
862 printf("OpenPrinter failed - %s\n", win_errstr(r
.out
.result
));
866 if (!test_GetPrinter(p
, mem_ctx
, &handle
)) {
870 if (!test_SecondaryClosePrinter(p
, mem_ctx
, &handle
)) {
874 if (!test_ClosePrinter(p
, mem_ctx
, &handle
)) {
881 static BOOL
call_OpenPrinterEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
882 const char *name
, struct policy_handle
*handle
)
884 struct spoolss_OpenPrinterEx r
;
885 struct spoolss_UserLevel1 userlevel1
;
888 if (name
&& name
[0]) {
889 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
890 dcerpc_server_name(p
), name
);
892 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s",
893 dcerpc_server_name(p
));
896 r
.in
.datatype
= NULL
;
897 r
.in
.devmode_ctr
.size
= 0;
898 r
.in
.devmode_ctr
.devmode
= NULL
;
899 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
901 r
.in
.userlevel
.level1
= &userlevel1
;
902 r
.out
.handle
= handle
;
904 userlevel1
.size
= 1234;
905 userlevel1
.client
= "hello";
906 userlevel1
.user
= "spottyfoot!";
907 userlevel1
.build
= 1;
908 userlevel1
.major
= 2;
909 userlevel1
.minor
= 3;
910 userlevel1
.processor
= 4;
912 printf("Testing OpenPrinterEx(%s)\n", r
.in
.printername
);
914 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &r
);
916 if (!NT_STATUS_IS_OK(status
)) {
917 printf("OpenPrinterEx failed - %s\n", nt_errstr(status
));
921 if (!W_ERROR_IS_OK(r
.out
.result
)) {
922 printf("OpenPrinterEx failed - %s\n", win_errstr(r
.out
.result
));
929 static BOOL
test_OpenPrinterEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
932 struct policy_handle handle
;
935 if (!call_OpenPrinterEx(p
, mem_ctx
, name
, &handle
)) {
939 if (!test_GetPrinter(p
, mem_ctx
, &handle
)) {
943 if (!test_EnumForms(p
, mem_ctx
, &handle
)) {
947 if (!test_AddForm(p
, mem_ctx
, &handle
)) {
951 if (!test_EnumPrinterData(p
, mem_ctx
, &handle
)) {
955 if (!test_EnumPrinterDataEx(p
, mem_ctx
, &handle
)) {
959 if (!test_EnumJobs(p
, mem_ctx
, &handle
)) {
963 if (!test_SetPrinterData(p
, mem_ctx
, &handle
)) {
967 if (!test_SecondaryClosePrinter(p
, mem_ctx
, &handle
)) {
971 if (!test_ClosePrinter(p
, mem_ctx
, &handle
)) {
978 static BOOL
test_EnumPrinters(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
980 struct spoolss_EnumPrinters r
;
982 uint16_t levels
[] = {1, 2, 4, 5};
986 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
987 uint32_t buf_size
= 0;
988 union spoolss_PrinterInfo
*info
;
991 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
993 r
.in
.level
= levels
[i
];
995 r
.in
.buf_size
= &buf_size
;
996 r
.out
.buf_size
= &buf_size
;
998 printf("\nTesting EnumPrinters level %u\n", r
.in
.level
);
1000 status
= dcerpc_spoolss_EnumPrinters(p
, mem_ctx
, &r
);
1001 if (!NT_STATUS_IS_OK(status
)) {
1002 printf("EnumPrinters failed - %s\n", nt_errstr(status
));
1007 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1008 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
1009 data_blob_clear(&blob
);
1010 r
.in
.buffer
= &blob
;
1011 status
= dcerpc_spoolss_EnumPrinters(p
, mem_ctx
, &r
);
1014 if (!NT_STATUS_IS_OK(status
)) {
1015 printf("EnumPrinters failed - %s\n",
1020 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1021 printf("EnumPrinters failed - %s\n",
1022 win_errstr(r
.out
.result
));
1027 printf("No printers returned");
1033 for (j
=0;j
<r
.out
.count
;j
++) {
1034 if (r
.in
.level
== 1) {
1035 /* the names appear to be comma-separated name lists? */
1036 char *name
= talloc_strdup(mem_ctx
, info
[j
].info1
.name
);
1037 char *comma
= strchr(name
, ',');
1038 if (comma
) *comma
= 0;
1039 if (!test_OpenPrinter(p
, mem_ctx
, name
)) {
1042 if (!test_OpenPrinterEx(p
, mem_ctx
, name
)) {
1053 static BOOL
test_GetPrinterDriver2(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
1054 struct policy_handle
*handle
,
1055 const char *driver_name
)
1058 struct spoolss_GetPrinterDriver2 r
;
1061 r
.in
.handle
= handle
;
1062 r
.in
.architecture
= "W32X86";
1066 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
1067 r
.in
.client_major_version
= 0;
1068 r
.in
.client_minor_version
= 0;
1070 printf("Testing GetPrinterDriver2\n");
1072 status
= dcerpc_spoolss_GetPrinterDriver2(p
, mem_ctx
, &r
);
1074 if (!NT_STATUS_IS_OK(status
)) {
1075 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status
));
1079 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1080 status
= dcerpc_spoolss_GetPrinterDriver2(p
, mem_ctx
, &r
);
1083 if (!NT_STATUS_IS_OK(status
)) {
1084 printf("GetPrinterDriver2 failed - %s\n",
1089 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1090 printf("GetPrinterDriver2 failed - %s\n",
1091 win_errstr(r
.out
.result
));
1099 static BOOL
test_EnumPrinterDrivers(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
1101 struct spoolss_EnumPrinterDrivers r
;
1103 uint16_t levels
[] = {1, 2, 3, 4, 5, 6};
1107 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
1110 r
.in
.server
= talloc_asprintf(mem_ctx
, "\\\\%s", dcerpc_server_name(p
));
1111 r
.in
.environment
= "Windows NT x86";
1112 r
.in
.level
= levels
[i
];
1115 r
.in
.buf_size
= &buf_size
;
1116 r
.out
.buf_size
= &buf_size
;
1118 printf("\nTesting EnumPrinterDrivers level %u\n", r
.in
.level
);
1120 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, mem_ctx
, &r
);
1122 if (!NT_STATUS_IS_OK(status
)) {
1123 printf("EnumPrinterDrivers failed - %s\n",
1129 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1130 DATA_BLOB blob
= data_blob_talloc(
1131 mem_ctx
, NULL
, buf_size
);
1133 data_blob_clear(&blob
);
1134 r
.in
.buffer
= &blob
;
1135 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, mem_ctx
, &r
);
1138 if (!NT_STATUS_IS_OK(status
)) {
1139 printf("EnumPrinterDrivers failed - %s\n",
1145 if (!W_ERROR_IS_OK(r
.out
.result
)) {
1146 printf("EnumPrinterDrivers failed - %s\n",
1147 win_errstr(r
.out
.result
));
1153 printf("No printer drivers returned");
1161 BOOL
torture_rpc_spoolss(void)
1164 struct dcerpc_pipe
*p
;
1165 TALLOC_CTX
*mem_ctx
;
1168 mem_ctx
= talloc_init("torture_rpc_spoolss");
1170 status
= torture_rpc_connection(mem_ctx
,
1172 DCERPC_SPOOLSS_NAME
,
1173 DCERPC_SPOOLSS_UUID
,
1174 DCERPC_SPOOLSS_VERSION
);
1175 if (!NT_STATUS_IS_OK(status
)) {
1176 talloc_free(mem_ctx
);
1180 ret
&= test_OpenPrinter_badnames(p
, mem_ctx
);
1182 ret
&= test_AddPort(p
, mem_ctx
);
1184 ret
&= test_EnumPorts(p
, mem_ctx
);
1186 ret
&= test_EnumPrinters(p
, mem_ctx
);
1188 ret
&= test_EnumPrinterDrivers(p
, mem_ctx
);
1190 talloc_free(mem_ctx
);