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"
32 /**********************************************************************
33 convencience wrapper around rpccli_spoolss_OpenPrinterEx
34 **********************************************************************/
36 WERROR
rpccli_spoolss_openprinter_ex(struct rpc_pipe_client
*cli
,
38 const char *printername
,
39 uint32_t access_desired
,
40 struct policy_handle
*handle
)
44 struct spoolss_DevmodeContainer devmode_ctr
;
45 struct spoolss_UserLevelCtr userlevel_ctr
;
46 struct spoolss_UserLevel1 level1
;
47 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
48 struct cli_credentials
*creds
= gensec_get_credentials(cli
->auth
->auth_ctx
);
50 ZERO_STRUCT(devmode_ctr
);
53 level1
.client
= talloc_asprintf(mem_ctx
, "\\\\%s", lp_netbios_name());
54 W_ERROR_HAVE_NO_MEMORY(level1
.client
);
55 level1
.user
= cli_credentials_get_username(creds
);
61 userlevel_ctr
.level
= 1;
62 userlevel_ctr
.user_info
.level1
= &level1
;
64 status
= dcerpc_spoolss_OpenPrinterEx(b
, mem_ctx
,
73 if (!NT_STATUS_IS_OK(status
)) {
74 return ntstatus_to_werror(status
);
77 if (!W_ERROR_IS_OK(werror
)) {
84 /**********************************************************************
85 convencience wrapper around rpccli_spoolss_GetPrinterDriver
86 **********************************************************************/
88 WERROR
rpccli_spoolss_getprinterdriver(struct rpc_pipe_client
*cli
,
90 struct policy_handle
*handle
,
91 const char *architecture
,
94 union spoolss_DriverInfo
*info
)
100 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
103 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
104 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
107 status
= dcerpc_spoolss_GetPrinterDriver(b
, mem_ctx
,
111 (offered
> 0) ? &buffer
: NULL
,
116 if (!NT_STATUS_IS_OK(status
)) {
117 return ntstatus_to_werror(status
);
119 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
121 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
122 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
124 status
= dcerpc_spoolss_GetPrinterDriver(b
, mem_ctx
,
134 if (!NT_STATUS_IS_OK(status
)) {
135 return ntstatus_to_werror(status
);
141 /**********************************************************************
142 convencience wrapper around rpccli_spoolss_GetPrinterDriver2
143 **********************************************************************/
145 WERROR
rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client
*cli
,
147 struct policy_handle
*handle
,
148 const char *architecture
,
151 uint32_t client_major_version
,
152 uint32_t client_minor_version
,
153 union spoolss_DriverInfo
*info
,
154 uint32_t *server_major_version
,
155 uint32_t *server_minor_version
)
161 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
164 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
165 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
168 status
= dcerpc_spoolss_GetPrinterDriver2(b
, mem_ctx
,
172 (offered
> 0) ? &buffer
: NULL
,
174 client_major_version
,
175 client_minor_version
,
178 server_major_version
,
179 server_minor_version
,
181 if (!NT_STATUS_IS_OK(status
)) {
182 return ntstatus_to_werror(status
);
185 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
187 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
188 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
190 status
= dcerpc_spoolss_GetPrinterDriver2(b
, mem_ctx
,
196 client_major_version
,
197 client_minor_version
,
200 server_major_version
,
201 server_minor_version
,
204 if (!NT_STATUS_IS_OK(status
)) {
205 return ntstatus_to_werror(status
);
211 /**********************************************************************
212 convencience wrapper around rpccli_spoolss_AddPrinterEx
213 **********************************************************************/
215 WERROR
rpccli_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
217 struct spoolss_SetPrinterInfoCtr
*info_ctr
)
221 struct spoolss_DevmodeContainer devmode_ctr
;
222 struct sec_desc_buf secdesc_ctr
;
223 struct spoolss_UserLevelCtr userlevel_ctr
;
224 struct spoolss_UserLevel1 level1
;
225 struct policy_handle handle
;
226 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
227 struct cli_credentials
*creds
= gensec_get_credentials(cli
->auth
->auth_ctx
);
229 ZERO_STRUCT(devmode_ctr
);
230 ZERO_STRUCT(secdesc_ctr
);
236 level1
.processor
= 0;
237 level1
.client
= talloc_asprintf(mem_ctx
, "\\\\%s", lp_netbios_name());
238 W_ERROR_HAVE_NO_MEMORY(level1
.client
);
239 level1
.user
= cli_credentials_get_username(creds
);
241 userlevel_ctr
.level
= 1;
242 userlevel_ctr
.user_info
.level1
= &level1
;
244 status
= dcerpc_spoolss_AddPrinterEx(b
, mem_ctx
,
252 if (!NT_STATUS_IS_OK(status
)) {
253 return ntstatus_to_werror(status
);
259 /**********************************************************************
260 convencience wrapper around rpccli_spoolss_GetPrinter
261 **********************************************************************/
263 WERROR
rpccli_spoolss_getprinter(struct rpc_pipe_client
*cli
,
265 struct policy_handle
*handle
,
268 union spoolss_PrinterInfo
*info
)
274 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
277 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
278 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
281 status
= dcerpc_spoolss_GetPrinter(b
, mem_ctx
,
284 (offered
> 0) ? &buffer
: NULL
,
289 if (!NT_STATUS_IS_OK(status
)) {
290 return ntstatus_to_werror(status
);
293 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
296 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
297 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
299 status
= dcerpc_spoolss_GetPrinter(b
, mem_ctx
,
308 if (!NT_STATUS_IS_OK(status
)) {
309 return ntstatus_to_werror(status
);
315 /**********************************************************************
316 convencience wrapper around rpccli_spoolss_GetJob
317 **********************************************************************/
319 WERROR
rpccli_spoolss_getjob(struct rpc_pipe_client
*cli
,
321 struct policy_handle
*handle
,
325 union spoolss_JobInfo
*info
)
331 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
334 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
335 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
338 status
= dcerpc_spoolss_GetJob(b
, mem_ctx
,
342 (offered
> 0) ? &buffer
: NULL
,
347 if (!NT_STATUS_IS_OK(status
)) {
348 return ntstatus_to_werror(status
);
351 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
353 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
354 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
356 status
= dcerpc_spoolss_GetJob(b
, mem_ctx
,
366 if (!NT_STATUS_IS_OK(status
)) {
367 return ntstatus_to_werror(status
);
373 /**********************************************************************
374 convencience wrapper around rpccli_spoolss_EnumForms
375 **********************************************************************/
377 WERROR
rpccli_spoolss_enumforms(struct rpc_pipe_client
*cli
,
379 struct policy_handle
*handle
,
383 union spoolss_FormInfo
**info
)
389 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
392 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
393 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
396 status
= dcerpc_spoolss_EnumForms(b
, mem_ctx
,
399 (offered
> 0) ? &buffer
: NULL
,
405 if (!NT_STATUS_IS_OK(status
)) {
406 return ntstatus_to_werror(status
);
409 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
411 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
412 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
414 status
= dcerpc_spoolss_EnumForms(b
, mem_ctx
,
417 (offered
> 0) ? &buffer
: NULL
,
424 if (!NT_STATUS_IS_OK(status
)) {
425 return ntstatus_to_werror(status
);
431 /**********************************************************************
432 convencience wrapper around rpccli_spoolss_EnumPrintProcessors
433 **********************************************************************/
435 WERROR
rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client
*cli
,
437 const char *servername
,
438 const char *environment
,
442 union spoolss_PrintProcessorInfo
**info
)
448 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
451 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
452 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
455 status
= dcerpc_spoolss_EnumPrintProcessors(b
, mem_ctx
,
459 (offered
> 0) ? &buffer
: NULL
,
465 if (!NT_STATUS_IS_OK(status
)) {
466 return ntstatus_to_werror(status
);
469 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
471 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
472 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
474 status
= dcerpc_spoolss_EnumPrintProcessors(b
, mem_ctx
,
478 (offered
> 0) ? &buffer
: NULL
,
485 if (!NT_STATUS_IS_OK(status
)) {
486 return ntstatus_to_werror(status
);
492 /**********************************************************************
493 convencience wrapper around rpccli_spoolss_EnumPrintProcDataTypes
494 **********************************************************************/
496 WERROR
rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client
*cli
,
498 const char *servername
,
499 const char *print_processor_name
,
503 union spoolss_PrintProcDataTypesInfo
**info
)
509 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
512 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
513 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
516 status
= dcerpc_spoolss_EnumPrintProcDataTypes(b
, mem_ctx
,
518 print_processor_name
,
520 (offered
> 0) ? &buffer
: NULL
,
526 if (!NT_STATUS_IS_OK(status
)) {
527 return ntstatus_to_werror(status
);
530 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
532 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
533 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
535 status
= dcerpc_spoolss_EnumPrintProcDataTypes(b
, mem_ctx
,
537 print_processor_name
,
539 (offered
> 0) ? &buffer
: NULL
,
546 if (!NT_STATUS_IS_OK(status
)) {
547 return ntstatus_to_werror(status
);
553 /**********************************************************************
554 convencience wrapper around rpccli_spoolss_EnumPorts
555 **********************************************************************/
557 WERROR
rpccli_spoolss_enumports(struct rpc_pipe_client
*cli
,
559 const char *servername
,
563 union spoolss_PortInfo
**info
)
569 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
572 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
573 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
576 status
= dcerpc_spoolss_EnumPorts(b
, mem_ctx
,
579 (offered
> 0) ? &buffer
: NULL
,
585 if (!NT_STATUS_IS_OK(status
)) {
586 return ntstatus_to_werror(status
);
589 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
591 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
592 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
594 status
= dcerpc_spoolss_EnumPorts(b
, mem_ctx
,
597 (offered
> 0) ? &buffer
: NULL
,
604 if (!NT_STATUS_IS_OK(status
)) {
605 return ntstatus_to_werror(status
);
611 /**********************************************************************
612 convencience wrapper around rpccli_spoolss_EnumMonitors
613 **********************************************************************/
615 WERROR
rpccli_spoolss_enummonitors(struct rpc_pipe_client
*cli
,
617 const char *servername
,
621 union spoolss_MonitorInfo
**info
)
627 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
630 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
631 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
634 status
= dcerpc_spoolss_EnumMonitors(b
, mem_ctx
,
637 (offered
> 0) ? &buffer
: NULL
,
643 if (!NT_STATUS_IS_OK(status
)) {
644 return ntstatus_to_werror(status
);
647 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
649 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
650 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
652 status
= dcerpc_spoolss_EnumMonitors(b
, mem_ctx
,
655 (offered
> 0) ? &buffer
: NULL
,
662 if (!NT_STATUS_IS_OK(status
)) {
663 return ntstatus_to_werror(status
);
669 /**********************************************************************
670 convencience wrapper around rpccli_spoolss_EnumJobs
671 **********************************************************************/
673 WERROR
rpccli_spoolss_enumjobs(struct rpc_pipe_client
*cli
,
675 struct policy_handle
*handle
,
681 union spoolss_JobInfo
**info
)
687 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
690 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
691 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
694 status
= dcerpc_spoolss_EnumJobs(b
, mem_ctx
,
699 (offered
> 0) ? &buffer
: NULL
,
705 if (!NT_STATUS_IS_OK(status
)) {
706 return ntstatus_to_werror(status
);
709 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
711 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
712 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
714 status
= dcerpc_spoolss_EnumJobs(b
, mem_ctx
,
719 (offered
> 0) ? &buffer
: NULL
,
726 if (!NT_STATUS_IS_OK(status
)) {
727 return ntstatus_to_werror(status
);
733 /**********************************************************************
734 convencience wrapper around rpccli_spoolss_EnumPrinterDrivers
735 **********************************************************************/
737 WERROR
rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client
*cli
,
740 const char *environment
,
744 union spoolss_DriverInfo
**info
)
750 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
753 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
754 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
757 status
= dcerpc_spoolss_EnumPrinterDrivers(b
, mem_ctx
,
761 (offered
> 0) ? &buffer
: NULL
,
767 if (!NT_STATUS_IS_OK(status
)) {
768 return ntstatus_to_werror(status
);
771 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
773 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
774 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
776 status
= dcerpc_spoolss_EnumPrinterDrivers(b
, mem_ctx
,
780 (offered
> 0) ? &buffer
: NULL
,
787 if (!NT_STATUS_IS_OK(status
)) {
788 return ntstatus_to_werror(status
);
794 /**********************************************************************
795 convencience wrapper around rpccli_spoolss_EnumPrinters
796 **********************************************************************/
798 WERROR
rpccli_spoolss_enumprinters(struct rpc_pipe_client
*cli
,
805 union spoolss_PrinterInfo
**info
)
811 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
814 buffer
= data_blob_talloc_zero(mem_ctx
, offered
);
815 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
818 status
= dcerpc_spoolss_EnumPrinters(b
, mem_ctx
,
822 (offered
> 0) ? &buffer
: NULL
,
828 if (!NT_STATUS_IS_OK(status
)) {
829 return ntstatus_to_werror(status
);
832 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
834 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
835 W_ERROR_HAVE_NO_MEMORY(buffer
.data
);
837 status
= dcerpc_spoolss_EnumPrinters(b
, mem_ctx
,
841 (offered
> 0) ? &buffer
: NULL
,
848 if (!NT_STATUS_IS_OK(status
)) {
849 return ntstatus_to_werror(status
);
855 /**********************************************************************
856 convencience wrapper around rpccli_spoolss_GetPrinterData
857 **********************************************************************/
859 WERROR
rpccli_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
861 struct policy_handle
*handle
,
862 const char *value_name
,
864 enum winreg_Type
*type
,
872 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
874 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
875 W_ERROR_HAVE_NO_MEMORY(data
);
877 status
= dcerpc_spoolss_GetPrinterData(b
, mem_ctx
,
885 if (!NT_STATUS_IS_OK(status
)) {
886 return ntstatus_to_werror(status
);
889 if (W_ERROR_EQUAL(werror
, WERR_MORE_DATA
)) {
891 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
892 W_ERROR_HAVE_NO_MEMORY(data
);
894 status
= dcerpc_spoolss_GetPrinterData(b
, mem_ctx
,
903 if (!NT_STATUS_IS_OK(status
)) {
904 return ntstatus_to_werror(status
);
913 /**********************************************************************
914 convencience wrapper around rpccli_spoolss_EnumPrinterKey
915 **********************************************************************/
917 WERROR
rpccli_spoolss_enumprinterkey(struct rpc_pipe_client
*cli
,
919 struct policy_handle
*handle
,
920 const char *key_name
,
921 const char ***key_buffer
,
927 union spoolss_KeyNames _key_buffer
;
929 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
931 status
= dcerpc_spoolss_EnumPrinterKey(b
, mem_ctx
,
939 if (!NT_STATUS_IS_OK(status
)) {
940 return ntstatus_to_werror(status
);
943 if (W_ERROR_EQUAL(werror
, WERR_MORE_DATA
)) {
945 status
= dcerpc_spoolss_EnumPrinterKey(b
, mem_ctx
,
954 if (!NT_STATUS_IS_OK(status
)) {
955 return ntstatus_to_werror(status
);
958 *key_buffer
= _key_buffer
.string_array
;
963 /**********************************************************************
964 convencience wrapper around rpccli_spoolss_EnumPrinterDataEx
965 **********************************************************************/
967 WERROR
rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client
*cli
,
969 struct policy_handle
*handle
,
970 const char *key_name
,
973 struct spoolss_PrinterEnumValues
**info
)
978 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
980 status
= dcerpc_spoolss_EnumPrinterDataEx(b
, mem_ctx
,
988 if (!NT_STATUS_IS_OK(status
)) {
989 return ntstatus_to_werror(status
);
992 if (W_ERROR_EQUAL(werror
, WERR_MORE_DATA
)) {
995 status
= dcerpc_spoolss_EnumPrinterDataEx(b
, mem_ctx
,
1004 if (!NT_STATUS_IS_OK(status
)) {
1005 return ntstatus_to_werror(status
);