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");
735 dcerpc_pipe_close(p2);
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);
751 dcerpc_pipe_close(p2);
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 status = torture_rpc_connection(&p,
1169 DCERPC_SPOOLSS_NAME,
1170 DCERPC_SPOOLSS_UUID,
1171 DCERPC_SPOOLSS_VERSION);
1172 if (!NT_STATUS_IS_OK(status)) {
1176 mem_ctx = talloc_init("torture_rpc_spoolss");
1178 ret &= test_OpenPrinter_badnames(p, mem_ctx);
1180 ret &= test_AddPort(p, mem_ctx);
1182 ret &= test_EnumPorts(p, mem_ctx);
1184 ret &= test_EnumPrinters(p, mem_ctx);
1186 ret &= test_EnumPrinterDrivers(p, mem_ctx);
1188 talloc_free(mem_ctx);
1190 torture_rpc_close(p);