2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005,
6 Copyright (C) Tim Potter 2000-2002,
7 Copyright (C) Andrew Tridgell 1994-2000,
8 Copyright (C) Jean-Francois Micouleau 1999-2000.
9 Copyright (C) Jeremy Allison 2005.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "rpc_client/rpc_client.h"
27 #include "../librpc/gen_ndr/ndr_spoolss_c.h"
28 #include "rpc_client/cli_spoolss.h"
29 #include "auth/gensec/gensec.h"
30 #include "auth/credentials/credentials.h"
31 #include "rpc_client/init_spoolss.h"
33 /**********************************************************************
34 convenience wrapper around rpccli_spoolss_OpenPrinterEx
35 **********************************************************************/
37 WERROR
rpccli_spoolss_openprinter_ex(struct rpc_pipe_client
*cli
,
39 const char *printername
,
40 uint32_t access_desired
,
41 struct policy_handle
*handle
)
45 struct spoolss_DevmodeContainer devmode_ctr
;
46 struct spoolss_UserLevelCtr userlevel_ctr
;
47 struct spoolss_UserLevel1 level1
;
48 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
50 ZERO_STRUCT(devmode_ctr
);
52 werror
= spoolss_init_spoolss_UserLevel1(mem_ctx
,
53 cli
->printer_username
,
55 if (!W_ERROR_IS_OK(werror
)) {
59 userlevel_ctr
.level
= 1;
60 userlevel_ctr
.user_info
.level1
= &level1
;
62 status
= dcerpc_spoolss_OpenPrinterEx(b
, mem_ctx
,
71 if (!NT_STATUS_IS_OK(status
)) {
72 return ntstatus_to_werror(status
);
75 if (!W_ERROR_IS_OK(werror
)) {
82 /**********************************************************************
83 convenience wrapper around rpccli_spoolss_GetPrinterDriver
84 **********************************************************************/
86 WERROR
rpccli_spoolss_getprinterdriver(struct rpc_pipe_client
*cli
,
88 struct policy_handle
*handle
,
89 const char *architecture
,
92 union spoolss_DriverInfo
*info
)
98 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
101 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
102 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
105 status
= dcerpc_spoolss_GetPrinterDriver(b
, mem_ctx
,
109 (offered
> 0) ? &buffer
: NULL
,
114 if (!NT_STATUS_IS_OK(status
)) {
115 return ntstatus_to_werror(status
);
117 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
119 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
120 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
122 status
= dcerpc_spoolss_GetPrinterDriver(b
, mem_ctx
,
132 if (!NT_STATUS_IS_OK(status
)) {
133 return ntstatus_to_werror(status
);
139 /**********************************************************************
140 convenience wrapper around rpccli_spoolss_GetPrinterDriver2
141 **********************************************************************/
143 WERROR
rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client
*cli
,
145 struct policy_handle
*handle
,
146 const char *architecture
,
149 uint32_t client_major_version
,
150 uint32_t client_minor_version
,
151 union spoolss_DriverInfo
*info
,
152 uint32_t *server_major_version
,
153 uint32_t *server_minor_version
)
159 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
162 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
163 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
166 status
= dcerpc_spoolss_GetPrinterDriver2(b
, mem_ctx
,
170 (offered
> 0) ? &buffer
: NULL
,
172 client_major_version
,
173 client_minor_version
,
176 server_major_version
,
177 server_minor_version
,
179 if (!NT_STATUS_IS_OK(status
)) {
180 return ntstatus_to_werror(status
);
183 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
185 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
186 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
188 status
= dcerpc_spoolss_GetPrinterDriver2(b
, mem_ctx
,
194 client_major_version
,
195 client_minor_version
,
198 server_major_version
,
199 server_minor_version
,
202 if (!NT_STATUS_IS_OK(status
)) {
203 return ntstatus_to_werror(status
);
209 /**********************************************************************
210 convenience wrapper around rpccli_spoolss_AddPrinterEx
211 **********************************************************************/
213 WERROR
rpccli_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
215 struct spoolss_SetPrinterInfoCtr
*info_ctr
)
219 struct spoolss_DevmodeContainer devmode_ctr
;
220 struct sec_desc_buf secdesc_ctr
;
221 struct spoolss_UserLevelCtr userlevel_ctr
;
222 struct spoolss_UserLevel1 level1
;
223 struct policy_handle handle
;
224 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
226 ZERO_STRUCT(devmode_ctr
);
227 ZERO_STRUCT(secdesc_ctr
);
229 result
= spoolss_init_spoolss_UserLevel1(mem_ctx
,
230 cli
->printer_username
,
232 if (!W_ERROR_IS_OK(result
)) {
236 userlevel_ctr
.level
= 1;
237 userlevel_ctr
.user_info
.level1
= &level1
;
239 status
= dcerpc_spoolss_AddPrinterEx(b
, mem_ctx
,
247 if (!NT_STATUS_IS_OK(status
)) {
248 return ntstatus_to_werror(status
);
254 /**********************************************************************
255 convenience wrapper around rpccli_spoolss_GetPrinter
256 **********************************************************************/
258 WERROR
rpccli_spoolss_getprinter(struct rpc_pipe_client
*cli
,
260 struct policy_handle
*handle
,
263 union spoolss_PrinterInfo
*info
)
269 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
272 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
273 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
276 status
= dcerpc_spoolss_GetPrinter(b
, mem_ctx
,
279 (offered
> 0) ? &buffer
: NULL
,
284 if (!NT_STATUS_IS_OK(status
)) {
285 return ntstatus_to_werror(status
);
288 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
291 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
292 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
294 status
= dcerpc_spoolss_GetPrinter(b
, mem_ctx
,
303 if (!NT_STATUS_IS_OK(status
)) {
304 return ntstatus_to_werror(status
);
310 /**********************************************************************
311 convenience wrapper around rpccli_spoolss_GetJob
312 **********************************************************************/
314 WERROR
rpccli_spoolss_getjob(struct rpc_pipe_client
*cli
,
316 struct policy_handle
*handle
,
320 union spoolss_JobInfo
*info
)
326 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
329 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
330 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
333 status
= dcerpc_spoolss_GetJob(b
, mem_ctx
,
337 (offered
> 0) ? &buffer
: NULL
,
342 if (!NT_STATUS_IS_OK(status
)) {
343 return ntstatus_to_werror(status
);
346 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
348 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
349 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
351 status
= dcerpc_spoolss_GetJob(b
, mem_ctx
,
361 if (!NT_STATUS_IS_OK(status
)) {
362 return ntstatus_to_werror(status
);
368 /**********************************************************************
369 convenience wrapper around rpccli_spoolss_EnumForms
370 **********************************************************************/
372 WERROR
rpccli_spoolss_enumforms(struct rpc_pipe_client
*cli
,
374 struct policy_handle
*handle
,
378 union spoolss_FormInfo
**info
)
384 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
387 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
388 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
391 status
= dcerpc_spoolss_EnumForms(b
, mem_ctx
,
394 (offered
> 0) ? &buffer
: NULL
,
400 if (!NT_STATUS_IS_OK(status
)) {
401 return ntstatus_to_werror(status
);
404 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
406 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
407 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
409 status
= dcerpc_spoolss_EnumForms(b
, mem_ctx
,
412 (offered
> 0) ? &buffer
: NULL
,
419 if (!NT_STATUS_IS_OK(status
)) {
420 return ntstatus_to_werror(status
);
426 /**********************************************************************
427 convenience wrapper around rpccli_spoolss_EnumPrintProcessors
428 **********************************************************************/
430 WERROR
rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client
*cli
,
432 const char *servername
,
433 const char *environment
,
437 union spoolss_PrintProcessorInfo
**info
)
443 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
446 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
447 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
450 status
= dcerpc_spoolss_EnumPrintProcessors(b
, mem_ctx
,
454 (offered
> 0) ? &buffer
: NULL
,
460 if (!NT_STATUS_IS_OK(status
)) {
461 return ntstatus_to_werror(status
);
464 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
466 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
467 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
469 status
= dcerpc_spoolss_EnumPrintProcessors(b
, mem_ctx
,
473 (offered
> 0) ? &buffer
: NULL
,
480 if (!NT_STATUS_IS_OK(status
)) {
481 return ntstatus_to_werror(status
);
487 /**********************************************************************
488 convenience wrapper around rpccli_spoolss_EnumPrintProcessorDataTypes
489 **********************************************************************/
491 WERROR
rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client
*cli
,
493 const char *servername
,
494 const char *print_processor_name
,
498 union spoolss_PrintProcDataTypesInfo
**info
)
504 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
507 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
508 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
511 status
= dcerpc_spoolss_EnumPrintProcessorDataTypes(b
, mem_ctx
,
513 print_processor_name
,
515 (offered
> 0) ? &buffer
: NULL
,
521 if (!NT_STATUS_IS_OK(status
)) {
522 return ntstatus_to_werror(status
);
525 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
527 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
528 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
530 status
= dcerpc_spoolss_EnumPrintProcessorDataTypes(b
, mem_ctx
,
532 print_processor_name
,
534 (offered
> 0) ? &buffer
: NULL
,
541 if (!NT_STATUS_IS_OK(status
)) {
542 return ntstatus_to_werror(status
);
548 /**********************************************************************
549 convenience wrapper around rpccli_spoolss_EnumPorts
550 **********************************************************************/
552 WERROR
rpccli_spoolss_enumports(struct rpc_pipe_client
*cli
,
554 const char *servername
,
558 union spoolss_PortInfo
**info
)
564 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
567 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
568 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
571 status
= dcerpc_spoolss_EnumPorts(b
, mem_ctx
,
574 (offered
> 0) ? &buffer
: NULL
,
580 if (!NT_STATUS_IS_OK(status
)) {
581 return ntstatus_to_werror(status
);
584 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
586 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
587 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
589 status
= dcerpc_spoolss_EnumPorts(b
, mem_ctx
,
592 (offered
> 0) ? &buffer
: NULL
,
599 if (!NT_STATUS_IS_OK(status
)) {
600 return ntstatus_to_werror(status
);
606 /**********************************************************************
607 convenience wrapper around rpccli_spoolss_EnumMonitors
608 **********************************************************************/
610 WERROR
rpccli_spoolss_enummonitors(struct rpc_pipe_client
*cli
,
612 const char *servername
,
616 union spoolss_MonitorInfo
**info
)
622 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
625 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
626 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
629 status
= dcerpc_spoolss_EnumMonitors(b
, mem_ctx
,
632 (offered
> 0) ? &buffer
: NULL
,
638 if (!NT_STATUS_IS_OK(status
)) {
639 return ntstatus_to_werror(status
);
642 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
644 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
645 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
647 status
= dcerpc_spoolss_EnumMonitors(b
, mem_ctx
,
650 (offered
> 0) ? &buffer
: NULL
,
657 if (!NT_STATUS_IS_OK(status
)) {
658 return ntstatus_to_werror(status
);
664 /**********************************************************************
665 convenience wrapper around rpccli_spoolss_EnumJobs
666 **********************************************************************/
668 WERROR
rpccli_spoolss_enumjobs(struct rpc_pipe_client
*cli
,
670 struct policy_handle
*handle
,
676 union spoolss_JobInfo
**info
)
682 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
685 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
686 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
689 status
= dcerpc_spoolss_EnumJobs(b
, mem_ctx
,
694 (offered
> 0) ? &buffer
: NULL
,
700 if (!NT_STATUS_IS_OK(status
)) {
701 return ntstatus_to_werror(status
);
704 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
706 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
707 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
709 status
= dcerpc_spoolss_EnumJobs(b
, mem_ctx
,
714 (offered
> 0) ? &buffer
: NULL
,
721 if (!NT_STATUS_IS_OK(status
)) {
722 return ntstatus_to_werror(status
);
728 /**********************************************************************
729 convenience wrapper around rpccli_spoolss_EnumPrinterDrivers
730 **********************************************************************/
732 WERROR
rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client
*cli
,
735 const char *environment
,
739 union spoolss_DriverInfo
**info
)
745 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
748 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
749 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
752 status
= dcerpc_spoolss_EnumPrinterDrivers(b
, mem_ctx
,
756 (offered
> 0) ? &buffer
: NULL
,
762 if (!NT_STATUS_IS_OK(status
)) {
763 return ntstatus_to_werror(status
);
766 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
768 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
769 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
771 status
= dcerpc_spoolss_EnumPrinterDrivers(b
, mem_ctx
,
775 (offered
> 0) ? &buffer
: NULL
,
782 if (!NT_STATUS_IS_OK(status
)) {
783 return ntstatus_to_werror(status
);
789 /**********************************************************************
790 convenience wrapper around rpccli_spoolss_EnumPrinters
791 **********************************************************************/
793 WERROR
rpccli_spoolss_enumprinters(struct rpc_pipe_client
*cli
,
800 union spoolss_PrinterInfo
**info
)
806 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
809 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
810 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
813 status
= dcerpc_spoolss_EnumPrinters(b
, mem_ctx
,
817 (offered
> 0) ? &buffer
: NULL
,
823 if (!NT_STATUS_IS_OK(status
)) {
824 return ntstatus_to_werror(status
);
827 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
829 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
830 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
832 status
= dcerpc_spoolss_EnumPrinters(b
, mem_ctx
,
836 (offered
> 0) ? &buffer
: NULL
,
843 if (!NT_STATUS_IS_OK(status
)) {
844 return ntstatus_to_werror(status
);
850 /**********************************************************************
851 convenience wrapper around rpccli_spoolss_GetPrinterData
852 **********************************************************************/
854 WERROR
rpccli_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
856 struct policy_handle
*handle
,
857 const char *value_name
,
859 enum winreg_Type
*type
,
867 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
869 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
870 W_ERROR_HAVE_NO_MEMORY(data
);
872 status
= dcerpc_spoolss_GetPrinterData(b
, mem_ctx
,
880 if (!NT_STATUS_IS_OK(status
)) {
881 return ntstatus_to_werror(status
);
884 if (W_ERROR_EQUAL(werror
, WERR_MORE_DATA
)) {
886 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
887 W_ERROR_HAVE_NO_MEMORY(data
);
889 status
= dcerpc_spoolss_GetPrinterData(b
, mem_ctx
,
898 if (!NT_STATUS_IS_OK(status
)) {
899 return ntstatus_to_werror(status
);
908 /**********************************************************************
909 convenience wrapper around rpccli_spoolss_EnumPrinterKey
910 **********************************************************************/
912 WERROR
rpccli_spoolss_enumprinterkey(struct rpc_pipe_client
*cli
,
914 struct policy_handle
*handle
,
915 const char *key_name
,
916 const char ***key_buffer
,
922 union spoolss_KeyNames _key_buffer
;
924 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
926 status
= dcerpc_spoolss_EnumPrinterKey(b
, mem_ctx
,
934 if (!NT_STATUS_IS_OK(status
)) {
935 return ntstatus_to_werror(status
);
938 if (W_ERROR_EQUAL(werror
, WERR_MORE_DATA
)) {
940 status
= dcerpc_spoolss_EnumPrinterKey(b
, mem_ctx
,
949 if (!NT_STATUS_IS_OK(status
)) {
950 return ntstatus_to_werror(status
);
953 *key_buffer
= _key_buffer
.string_array
;
958 /**********************************************************************
959 convenience wrapper around rpccli_spoolss_EnumPrinterDataEx
960 **********************************************************************/
962 WERROR
rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client
*cli
,
964 struct policy_handle
*handle
,
965 const char *key_name
,
968 struct spoolss_PrinterEnumValues
**info
)
973 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
975 status
= dcerpc_spoolss_EnumPrinterDataEx(b
, mem_ctx
,
983 if (!NT_STATUS_IS_OK(status
)) {
984 return ntstatus_to_werror(status
);
987 if (W_ERROR_EQUAL(werror
, WERR_MORE_DATA
)) {
990 status
= dcerpc_spoolss_EnumPrinterDataEx(b
, mem_ctx
,
999 if (!NT_STATUS_IS_OK(status
)) {
1000 return ntstatus_to_werror(status
);