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 !W_ERROR_IS_OK(r
.out
.result
)) {
60 printf("GetPrinter failed - %s/%s\n",
61 nt_errstr(status
), win_errstr(r
.out
.result
));
71 static BOOL
test_ClosePrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
72 struct policy_handle
*handle
)
75 struct spoolss_ClosePrinter r
;
78 r
.out
.handle
= handle
;
80 printf("Testing ClosePrinter\n");
82 status
= dcerpc_spoolss_ClosePrinter(p
, mem_ctx
, &r
);
83 if (!NT_STATUS_IS_OK(status
)) {
84 printf("ClosePrinter failed - %s\n", nt_errstr(status
));
91 static BOOL
test_GetForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
92 struct policy_handle
*handle
,
96 struct spoolss_GetForm r
;
100 r
.in
.formname
= formname
;
104 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
106 printf("Testing GetForm\n");
108 status
= dcerpc_spoolss_GetForm(p
, mem_ctx
, &r
);
110 if (!NT_STATUS_IS_OK(status
)) {
111 printf("GetForm failed - %s\n", nt_errstr(status
));
115 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
116 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
118 data_blob_clear(&blob
);
121 status
= dcerpc_spoolss_GetForm(p
, mem_ctx
, &r
);
124 printf("No form info returned");
132 static BOOL
test_EnumForms(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
133 struct policy_handle
*handle
)
136 struct spoolss_EnumForms r
;
139 r
.in
.handle
= handle
;
143 r
.in
.buf_size
= &buf_size
;
144 r
.out
.buf_size
= &buf_size
;
146 printf("Testing EnumForms\n");
148 status
= dcerpc_spoolss_EnumForms(p
, mem_ctx
, &r
);
150 if (!NT_STATUS_IS_OK(status
)) {
151 printf("EnumForms failed - %s\n", nt_errstr(status
));
155 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
156 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
157 union spoolss_FormInfo
*info
;
160 data_blob_clear(&blob
);
163 status
= dcerpc_spoolss_EnumForms(p
, mem_ctx
, &r
);
166 printf("No forms returned");
172 for (j
= 0; j
< r
.out
.count
; j
++) {
173 test_GetForm(p
, mem_ctx
, handle
, info
[j
].info1
.formname
);
177 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
178 printf("EnumForms failed - %s/%s\n",
179 nt_errstr(status
), win_errstr(r
.out
.result
));
186 static BOOL
test_DeleteForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
187 struct policy_handle
*handle
,
188 const char *formname
)
191 struct spoolss_DeleteForm r
;
193 r
.in
.handle
= handle
;
194 r
.in
.formname
= formname
;
196 status
= dcerpc_spoolss_DeleteForm(p
, mem_ctx
, &r
);
198 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
199 printf("DeleteForm failed - %s/%s\n",
200 nt_errstr(status
), win_errstr(r
.out
.result
));
207 static BOOL
test_AddForm(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
208 struct policy_handle
*handle
)
210 struct spoolss_AddForm r
;
211 struct spoolss_AddFormInfo1 form
;
213 const char *formname
= "testform3";
216 r
.in
.handle
= handle
;
218 form
.flags
= 2; /* User form */
219 form
.formname
= formname
;
226 r
.in
.info
.info1
= &form
;
228 status
= dcerpc_spoolss_AddForm(p
, mem_ctx
, &r
);
230 if (!NT_STATUS_IS_OK(status
)) {
231 printf("AddForm failed - %s\n", nt_errstr(status
));
235 if (!W_ERROR_IS_OK(r
.out
.result
)) {
236 printf("AddForm failed - %s\n", nt_errstr(status
));
241 struct spoolss_SetForm sf
;
243 sf
.in
.handle
= handle
;
244 sf
.in
.formname
= formname
;
246 sf
.in
.info
.info1
= &form
;
249 status
= dcerpc_spoolss_SetForm(p
, mem_ctx
, &sf
);
251 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
252 printf("SetForm failed - %s/%s\n",
253 nt_errstr(status
), win_errstr(r
.out
.result
));
255 /* Fall through to delete */
260 if (!test_DeleteForm(p
, mem_ctx
, handle
, formname
)) {
261 printf("DeleteForm failed\n");
268 static BOOL
test_EnumPorts(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
271 struct spoolss_EnumPorts r
;
274 r
.in
.servername
= talloc_asprintf(mem_ctx
, "\\\\%s",
275 dcerpc_server_name(p
));
279 r
.in
.buf_size
= &buf_size
;
280 r
.out
.buf_size
= &buf_size
;
282 printf("Testing EnumPorts\n");
284 status
= dcerpc_spoolss_EnumPorts(p
, mem_ctx
, &r
);
286 if (!NT_STATUS_IS_OK(status
)) {
287 printf("EnumPorts failed -- %s\n", nt_errstr(status
));
291 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
292 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
294 data_blob_clear(&blob
);
297 status
= dcerpc_spoolss_EnumPorts(p
, mem_ctx
, &r
);
299 if (!NT_STATUS_IS_OK(status
)) {
300 printf("EnumPorts failed -- %s\n", nt_errstr(status
));
305 printf("No ports returned");
313 static BOOL
test_GetJob(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
314 struct policy_handle
*handle
, uint32_t job_id
)
317 struct spoolss_GetJob r
;
320 r
.in
.handle
= handle
;
321 r
.in
.job_id
= job_id
;
325 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
327 printf("Testing GetJob\n");
329 status
= dcerpc_spoolss_GetJob(p
, mem_ctx
, &r
);
331 if (!NT_STATUS_IS_OK(status
)) {
332 printf("GetJob failed - %s\n", nt_errstr(status
));
336 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
337 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
339 data_blob_clear(&blob
);
342 status
= dcerpc_spoolss_GetJob(p
, mem_ctx
, &r
);
345 printf("No job info returned");
353 static BOOL
test_SetJob(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
354 struct policy_handle
*handle
, uint32_t job_id
, uint32_t command
)
357 struct spoolss_SetJob r
;
359 r
.in
.handle
= handle
;
360 r
.in
.job_id
= job_id
;
362 r
.in
.command
= command
;
364 printf("Testing SetJob\n");
366 status
= dcerpc_spoolss_SetJob(p
, mem_ctx
, &r
);
368 if (!NT_STATUS_IS_OK(status
)) {
369 printf("SetJob failed - %s\n", nt_errstr(status
));
376 static BOOL
test_EnumJobs(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
377 struct policy_handle
*handle
)
380 struct spoolss_EnumJobs r
;
383 r
.in
.handle
= handle
;
385 r
.in
.numjobs
= 0xffffffff;
389 r
.in
.buf_size
= &buf_size
;
390 r
.out
.buf_size
= &buf_size
;
392 printf("Testing EnumJobs\n");
394 status
= dcerpc_spoolss_EnumJobs(p
, mem_ctx
, &r
);
396 if (!NT_STATUS_IS_OK(status
)) {
397 printf("EnumJobs failed - %s\n", nt_errstr(status
));
401 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
402 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
403 union spoolss_JobInfo
*info
;
406 data_blob_clear(&blob
);
409 status
= dcerpc_spoolss_EnumJobs(p
, mem_ctx
, &r
);
412 printf("No jobs returned");
418 for (j
= 0; j
< r
.out
.count
; j
++) {
419 test_GetJob(p
, mem_ctx
, handle
, info
[j
].info1
.job_id
);
420 test_SetJob(p
, mem_ctx
, handle
, info
[j
].info1
.job_id
, 1);
423 } else if (!W_ERROR_IS_OK(r
.out
.result
)) {
424 printf("EnumJobs failed - %s\n", win_errstr(r
.out
.result
));
431 static BOOL
test_GetPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
432 struct policy_handle
*handle
,
433 const char *value_name
)
436 struct spoolss_GetPrinterData r
;
439 r
.in
.handle
= handle
;
440 r
.in
.value_name
= value_name
;
442 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
444 printf("Testing GetPrinterData\n");
446 status
= dcerpc_spoolss_GetPrinterData(p
, mem_ctx
, &r
);
448 if (!NT_STATUS_IS_OK(status
)) {
449 printf("GetPrinterData failed - %s\n", nt_errstr(status
));
453 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
455 status
= dcerpc_spoolss_GetPrinterData(p
, mem_ctx
, &r
);
457 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
458 printf("GetPrinterData failed - %s/%s\n",
459 nt_errstr(status
), win_errstr(r
.out
.result
));
467 static BOOL
test_GetPrinterDataEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
468 struct policy_handle
*handle
,
469 const char *key_name
,
470 const char *value_name
)
473 struct spoolss_GetPrinterDataEx r
;
476 r
.in
.handle
= handle
;
477 r
.in
.key_name
= key_name
;
478 r
.in
.value_name
= value_name
;
480 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
482 printf("Testing GetPrinterDataEx\n");
484 status
= dcerpc_spoolss_GetPrinterDataEx(p
, mem_ctx
, &r
);
485 if (!NT_STATUS_IS_OK(status
)) {
486 if (NT_STATUS_EQUAL(status
,NT_STATUS_NET_WRITE_FAULT
) &&
487 p
->last_fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
488 printf("GetPrinterDataEx not supported by server\n");
491 printf("GetPrinterDataEx failed - %s\n", nt_errstr(status
));
495 if (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
)) {
497 status
= dcerpc_spoolss_GetPrinterDataEx(p
, mem_ctx
, &r
);
499 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
500 printf("GetPrinterDataEx failed - %s/%s\n",
501 nt_errstr(status
), win_errstr(r
.out
.result
));
509 static BOOL
test_EnumPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
510 struct policy_handle
*handle
)
513 struct spoolss_EnumPrinterData r
;
515 r
.in
.handle
= handle
;
521 r
.in
.value_offered
= 0;
523 r
.in
.data_size
= &data_size
;
524 r
.out
.data_size
= &data_size
;
526 printf("Testing EnumPrinterData\n");
528 status
= dcerpc_spoolss_EnumPrinterData(p
, mem_ctx
, &r
);
530 if (!NT_STATUS_IS_OK(status
)) {
531 printf("EnumPrinterData failed - %s\n", nt_errstr(status
));
535 r
.in
.value_offered
= r
.out
.value_needed
;
537 status
= dcerpc_spoolss_EnumPrinterData(p
, mem_ctx
, &r
);
539 if (!NT_STATUS_IS_OK(status
)) {
540 printf("EnumPrinterData failed - %s\n", nt_errstr(status
));
544 test_GetPrinterData(p
, mem_ctx
, handle
, r
.out
.value_name
);
546 test_GetPrinterDataEx(
547 p
, mem_ctx
, handle
, "PrinterDriverData",
552 } while (W_ERROR_IS_OK(r
.out
.result
));
557 static BOOL
test_DeletePrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
558 struct policy_handle
*handle
,
559 const char *value_name
)
562 struct spoolss_DeletePrinterData r
;
564 r
.in
.handle
= handle
;
565 r
.in
.value_name
= value_name
;
567 printf("Testing DeletePrinterData\n");
569 status
= dcerpc_spoolss_DeletePrinterData(p
, mem_ctx
, &r
);
571 if (!NT_STATUS_IS_OK(status
)) {
572 printf("DeletePrinterData failed - %s\n", nt_errstr(status
));
579 static BOOL
test_SetPrinterData(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
580 struct policy_handle
*handle
)
583 struct spoolss_SetPrinterData r
;
584 const char *value_name
= "spottyfoot";
586 r
.in
.handle
= handle
;
587 r
.in
.value_name
= value_name
;
589 r
.in
.buffer
= data_blob_talloc(mem_ctx
, "dog", 4);
592 printf("Testing SetPrinterData\n");
594 status
= dcerpc_spoolss_SetPrinterData(p
, mem_ctx
, &r
);
596 if (!NT_STATUS_IS_OK(status
)) {
597 printf("SetPrinterData failed - %s\n", nt_errstr(status
));
601 if (!test_DeletePrinterData(p
, mem_ctx
, handle
, value_name
)) {
608 static BOOL
test_SecondaryClosePrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
609 struct policy_handle
*handle
)
612 struct dcerpc_pipe
*p2
;
615 /* only makes sense on SMB */
616 if (p
->conn
->transport
.transport
!= NCACN_NP
) {
620 printf("testing close on secondary pipe\n");
622 status
= dcerpc_secondary_connection(p
, &p2
,
625 DCERPC_SPOOLSS_VERSION
);
626 if (!NT_STATUS_IS_OK(status
)) {
627 printf("Failed to create secondary connection\n");
631 if (test_ClosePrinter(p2
, mem_ctx
, handle
)) {
632 printf("ERROR: Allowed close on secondary connection!\n");
636 if (p2
->last_fault_code
!= DCERPC_FAULT_CONTEXT_MISMATCH
) {
637 printf("Unexpected fault code 0x%x - expected 0x%x\n",
638 p2
->last_fault_code
, DCERPC_FAULT_CONTEXT_MISMATCH
);
642 dcerpc_pipe_close(p2
);
647 static BOOL
test_OpenPrinter_badname(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
, const char *name
)
650 struct spoolss_OpenPrinter op
;
651 struct spoolss_OpenPrinterEx opEx
;
652 struct policy_handle handle
;
655 op
.in
.printername
= name
;
656 op
.in
.datatype
= NULL
;
657 op
.in
.devmode_ctr
.size
= 0;
658 op
.in
.devmode_ctr
.devmode
= NULL
;
659 op
.in
.access_mask
= 0;
660 op
.out
.handle
= &handle
;
662 printf("\nTesting OpenPrinter(%s) with bad name\n", op
.in
.printername
);
664 status
= dcerpc_spoolss_OpenPrinter(p
, mem_ctx
, &op
);
665 if (!NT_STATUS_IS_OK(status
)) {
666 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
669 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,op
.out
.result
)) {
670 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
671 name
, win_errstr(op
.out
.result
));
674 if (W_ERROR_IS_OK(op
.out
.result
)) {
675 ret
&=test_ClosePrinter(p
, mem_ctx
, &handle
);
678 opEx
.in
.printername
= name
;
679 opEx
.in
.datatype
= NULL
;
680 opEx
.in
.devmode_ctr
.size
= 0;
681 opEx
.in
.devmode_ctr
.devmode
= NULL
;
682 opEx
.in
.access_mask
= 0;
684 opEx
.in
.userlevel
.level1
= NULL
;
685 opEx
.out
.handle
= &handle
;
687 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx
.in
.printername
);
689 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &opEx
);
690 if (!NT_STATUS_IS_OK(status
)) {
691 printf("OpenPrinter failed - %s\n", nt_errstr(status
));
694 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME
,opEx
.out
.result
)) {
695 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
696 name
, win_errstr(opEx
.out
.result
));
699 if (W_ERROR_IS_OK(opEx
.out
.result
)) {
700 ret
&=test_ClosePrinter(p
, mem_ctx
, &handle
);
706 static BOOL
test_OpenPrinter_badnames(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
711 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "__INVALID_PRINTER__");
712 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\127.0.0.1");
713 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "\\\\localhost");
714 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, "");
716 name
= talloc_asprintf(mem_ctx
, "\\\\%s\\", dcerpc_server_name(p
));
717 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, name
);
720 name
= talloc_asprintf(mem_ctx
, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p
));
721 ret
&= test_OpenPrinter_badname(p
, mem_ctx
, name
);
727 static BOOL
test_OpenPrinter(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
731 struct spoolss_OpenPrinter r
;
732 struct policy_handle handle
;
735 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s", dcerpc_server_name(p
), name
);
736 r
.in
.datatype
= NULL
;
737 r
.in
.devmode_ctr
.size
= 0;
738 r
.in
.devmode_ctr
.devmode
= NULL
;
739 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
740 r
.out
.handle
= &handle
;
742 printf("\nTesting OpenPrinter(%s)\n", r
.in
.printername
);
744 status
= dcerpc_spoolss_OpenPrinter(p
, mem_ctx
, &r
);
745 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
746 printf("OpenPrinter failed - %s/%s\n",
747 nt_errstr(status
), win_errstr(r
.out
.result
));
751 if (!test_GetPrinter(p
, mem_ctx
, &handle
)) {
755 if (!test_SecondaryClosePrinter(p
, mem_ctx
, &handle
)) {
759 if (!test_ClosePrinter(p
, mem_ctx
, &handle
)) {
766 static BOOL
call_OpenPrinterEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
767 const char *name
, struct policy_handle
*handle
)
769 struct spoolss_OpenPrinterEx r
;
770 struct spoolss_UserLevel1 userlevel1
;
773 if (name
&& name
[0]) {
774 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\%s",
775 dcerpc_server_name(p
), name
);
777 r
.in
.printername
= talloc_asprintf(mem_ctx
, "\\\\%s",
778 dcerpc_server_name(p
));
781 r
.in
.datatype
= NULL
;
782 r
.in
.devmode_ctr
.size
= 0;
783 r
.in
.devmode_ctr
.devmode
= NULL
;
784 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
786 r
.in
.userlevel
.level1
= &userlevel1
;
787 r
.out
.handle
= handle
;
789 userlevel1
.size
= 1234;
790 userlevel1
.client
= "hello";
791 userlevel1
.user
= "spottyfoot!";
792 userlevel1
.build
= 1;
793 userlevel1
.major
= 2;
794 userlevel1
.minor
= 3;
795 userlevel1
.processor
= 4;
797 printf("Testing OpenPrinterEx(%s)\n", r
.in
.printername
);
799 status
= dcerpc_spoolss_OpenPrinterEx(p
, mem_ctx
, &r
);
801 if (!NT_STATUS_IS_OK(status
)) {
802 printf("OpenPrinterEx failed - %s\n", nt_errstr(status
));
806 if (!W_ERROR_IS_OK(r
.out
.result
)) {
807 printf("OpenPrinterEx failed - %s\n", win_errstr(r
.out
.result
));
814 static BOOL
test_OpenPrinterEx(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
817 struct policy_handle handle
;
820 if (!call_OpenPrinterEx(p
, mem_ctx
, name
, &handle
)) {
824 if (!test_GetPrinter(p
, mem_ctx
, &handle
)) {
828 if (!test_EnumForms(p
, mem_ctx
, &handle
)) {
832 if (!test_AddForm(p
, mem_ctx
, &handle
)) {
836 if (!test_EnumPrinterData(p
, mem_ctx
, &handle
)) {
840 if (!test_EnumJobs(p
, mem_ctx
, &handle
)) {
844 if (!test_SetPrinterData(p
, mem_ctx
, &handle
)) {
848 if (!test_SecondaryClosePrinter(p
, mem_ctx
, &handle
)) {
852 if (!test_ClosePrinter(p
, mem_ctx
, &handle
)) {
859 static BOOL
test_EnumPrinters(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
861 struct spoolss_EnumPrinters r
;
863 uint16_t levels
[] = {1, 2, 4, 5};
867 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
868 uint32_t buf_size
= 0;
869 union spoolss_PrinterInfo
*info
;
872 r
.in
.flags
= PRINTER_ENUM_LOCAL
;
874 r
.in
.level
= levels
[i
];
876 r
.in
.buf_size
= &buf_size
;
877 r
.out
.buf_size
= &buf_size
;
879 printf("\nTesting EnumPrinters level %u\n", r
.in
.level
);
881 status
= dcerpc_spoolss_EnumPrinters(p
, mem_ctx
, &r
);
882 if (!NT_STATUS_IS_OK(status
)) {
883 printf("EnumPrinters failed - %s\n", nt_errstr(status
));
888 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
889 DATA_BLOB blob
= data_blob_talloc(mem_ctx
, NULL
, buf_size
);
890 data_blob_clear(&blob
);
892 status
= dcerpc_spoolss_EnumPrinters(p
, mem_ctx
, &r
);
895 if (!NT_STATUS_IS_OK(status
) ||
896 !W_ERROR_IS_OK(r
.out
.result
)) {
897 printf("EnumPrinters failed - %s/%s\n",
898 nt_errstr(status
), win_errstr(r
.out
.result
));
903 printf("No printers returned");
909 for (j
=0;j
<r
.out
.count
;j
++) {
910 if (r
.in
.level
== 1) {
911 /* the names appear to be comma-separated name lists? */
912 char *name
= talloc_strdup(mem_ctx
, info
[j
].info1
.name
);
913 char *comma
= strchr(name
, ',');
914 if (comma
) *comma
= 0;
915 if (!test_OpenPrinter(p
, mem_ctx
, name
)) {
918 if (!test_OpenPrinterEx(p
, mem_ctx
, name
)) {
929 static BOOL
test_GetPrinterDriver2(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
,
930 struct policy_handle
*handle
,
931 const char *driver_name
)
934 struct spoolss_GetPrinterDriver2 r
;
937 r
.in
.handle
= handle
;
938 r
.in
.architecture
= "W32X86";
942 r
.in
.buf_size
= r
.out
.buf_size
= &buf_size
;
943 r
.in
.client_major_version
= 0;
944 r
.in
.client_minor_version
= 0;
946 printf("Testing GetPrinterDriver2\n");
948 status
= dcerpc_spoolss_GetPrinterDriver2(p
, mem_ctx
, &r
);
950 if (!NT_STATUS_IS_OK(status
)) {
951 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status
));
955 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
956 status
= dcerpc_spoolss_GetPrinterDriver2(p
, mem_ctx
, &r
);
959 if (!NT_STATUS_IS_OK(status
) ||
960 !W_ERROR_IS_OK(r
.out
.result
)) {
961 printf("GetPrinterDriver2 failed - %s/%s\n",
962 nt_errstr(status
), win_errstr(r
.out
.result
));
970 static BOOL
test_EnumPrinterDrivers(struct dcerpc_pipe
*p
, TALLOC_CTX
*mem_ctx
)
972 struct spoolss_EnumPrinterDrivers r
;
974 uint16_t levels
[] = {1, 2, 3, 4, 5, 6};
978 for (i
=0;i
<ARRAY_SIZE(levels
);i
++) {
981 r
.in
.server
= talloc_asprintf(mem_ctx
, "\\\\%s", dcerpc_server_name(p
));
982 r
.in
.environment
= "Windows NT x86";
983 r
.in
.level
= levels
[i
];
986 r
.in
.buf_size
= &buf_size
;
987 r
.out
.buf_size
= &buf_size
;
989 printf("\nTesting EnumPrinterDrivers level %u\n", r
.in
.level
);
991 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, mem_ctx
, &r
);
993 if (!NT_STATUS_IS_OK(status
)) {
994 printf("EnumPrinterDrivers failed - %s\n",
1000 if (W_ERROR_EQUAL(r
.out
.result
, WERR_INSUFFICIENT_BUFFER
)) {
1001 DATA_BLOB blob
= data_blob_talloc(
1002 mem_ctx
, NULL
, buf_size
);
1004 data_blob_clear(&blob
);
1005 r
.in
.buffer
= &blob
;
1006 status
= dcerpc_spoolss_EnumPrinterDrivers(p
, mem_ctx
, &r
);
1009 if (!NT_STATUS_IS_OK(status
) ||
1010 !W_ERROR_IS_OK(r
.out
.result
)) {
1011 printf("EnumPrinterDrivers failed - %s/%s\n",
1012 nt_errstr(status
), win_errstr(r
.out
.result
));
1018 printf("No printer drivers returned");
1026 BOOL
torture_rpc_spoolss(void)
1029 struct dcerpc_pipe
*p
;
1030 TALLOC_CTX
*mem_ctx
;
1033 status
= torture_rpc_connection(&p
,
1034 DCERPC_SPOOLSS_NAME
,
1035 DCERPC_SPOOLSS_UUID
,
1036 DCERPC_SPOOLSS_VERSION
);
1037 if (!NT_STATUS_IS_OK(status
)) {
1041 mem_ctx
= talloc_init("torture_rpc_spoolss");
1043 ret
&= test_OpenPrinter_badnames(p
, mem_ctx
);
1045 ret
&= test_EnumPorts(p
, mem_ctx
);
1047 ret
&= test_EnumPrinters(p
, mem_ctx
);
1049 ret
&= test_EnumPrinterDrivers(p
, mem_ctx
);
1051 talloc_free(mem_ctx
);
1053 torture_rpc_close(p
);