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_DeletePrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
622 struct policy_handle *handle,
623 const char *value_name)
626 struct spoolss_DeletePrinterData r;
628 r.in.handle = handle;
629 r.in.value_name = value_name;
631 printf("Testing DeletePrinterData\n");
633 status = dcerpc_spoolss_DeletePrinterData(p, mem_ctx, &r);
635 if (!NT_STATUS_IS_OK(status)) {
636 printf("DeletePrinterData failed - %s\n", nt_errstr(status));
643 static BOOL test_SetPrinterData(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
644 struct policy_handle *handle)
647 struct spoolss_SetPrinterData r;
648 const char *value_name = "spottyfoot";
650 r.in.handle = handle;
651 r.in.value_name = value_name;
653 r.in.buffer = data_blob_talloc(mem_ctx, "dog", 4);
656 printf("Testing SetPrinterData\n");
658 status = dcerpc_spoolss_SetPrinterData(p, mem_ctx, &r);
660 if (!NT_STATUS_IS_OK(status)) {
661 printf("SetPrinterData failed - %s\n", nt_errstr(status));
665 if (!test_DeletePrinterData(p, mem_ctx, handle, value_name)) {
672 static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
673 struct policy_handle *handle)
676 struct dcerpc_pipe *p2;
679 /* only makes sense on SMB */
680 if (p->conn->transport.transport != NCACN_NP) {
684 printf("testing close on secondary pipe\n");
686 status = dcerpc_secondary_connection(p, &p2,
689 DCERPC_SPOOLSS_VERSION);
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("Failed to create secondary connection\n");
695 if (test_ClosePrinter(p2, mem_ctx, handle)) {
696 printf("ERROR: Allowed close on secondary connection!\n");
700 if (p2->last_fault_code != DCERPC_FAULT_CONTEXT_MISMATCH) {
701 printf("Unexpected fault code 0x%x - expected 0x%x\n",
702 p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH);
706 dcerpc_pipe_close(p2);
711 static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
714 struct spoolss_OpenPrinter op;
715 struct spoolss_OpenPrinterEx opEx;
716 struct policy_handle handle;
719 op.in.printername = name;
720 op.in.datatype = NULL;
721 op.in.devmode_ctr.size = 0;
722 op.in.devmode_ctr.devmode= NULL;
723 op.in.access_mask = 0;
724 op.out.handle = &handle;
726 printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
728 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
729 if (!NT_STATUS_IS_OK(status)) {
730 printf("OpenPrinter failed - %s\n", nt_errstr(status));
733 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
734 printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
735 name, win_errstr(op.out.result));
738 if (W_ERROR_IS_OK(op.out.result)) {
739 ret &=test_ClosePrinter(p, mem_ctx, &handle);
742 opEx.in.printername = name;
743 opEx.in.datatype = NULL;
744 opEx.in.devmode_ctr.size = 0;
745 opEx.in.devmode_ctr.devmode = NULL;
746 opEx.in.access_mask = 0;
748 opEx.in.userlevel.level1 = NULL;
749 opEx.out.handle = &handle;
751 printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
753 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
754 if (!NT_STATUS_IS_OK(status)) {
755 printf("OpenPrinter failed - %s\n", nt_errstr(status));
758 if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
759 printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
760 name, win_errstr(opEx.out.result));
763 if (W_ERROR_IS_OK(opEx.out.result)) {
764 ret &=test_ClosePrinter(p, mem_ctx, &handle);
770 static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
775 ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
776 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
777 ret &= test_OpenPrinter_badname(p, mem_ctx, "");
778 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
779 ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
781 name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
782 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
785 name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
786 ret &= test_OpenPrinter_badname(p, mem_ctx, name);
792 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
796 struct spoolss_OpenPrinter r;
797 struct policy_handle handle;
800 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
801 r.in.datatype = NULL;
802 r.in.devmode_ctr.size = 0;
803 r.in.devmode_ctr.devmode= NULL;
804 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
805 r.out.handle = &handle;
807 printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
809 status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
811 if (!NT_STATUS_IS_OK(status)) {
812 printf("OpenPrinter failed - %s\n", nt_errstr(status));
816 if (!W_ERROR_IS_OK(r.out.result)) {
817 printf("OpenPrinter failed - %s\n", win_errstr(r.out.result));
821 if (!test_GetPrinter(p, mem_ctx, &handle)) {
825 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
829 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
836 static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
837 const char *name, struct policy_handle *handle)
839 struct spoolss_OpenPrinterEx r;
840 struct spoolss_UserLevel1 userlevel1;
843 if (name && name[0]) {
844 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
845 dcerpc_server_name(p), name);
847 r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s",
848 dcerpc_server_name(p));
851 r.in.datatype = NULL;
852 r.in.devmode_ctr.size = 0;
853 r.in.devmode_ctr.devmode= NULL;
854 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
856 r.in.userlevel.level1 = &userlevel1;
857 r.out.handle = handle;
859 userlevel1.size = 1234;
860 userlevel1.client = "hello";
861 userlevel1.user = "spottyfoot!";
862 userlevel1.build = 1;
863 userlevel1.major = 2;
864 userlevel1.minor = 3;
865 userlevel1.processor = 4;
867 printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
869 status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &r);
871 if (!NT_STATUS_IS_OK(status)) {
872 printf("OpenPrinterEx failed - %s\n", nt_errstr(status));
876 if (!W_ERROR_IS_OK(r.out.result)) {
877 printf("OpenPrinterEx failed - %s\n", win_errstr(r.out.result));
884 static BOOL test_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
887 struct policy_handle handle;
890 if (!call_OpenPrinterEx(p, mem_ctx, name, &handle)) {
894 if (!test_GetPrinter(p, mem_ctx, &handle)) {
898 if (!test_EnumForms(p, mem_ctx, &handle)) {
902 if (!test_AddForm(p, mem_ctx, &handle)) {
906 if (!test_EnumPrinterData(p, mem_ctx, &handle)) {
910 if (!test_EnumJobs(p, mem_ctx, &handle)) {
914 if (!test_SetPrinterData(p, mem_ctx, &handle)) {
918 if (!test_SecondaryClosePrinter(p, mem_ctx, &handle)) {
922 if (!test_ClosePrinter(p, mem_ctx, &handle)) {
929 static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
931 struct spoolss_EnumPrinters r;
933 uint16_t levels[] = {1, 2, 4, 5};
937 for (i=0;i<ARRAY_SIZE(levels);i++) {
938 uint32_t buf_size = 0;
939 union spoolss_PrinterInfo *info;
942 r.in.flags = PRINTER_ENUM_LOCAL;
944 r.in.level = levels[i];
946 r.in.buf_size = &buf_size;
947 r.out.buf_size = &buf_size;
949 printf("\nTesting EnumPrinters level %u\n", r.in.level);
951 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
952 if (!NT_STATUS_IS_OK(status)) {
953 printf("EnumPrinters failed - %s\n", nt_errstr(status));
958 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
959 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
960 data_blob_clear(&blob);
962 status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
965 if (!NT_STATUS_IS_OK(status)) {
966 printf("EnumPrinters failed - %s\n",
971 if (!W_ERROR_IS_OK(r.out.result)) {
972 printf("EnumPrinters failed - %s\n",
973 win_errstr(r.out.result));
978 printf("No printers returned");
984 for (j=0;j<r.out.count;j++) {
985 if (r.in.level == 1) {
986 /* the names appear to be comma-separated name lists? */
987 char *name = talloc_strdup(mem_ctx, info[j].info1.name);
988 char *comma = strchr(name, ',');
989 if (comma) *comma = 0;
990 if (!test_OpenPrinter(p, mem_ctx, name)) {
993 if (!test_OpenPrinterEx(p, mem_ctx, name)) {
1004 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1005 struct policy_handle *handle,
1006 const char *driver_name)
1009 struct spoolss_GetPrinterDriver2 r;
1012 r.in.handle = handle;
1013 r.in.architecture = "W32X86";
1017 r.in.buf_size = r.out.buf_size = &buf_size;
1018 r.in.client_major_version = 0;
1019 r.in.client_minor_version = 0;
1021 printf("Testing GetPrinterDriver2\n");
1023 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
1030 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1031 status = dcerpc_spoolss_GetPrinterDriver2(p, mem_ctx, &r);
1034 if (!NT_STATUS_IS_OK(status)) {
1035 printf("GetPrinterDriver2 failed - %s\n",
1040 if (!W_ERROR_IS_OK(r.out.result)) {
1041 printf("GetPrinterDriver2 failed - %s\n",
1042 win_errstr(r.out.result));
1050 static BOOL test_EnumPrinterDrivers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
1052 struct spoolss_EnumPrinterDrivers r;
1054 uint16_t levels[] = {1, 2, 3, 4, 5, 6};
1058 for (i=0;i<ARRAY_SIZE(levels);i++) {
1061 r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1062 r.in.environment = "Windows NT x86";
1063 r.in.level = levels[i];
1066 r.in.buf_size = &buf_size;
1067 r.out.buf_size = &buf_size;
1069 printf("\nTesting EnumPrinterDrivers level %u\n", r.in.level);
1071 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
1073 if (!NT_STATUS_IS_OK(status)) {
1074 printf("EnumPrinterDrivers failed - %s\n",
1080 if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
1081 DATA_BLOB blob = data_blob_talloc(
1082 mem_ctx, NULL, buf_size);
1084 data_blob_clear(&blob);
1085 r.in.buffer = &blob;
1086 status = dcerpc_spoolss_EnumPrinterDrivers(p, mem_ctx, &r);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 printf("EnumPrinterDrivers failed - %s\n",
1096 if (!W_ERROR_IS_OK(r.out.result)) {
1097 printf("EnumPrinterDrivers failed - %s\n",
1098 win_errstr(r.out.result));
1104 printf("No printer drivers returned");
1112 BOOL torture_rpc_spoolss(void)
1115 struct dcerpc_pipe *p;
1116 TALLOC_CTX *mem_ctx;
1119 status = torture_rpc_connection(&p,
1120 DCERPC_SPOOLSS_NAME,
1121 DCERPC_SPOOLSS_UUID,
1122 DCERPC_SPOOLSS_VERSION);
1123 if (!NT_STATUS_IS_OK(status)) {
1127 mem_ctx = talloc_init("torture_rpc_spoolss");
1129 ret &= test_OpenPrinter_badnames(p, mem_ctx);
1131 ret &= test_AddPort(p, mem_ctx);
1133 ret &= test_EnumPorts(p, mem_ctx);
1135 ret &= test_EnumPrinters(p, mem_ctx);
1137 ret &= test_EnumPrinterDrivers(p, mem_ctx);
1139 talloc_free(mem_ctx);
1141 torture_rpc_close(p);