2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
9 Copyright (C) Guenther Deschner 2009
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 "rpcclient.h"
27 #include "../librpc/gen_ndr/ndr_spoolss_c.h"
28 #include "../librpc/gen_ndr/ndr_spoolss.h"
29 #include "rpc_client/cli_spoolss.h"
30 #include "rpc_client/init_spoolss.h"
31 #include "nt_printing.h"
32 #include "../libcli/security/display_sec.h"
33 #include "../libcli/security/security_descriptor.h"
34 #include "../libcli/registry/util_reg.h"
35 #include "libsmb/libsmb.h"
37 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
39 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
40 _cli->srv_name_slash, _arg); \
41 W_ERROR_HAVE_NO_MEMORY(_printername); \
44 /* The version int is used by getdrivers. Note that
45 all architecture strings that support mutliple
46 versions must be grouped together since enumdrivers
47 uses this property to prevent issuing multiple
48 enumdriver calls for the same arch */
51 static const struct print_architecture_table_node archi_table
[]= {
53 {"Windows 4.0", "WIN40", 0 },
54 {"Windows NT x86", "W32X86", 2 },
55 {"Windows NT x86", "W32X86", 3 },
56 {"Windows NT R4000", "W32MIPS", 2 },
57 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
58 {"Windows NT PowerPC", "W32PPC", 2 },
59 {"Windows IA64", "IA64", 3 },
60 {"Windows x64", "x64", 3 },
67 * rpcclient module for SPOOLSS rpc pipe.
69 * This generally just parses and checks command lines, and then calls
70 * a cli_spoolss function.
73 /****************************************************************************
74 function to do the mapping between the long architecture name and
76 ****************************************************************************/
78 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
82 DEBUG(107,("Getting architecture dependent directory\n"));
85 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
86 strcasecmp_m(long_archi
, archi_table
[i
].long_archi
) );
88 if (archi_table
[i
].long_archi
==NULL
) {
89 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
93 /* this might be client code - but shouldn't this be an fstrcpy etc? */
96 DEBUGADD(108,("index: [%d]\n", i
));
97 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
98 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
100 return archi_table
[i
].short_archi
;
103 /****************************************************************************
104 ****************************************************************************/
106 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
108 int argc
, const char **argv
)
111 struct policy_handle hnd
;
112 uint32_t access_mask
= PRINTER_ALL_ACCESS
;
113 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
116 printf("Usage: %s <printername> [access_mask]\n", argv
[0]);
121 sscanf(argv
[2], "%x", &access_mask
);
124 /* Open the printer handle */
126 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
130 if (W_ERROR_IS_OK(werror
)) {
131 printf("Printer %s opened successfully\n", argv
[1]);
132 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &werror
);
134 if (!W_ERROR_IS_OK(werror
)) {
135 printf("Error closing printer handle! (%s)\n",
136 get_dos_error_msg(werror
));
143 /****************************************************************************
144 ****************************************************************************/
146 static WERROR
cmd_spoolss_open_printer(struct rpc_pipe_client
*cli
,
148 int argc
, const char **argv
)
151 struct policy_handle hnd
;
152 uint32_t access_mask
= PRINTER_ALL_ACCESS
;
154 struct spoolss_DevmodeContainer devmode_ctr
;
155 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
157 ZERO_STRUCT(devmode_ctr
);
160 printf("Usage: %s <printername> [access_mask]\n", argv
[0]);
165 sscanf(argv
[2], "%x", &access_mask
);
168 /* Open the printer handle */
170 status
= dcerpc_spoolss_OpenPrinter(b
, mem_ctx
,
177 if (!NT_STATUS_IS_OK(status
)) {
178 return ntstatus_to_werror(status
);
180 if (W_ERROR_IS_OK(werror
)) {
181 printf("Printer %s opened successfully\n", argv
[1]);
182 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &werror
);
184 if (!W_ERROR_IS_OK(werror
)) {
185 printf("Error closing printer handle! (%s)\n",
186 get_dos_error_msg(werror
));
193 /****************************************************************************
194 ****************************************************************************/
196 static void display_print_info0(struct spoolss_PrinterInfo0
*r
)
201 printf("\tprintername:[%s]\n", r
->printername
);
202 printf("\tservername:[%s]\n", r
->servername
);
203 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
204 printf("\ttotal_jobs:[0x%x]\n", r
->total_jobs
);
205 printf("\ttotal_bytes:[0x%x]\n", r
->total_bytes
);
206 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r
->time
.year
, r
->time
.month
,
207 r
->time
.day
, r
->time
.day_of_week
);
208 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r
->time
.hour
, r
->time
.minute
,
209 r
->time
.second
, r
->time
.millisecond
);
211 printf("\tglobal_counter:[0x%x]\n", r
->global_counter
);
212 printf("\ttotal_pages:[0x%x]\n", r
->total_pages
);
214 printf("\tversion:[0x%x]\n", r
->version
);
215 printf("\tfree_build:[0x%x]\n", r
->free_build
);
216 printf("\tspooling:[0x%x]\n", r
->spooling
);
217 printf("\tmax_spooling:[0x%x]\n", r
->max_spooling
);
218 printf("\tsession_counter:[0x%x]\n", r
->session_counter
);
219 printf("\tnum_error_out_of_paper:[0x%x]\n", r
->num_error_out_of_paper
);
220 printf("\tnum_error_not_ready:[0x%x]\n", r
->num_error_not_ready
);
221 printf("\tjob_error:[0x%x]\n", r
->job_error
);
222 printf("\tnumber_of_processors:[0x%x]\n", r
->number_of_processors
);
223 printf("\tprocessor_type:[0x%x]\n", r
->processor_type
);
224 printf("\thigh_part_total_bytes:[0x%x]\n", r
->high_part_total_bytes
);
225 printf("\tchange_id:[0x%x]\n", r
->change_id
);
226 printf("\tlast_error: %s\n", win_errstr(r
->last_error
));
227 printf("\tstatus:[0x%x]\n", r
->status
);
228 printf("\tenumerate_network_printers:[0x%x]\n", r
->enumerate_network_printers
);
229 printf("\tc_setprinter:[0x%x]\n", r
->c_setprinter
);
230 printf("\tprocessor_architecture:[0x%x]\n", r
->processor_architecture
);
231 printf("\tprocessor_level:[0x%x]\n", r
->processor_level
);
232 printf("\tref_ic:[0x%x]\n", r
->ref_ic
);
233 printf("\treserved2:[0x%x]\n", r
->reserved2
);
234 printf("\treserved3:[0x%x]\n", r
->reserved3
);
239 /****************************************************************************
240 ****************************************************************************/
242 static void display_print_info1(struct spoolss_PrinterInfo1
*r
)
244 printf("\tflags:[0x%x]\n", r
->flags
);
245 printf("\tname:[%s]\n", r
->name
);
246 printf("\tdescription:[%s]\n", r
->description
);
247 printf("\tcomment:[%s]\n", r
->comment
);
252 /****************************************************************************
253 ****************************************************************************/
255 static void display_print_info2(struct spoolss_PrinterInfo2
*r
)
257 printf("\tservername:[%s]\n", r
->servername
);
258 printf("\tprintername:[%s]\n", r
->printername
);
259 printf("\tsharename:[%s]\n", r
->sharename
);
260 printf("\tportname:[%s]\n", r
->portname
);
261 printf("\tdrivername:[%s]\n", r
->drivername
);
262 printf("\tcomment:[%s]\n", r
->comment
);
263 printf("\tlocation:[%s]\n", r
->location
);
264 printf("\tsepfile:[%s]\n", r
->sepfile
);
265 printf("\tprintprocessor:[%s]\n", r
->printprocessor
);
266 printf("\tdatatype:[%s]\n", r
->datatype
);
267 printf("\tparameters:[%s]\n", r
->parameters
);
268 printf("\tattributes:[0x%x]\n", r
->attributes
);
269 printf("\tpriority:[0x%x]\n", r
->priority
);
270 printf("\tdefaultpriority:[0x%x]\n", r
->defaultpriority
);
271 printf("\tstarttime:[0x%x]\n", r
->starttime
);
272 printf("\tuntiltime:[0x%x]\n", r
->untiltime
);
273 printf("\tstatus:[0x%x]\n", r
->status
);
274 printf("\tcjobs:[0x%x]\n", r
->cjobs
);
275 printf("\taverageppm:[0x%x]\n", r
->averageppm
);
278 display_sec_desc(r
->secdesc
);
283 /****************************************************************************
284 ****************************************************************************/
286 static void display_print_info3(struct spoolss_PrinterInfo3
*r
)
288 display_sec_desc(r
->secdesc
);
293 /****************************************************************************
294 ****************************************************************************/
296 static void display_print_info4(struct spoolss_PrinterInfo4
*r
)
298 printf("\tservername:[%s]\n", r
->servername
);
299 printf("\tprintername:[%s]\n", r
->printername
);
300 printf("\tattributes:[0x%x]\n", r
->attributes
);
304 /****************************************************************************
305 ****************************************************************************/
307 static void display_print_info5(struct spoolss_PrinterInfo5
*r
)
309 printf("\tprintername:[%s]\n", r
->printername
);
310 printf("\tportname:[%s]\n", r
->portname
);
311 printf("\tattributes:[0x%x]\n", r
->attributes
);
312 printf("\tdevice_not_selected_timeout:[0x%x]\n", r
->device_not_selected_timeout
);
313 printf("\ttransmission_retry_timeout:[0x%x]\n", r
->transmission_retry_timeout
);
317 /****************************************************************************
318 ****************************************************************************/
320 static void display_print_info6(struct spoolss_PrinterInfo6
*r
)
322 printf("\tstatus:[0x%x]\n", r
->status
);
326 /****************************************************************************
327 ****************************************************************************/
329 static void display_print_info7(struct spoolss_PrinterInfo7
*r
)
331 printf("\tguid:[%s]\n", r
->guid
);
332 printf("\taction:[0x%x]\n", r
->action
);
336 /****************************************************************************
337 ****************************************************************************/
339 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
341 int argc
, const char **argv
)
345 union spoolss_PrinterInfo
*info
;
348 uint32_t flags
= PRINTER_ENUM_LOCAL
;
351 printf("Usage: %s [level] [name] [flags]\n", argv
[0]);
356 level
= atoi(argv
[1]);
362 name
= cli
->srv_name_slash
;
366 flags
= atoi(argv
[3]);
369 result
= rpccli_spoolss_enumprinters(cli
, mem_ctx
,
376 if (W_ERROR_IS_OK(result
)) {
379 printf ("No printers returned.\n");
383 for (i
= 0; i
< count
; i
++) {
386 display_print_info0(&info
[i
].info0
);
389 display_print_info1(&info
[i
].info1
);
392 display_print_info2(&info
[i
].info2
);
395 display_print_info3(&info
[i
].info3
);
398 display_print_info4(&info
[i
].info4
);
401 display_print_info5(&info
[i
].info5
);
404 display_print_info6(&info
[i
].info6
);
407 printf("unknown info level %d\n", level
);
417 /****************************************************************************
418 ****************************************************************************/
420 static void display_port_info_1(struct spoolss_PortInfo1
*r
)
422 printf("\tPort Name:\t[%s]\n", r
->port_name
);
425 /****************************************************************************
426 ****************************************************************************/
428 static void display_port_info_2(struct spoolss_PortInfo2
*r
)
430 printf("\tPort Name:\t[%s]\n", r
->port_name
);
431 printf("\tMonitor Name:\t[%s]\n", r
->monitor_name
);
432 printf("\tDescription:\t[%s]\n", r
->description
);
433 printf("\tPort Type:\t" );
435 int comma
= 0; /* hack */
437 if (r
->port_type
& SPOOLSS_PORT_TYPE_READ
) {
441 if (r
->port_type
& SPOOLSS_PORT_TYPE_WRITE
) {
442 printf( "%sWrite", comma
? ", " : "" );
445 /* These two have slightly different interpretations
446 on 95/98/ME but I'm disregarding that for now */
447 if (r
->port_type
& SPOOLSS_PORT_TYPE_REDIRECTED
) {
448 printf( "%sRedirected", comma
? ", " : "" );
451 if (r
->port_type
& SPOOLSS_PORT_TYPE_NET_ATTACHED
) {
452 printf( "%sNet-Attached", comma
? ", " : "" );
456 printf( "[Unset]\n" );
458 printf("\tReserved:\t[%d]\n", r
->reserved
);
462 /****************************************************************************
463 ****************************************************************************/
465 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
466 TALLOC_CTX
*mem_ctx
, int argc
,
472 union spoolss_PortInfo
*info
;
475 printf("Usage: %s [level]\n", argv
[0]);
480 level
= atoi(argv
[1]);
483 /* Enumerate ports */
485 result
= rpccli_spoolss_enumports(cli
, mem_ctx
,
491 if (W_ERROR_IS_OK(result
)) {
494 for (i
= 0; i
< count
; i
++) {
497 display_port_info_1(&info
[i
].info1
);
500 display_port_info_2(&info
[i
].info2
);
503 printf("unknown info level %d\n", level
);
512 /****************************************************************************
513 ****************************************************************************/
515 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
517 int argc
, const char **argv
)
519 struct policy_handle pol
;
522 uint32_t info_level
= 2;
523 union spoolss_PrinterInfo info
;
524 struct spoolss_SetPrinterInfoCtr info_ctr
;
525 struct spoolss_SetPrinterInfo2 info2
;
526 const char *printername
, *comment
= NULL
;
527 struct spoolss_DevmodeContainer devmode_ctr
;
528 struct sec_desc_buf secdesc_ctr
;
529 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
531 if (argc
== 1 || argc
> 3) {
532 printf("Usage: %s printername comment\n", argv
[0]);
537 /* Open a printer handle */
542 ZERO_STRUCT(devmode_ctr
);
543 ZERO_STRUCT(secdesc_ctr
);
545 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
547 /* get a printer handle */
548 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
552 if (!W_ERROR_IS_OK(result
))
555 /* Get printer info */
556 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
561 if (!W_ERROR_IS_OK(result
))
565 /* Modify the comment. */
566 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
567 info2
.comment
= comment
;
570 info_ctr
.info
.info2
= &info2
;
572 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
579 if (!NT_STATUS_IS_OK(status
)) {
580 result
= ntstatus_to_werror(status
);
583 if (W_ERROR_IS_OK(result
))
584 printf("Success in setting comment.\n");
587 if (is_valid_policy_hnd(&pol
)) {
589 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
595 /****************************************************************************
596 ****************************************************************************/
598 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
600 int argc
, const char **argv
)
602 struct policy_handle pol
;
605 uint32_t info_level
= 2;
606 union spoolss_PrinterInfo info
;
607 const char *printername
,
608 *new_printername
= NULL
;
609 struct spoolss_SetPrinterInfoCtr info_ctr
;
610 struct spoolss_SetPrinterInfo2 info2
;
611 struct spoolss_DevmodeContainer devmode_ctr
;
612 struct sec_desc_buf secdesc_ctr
;
613 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
615 ZERO_STRUCT(devmode_ctr
);
616 ZERO_STRUCT(secdesc_ctr
);
618 if (argc
== 1 || argc
> 3) {
619 printf("Usage: %s printername new_printername\n", argv
[0]);
624 /* Open a printer handle */
626 new_printername
= argv
[2];
629 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
631 /* get a printer handle */
632 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
636 if (!W_ERROR_IS_OK(result
))
639 /* Get printer info */
640 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
645 if (!W_ERROR_IS_OK(result
))
648 /* Modify the printername. */
649 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
650 info2
.printername
= new_printername
;
653 info_ctr
.info
.info2
= &info2
;
655 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
662 if (!NT_STATUS_IS_OK(status
)) {
663 result
= ntstatus_to_werror(status
);
666 if (W_ERROR_IS_OK(result
))
667 printf("Success in setting printername.\n");
670 if (is_valid_policy_hnd(&pol
)) {
672 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
678 /****************************************************************************
679 ****************************************************************************/
681 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
683 int argc
, const char **argv
)
685 struct policy_handle pol
;
688 const char *printername
;
689 union spoolss_PrinterInfo info
;
690 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
692 if (argc
== 1 || argc
> 3) {
693 printf("Usage: %s <printername> [level]\n", argv
[0]);
697 /* Open a printer handle */
699 level
= atoi(argv
[2]);
702 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
704 /* get a printer handle */
706 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
708 SEC_FLAG_MAXIMUM_ALLOWED
,
710 if (!W_ERROR_IS_OK(result
)) {
714 /* Get printer info */
716 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
721 if (!W_ERROR_IS_OK(result
)) {
725 /* Display printer info */
728 display_print_info0(&info
.info0
);
731 display_print_info1(&info
.info1
);
734 display_print_info2(&info
.info2
);
737 display_print_info3(&info
.info3
);
740 display_print_info4(&info
.info4
);
743 display_print_info5(&info
.info5
);
746 display_print_info6(&info
.info6
);
749 display_print_info7(&info
.info7
);
752 printf("unknown info level %d\n", level
);
756 if (is_valid_policy_hnd(&pol
)) {
758 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
764 /****************************************************************************
765 ****************************************************************************/
767 static void display_reg_value(const char *name
, enum winreg_Type type
, DATA_BLOB blob
)
769 const char *text
= NULL
;
773 if (blob
.length
== sizeof(uint32_t)) {
774 printf("%s: REG_DWORD: 0x%08x\n", name
, IVAL(blob
.data
,0));
776 printf("%s: REG_DWORD: <invalid>\n", name
);
780 pull_reg_sz(talloc_tos(), &blob
, &text
);
781 printf("%s: REG_SZ: %s\n", name
, text
? text
: "");
784 char *hex
= hex_encode_talloc(NULL
, blob
.data
, blob
.length
);
786 printf("%s: REG_BINARY:", name
);
788 for (i
=0; i
<len
; i
++) {
789 if (hex
[i
] == '\0') {
805 if (!pull_reg_multi_sz(NULL
, &blob
, &values
)) {
806 d_printf("pull_reg_multi_sz failed\n");
810 printf("%s: REG_MULTI_SZ: \n", name
);
811 for (i
=0; values
[i
] != NULL
; i
++) {
812 d_printf("%s\n", values
[i
]);
818 printf("%s: unknown type %d\n", name
, type
);
823 /****************************************************************************
824 ****************************************************************************/
826 static void display_printer_data(const char *v
,
827 enum winreg_Type type
,
832 union spoolss_PrinterData r
;
833 DATA_BLOB blob
= data_blob_const(data
, length
);
835 enum ndr_err_code ndr_err
;
837 result
= pull_spoolss_PrinterData(talloc_tos(), &blob
, &r
, type
);
838 if (!W_ERROR_IS_OK(result
)) {
844 printf("%s: REG_DWORD: 0x%08x\n", v
, r
.value
);
847 printf("%s: REG_SZ: %s\n", v
, r
.string
);
850 char *hex
= hex_encode_talloc(NULL
,
851 r
.binary
.data
, r
.binary
.length
);
853 printf("%s: REG_BINARY:", v
);
855 for (i
=0; i
<len
; i
++) {
856 if (hex
[i
] == '\0') {
868 if (strequal(v
, "OsVersion")) {
869 struct spoolss_OSVersion os
;
870 ndr_err
= ndr_pull_struct_blob(&blob
, talloc_tos(), &os
,
871 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_OSVersion
);
872 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
874 printf("OsMajor: %u\n", os
.major
);
875 printf("OsMinor: %u\n", os
.minor
);
876 printf("OsBuild: %u\n", os
.build
);
877 NDR_PRINT_DEBUG(spoolss_OSVersion
, &os
);
880 if (strequal(v
, "OsVersionEx")) {
881 struct spoolss_OSVersionEx os
;
882 ndr_err
= ndr_pull_struct_blob(&blob
, talloc_tos(), &os
,
883 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_OSVersionEx
);
884 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
885 printf("OsMajor: %u\n", os
.major
);
886 printf("OsMinor: %u\n", os
.minor
);
887 printf("OsBuild: %u\n", os
.build
);
888 printf("ServicePackMajor: %u\n", os
.service_pack_major
);
889 printf("ServicePackMinor: %u\n", os
.service_pack_minor
);
890 NDR_PRINT_DEBUG(spoolss_OSVersionEx
, &os
);
896 printf("%s: REG_MULTI_SZ: ", v
);
897 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
898 printf("%s ", r
.string_array
[i
]);
903 printf("%s: unknown type 0x%02x:\n", v
, type
);
908 /****************************************************************************
909 ****************************************************************************/
911 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
913 int argc
, const char **argv
)
915 struct policy_handle pol
;
918 const char *valuename
;
919 enum winreg_Type type
;
922 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
925 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
926 printf("<printername> of . queries print server\n");
931 /* Open a printer handle */
933 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
934 fstrcpy(printername
, cli
->srv_name_slash
);
936 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
937 cli
->srv_name_slash
, argv
[1]);
939 /* get a printer handle */
941 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
943 SEC_FLAG_MAXIMUM_ALLOWED
,
945 if (!W_ERROR_IS_OK(result
))
948 /* Get printer info */
950 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
957 if (!W_ERROR_IS_OK(result
))
960 /* Display printer data */
962 display_printer_data(valuename
, type
, data
, needed
);
965 if (is_valid_policy_hnd(&pol
)) {
967 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
973 /****************************************************************************
974 ****************************************************************************/
976 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
978 int argc
, const char **argv
)
980 struct policy_handle pol
;
984 const char *valuename
, *keyname
;
986 enum winreg_Type type
;
987 uint8_t *data
= NULL
;
988 uint32_t offered
= 0;
990 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
993 printf("Usage: %s <printername> <keyname> <valuename>\n",
995 printf("<printername> of . queries print server\n");
1001 /* Open a printer handle */
1003 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
1004 fstrcpy(printername
, cli
->srv_name_slash
);
1006 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
1007 cli
->srv_name_slash
, argv
[1]);
1009 /* get a printer handle */
1011 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1013 SEC_FLAG_MAXIMUM_ALLOWED
,
1015 if (!W_ERROR_IS_OK(result
))
1018 /* Get printer info */
1020 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
1025 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1034 if (!NT_STATUS_IS_OK(status
)) {
1035 result
= ntstatus_to_werror(status
);
1038 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
1040 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
1044 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1055 if (!NT_STATUS_IS_OK(status
)) {
1056 result
= ntstatus_to_werror(status
);
1060 if (!W_ERROR_IS_OK(result
))
1063 /* Display printer data */
1065 display_printer_data(valuename
, type
, data
, needed
);
1069 if (is_valid_policy_hnd(&pol
)) {
1071 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1077 /****************************************************************************
1078 ****************************************************************************/
1080 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1086 printf("Printer Driver Info 1:\n");
1087 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1091 /****************************************************************************
1092 ****************************************************************************/
1094 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1100 printf("Printer Driver Info 2:\n");
1101 printf("\tVersion: [%x]\n", r
->version
);
1102 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1103 printf("\tArchitecture: [%s]\n", r
->architecture
);
1104 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1105 printf("\tDatafile: [%s]\n", r
->data_file
);
1106 printf("\tConfigfile: [%s]\n", r
->config_file
);
1110 /****************************************************************************
1111 ****************************************************************************/
1113 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1121 printf("Printer Driver Info 3:\n");
1122 printf("\tVersion: [%x]\n", r
->version
);
1123 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1124 printf("\tArchitecture: [%s]\n", r
->architecture
);
1125 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1126 printf("\tDatafile: [%s]\n", r
->data_file
);
1127 printf("\tConfigfile: [%s]\n", r
->config_file
);
1128 printf("\tHelpfile: [%s]\n", r
->help_file
);
1130 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1131 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1134 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1135 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1139 /****************************************************************************
1140 ****************************************************************************/
1142 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1150 printf("Printer Driver Info 4:\n");
1151 printf("\tVersion: [%x]\n", r
->version
);
1152 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1153 printf("\tArchitecture: [%s]\n", r
->architecture
);
1154 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1155 printf("\tDatafile: [%s]\n", r
->data_file
);
1156 printf("\tConfigfile: [%s]\n", r
->config_file
);
1157 printf("\tHelpfile: [%s]\n", r
->help_file
);
1159 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1160 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1163 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1164 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1166 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1167 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1172 /****************************************************************************
1173 ****************************************************************************/
1175 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1181 printf("Printer Driver Info 5:\n");
1182 printf("\tVersion: [%x]\n", r
->version
);
1183 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1184 printf("\tArchitecture: [%s]\n", r
->architecture
);
1185 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1186 printf("\tDatafile: [%s]\n", r
->data_file
);
1187 printf("\tConfigfile: [%s]\n", r
->config_file
);
1188 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1189 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1190 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1194 /****************************************************************************
1195 ****************************************************************************/
1197 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1205 printf("Printer Driver Info 6:\n");
1206 printf("\tVersion: [%x]\n", r
->version
);
1207 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1208 printf("\tArchitecture: [%s]\n", r
->architecture
);
1209 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1210 printf("\tDatafile: [%s]\n", r
->data_file
);
1211 printf("\tConfigfile: [%s]\n", r
->config_file
);
1212 printf("\tHelpfile: [%s]\n", r
->help_file
);
1214 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1215 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1218 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1219 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1221 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1222 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1225 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1226 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1227 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1228 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1229 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1230 printf("\tProvider: [%s]\n", r
->provider
);
1235 /****************************************************************************
1236 ****************************************************************************/
1238 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1246 printf("Printer Driver Info 8:\n");
1247 printf("\tVersion: [%x]\n", r
->version
);
1248 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1249 printf("\tArchitecture: [%s]\n", r
->architecture
);
1250 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1251 printf("\tDatafile: [%s]\n", r
->data_file
);
1252 printf("\tConfigfile: [%s]\n", r
->config_file
);
1253 printf("\tHelpfile: [%s]\n", r
->help_file
);
1254 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1255 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1257 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1258 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1261 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1262 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1265 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1266 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1267 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1268 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1269 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1270 printf("\tProvider: [%s]\n", r
->provider
);
1271 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1272 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1273 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1274 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1276 printf("\tInf Path: [%s]\n", r
->inf_path
);
1277 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1278 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1279 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1281 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1282 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1283 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1288 /****************************************************************************
1289 ****************************************************************************/
1291 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1292 TALLOC_CTX
*mem_ctx
,
1293 int argc
, const char **argv
)
1295 struct policy_handle pol
;
1298 const char *printername
;
1300 bool success
= false;
1301 union spoolss_DriverInfo info
;
1302 uint32_t server_major_version
;
1303 uint32_t server_minor_version
;
1304 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1306 if ((argc
== 1) || (argc
> 3)) {
1307 printf("Usage: %s <printername> [level]\n", argv
[0]);
1311 /* get the arguments need to open the printer handle */
1313 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1316 level
= atoi(argv
[2]);
1319 /* Open a printer handle */
1321 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1325 if (!W_ERROR_IS_OK(werror
)) {
1326 printf("Error opening printer handle for %s!\n", printername
);
1330 /* loop through and print driver info level for each architecture */
1332 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1334 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1336 archi_table
[i
].long_archi
,
1339 archi_table
[i
].version
,
1342 &server_major_version
,
1343 &server_minor_version
);
1344 if (!W_ERROR_IS_OK(werror
)) {
1348 /* need at least one success */
1352 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1356 display_print_driver1(&info
.info1
);
1359 display_print_driver2(&info
.info2
);
1362 display_print_driver3(&info
.info3
);
1365 display_print_driver4(&info
.info4
);
1368 display_print_driver5(&info
.info5
);
1371 display_print_driver6(&info
.info6
);
1374 display_print_driver8(&info
.info8
);
1377 printf("unknown info level %d\n", level
);
1384 if (is_valid_policy_hnd(&pol
)) {
1386 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1396 /****************************************************************************
1397 ****************************************************************************/
1399 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1400 TALLOC_CTX
*mem_ctx
,
1401 const char *architecture
,
1406 union spoolss_DriverInfo
*info
= NULL
;
1409 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1410 cli
->srv_name_slash
,
1417 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1418 printf("Server does not support environment [%s]\n",
1427 if (!W_ERROR_IS_OK(werror
)) {
1428 printf("Error getting driver for environment [%s] - %s\n",
1429 architecture
, win_errstr(werror
));
1433 printf("\n[%s]\n", architecture
);
1437 for (j
=0; j
< count
; j
++) {
1438 display_print_driver1(&info
[j
].info1
);
1442 for (j
=0; j
< count
; j
++) {
1443 display_print_driver2(&info
[j
].info2
);
1447 for (j
=0; j
< count
; j
++) {
1448 display_print_driver3(&info
[j
].info3
);
1452 for (j
=0; j
< count
; j
++) {
1453 display_print_driver4(&info
[j
].info4
);
1457 for (j
=0; j
< count
; j
++) {
1458 display_print_driver5(&info
[j
].info5
);
1462 for (j
=0; j
< count
; j
++) {
1463 display_print_driver6(&info
[j
].info6
);
1467 for (j
=0; j
< count
; j
++) {
1468 display_print_driver8(&info
[j
].info8
);
1472 printf("unknown info level %d\n", level
);
1473 return WERR_UNKNOWN_LEVEL
;
1479 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1480 TALLOC_CTX
*mem_ctx
,
1481 int argc
, const char **argv
)
1483 WERROR werror
= WERR_OK
;
1486 const char *architecture
= NULL
;
1489 printf("Usage: enumdrivers [level] [architecture]\n");
1494 level
= atoi(argv
[1]);
1498 architecture
= argv
[2];
1502 return enum_driver_by_architecture(cli
, mem_ctx
,
1507 /* loop through and print driver info level for each architecture */
1508 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1509 /* check to see if we already asked for this architecture string */
1511 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1515 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1516 archi_table
[i
].long_archi
,
1518 if (!W_ERROR_IS_OK(werror
)) {
1526 /****************************************************************************
1527 ****************************************************************************/
1529 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1531 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1534 /****************************************************************************
1535 ****************************************************************************/
1537 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1538 TALLOC_CTX
*mem_ctx
,
1539 int argc
, const char **argv
)
1543 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1546 union spoolss_DriverDirectoryInfo info
;
1548 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1551 printf("Usage: %s [environment]\n", argv
[0]);
1555 /* Get the arguments need to open the printer handle */
1561 /* Get the directory. Only use Info level 1 */
1563 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1564 cli
->srv_name_slash
,
1572 if (!NT_STATUS_IS_OK(status
)) {
1573 return ntstatus_to_werror(status
);
1575 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1577 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1579 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1580 cli
->srv_name_slash
,
1588 if (!NT_STATUS_IS_OK(status
)) {
1589 return ntstatus_to_werror(status
);
1593 if (W_ERROR_IS_OK(result
)) {
1594 display_printdriverdir_1(&info
.info1
);
1600 /****************************************************************************
1601 ****************************************************************************/
1603 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1604 struct spoolss_AddDriverInfo3
*info
,
1610 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1612 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1614 info
->version
= archi_table
[i
].version
;
1615 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1620 if (archi_table
[i
].long_archi
== NULL
)
1622 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1629 /**************************************************************************
1630 wrapper for strtok to get the next parameter from a delimited list.
1631 Needed to handle the empty parameter string denoted by "NULL"
1632 *************************************************************************/
1634 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1635 const char *delim
, const char **dest
,
1640 /* get the next token */
1641 ptr
= strtok_r(str
, delim
, saveptr
);
1643 /* a string of 'NULL' is used to represent an empty
1644 parameter because two consecutive delimiters
1645 will not return an empty string. See man strtok(3)
1647 if (ptr
&& (strcasecmp_m(ptr
, "NULL") == 0)) {
1652 *dest
= talloc_strdup(mem_ctx
, ptr
);
1658 /********************************************************************************
1659 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1660 string in the form of
1661 <Long Driver Name>:<Driver File Name>:<Data File Name>:\
1662 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1663 <Default Data Type>:<Comma Separated list of Files>
1664 *******************************************************************************/
1666 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1671 char *saveptr
= NULL
;
1672 struct spoolss_StringArray
*deps
;
1673 const char **file_array
= NULL
;
1676 /* fill in the UNISTR fields */
1677 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1678 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1679 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1680 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1681 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1682 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1683 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1685 /* <Comma Separated List of Dependent Files> */
1686 /* save the beginning of the string */
1687 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1690 /* begin to strip out each filename */
1691 str
= strtok_r(str
, ",", &saveptr
);
1693 /* no dependent files, we are done */
1698 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1703 while (str
!= NULL
) {
1705 ok
= add_string_to_array(deps
, str
, &file_array
, &count
);
1709 str
= strtok_r(NULL
, ",", &saveptr
);
1712 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1713 if (!deps
->string
) {
1717 for (i
=0; i
< count
; i
++) {
1718 deps
->string
[i
] = file_array
[i
];
1721 r
->dependent_files
= deps
;
1726 /****************************************************************************
1727 ****************************************************************************/
1729 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1730 TALLOC_CTX
*mem_ctx
,
1731 int argc
, const char **argv
)
1736 struct spoolss_AddDriverInfoCtr info_ctr
;
1737 struct spoolss_AddDriverInfo3 info3
;
1740 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1742 /* parse the command arguments */
1743 if (argc
!= 3 && argc
!= 4)
1745 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1746 printf ("\t<Long Driver Name>:<Driver File Name>:<Data File Name>:\\\n");
1747 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1748 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1749 printf ("\t[version]\n");
1754 /* Fill in the spoolss_AddDriverInfo3 struct */
1757 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1759 printf ("Error Unknown architecture [%s]\n", argv
[1]);
1760 return WERR_INVALID_PARAM
;
1763 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1765 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1766 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1768 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1769 return WERR_INVALID_PARAM
;
1772 /* if printer driver version specified, override the default version
1773 * used by the architecture. This allows installation of Windows
1774 * 2000 (version 3) printer drivers. */
1777 info3
.version
= atoi(argv
[3]);
1781 info_ctr
.level
= level
;
1782 info_ctr
.info
.info3
= &info3
;
1784 status
= dcerpc_spoolss_AddPrinterDriver(b
, mem_ctx
,
1785 cli
->srv_name_slash
,
1788 if (!NT_STATUS_IS_OK(status
)) {
1789 return ntstatus_to_werror(status
);
1791 if (W_ERROR_IS_OK(result
)) {
1792 printf ("Printer Driver %s successfully installed.\n",
1800 /****************************************************************************
1801 ****************************************************************************/
1803 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1804 TALLOC_CTX
*mem_ctx
,
1805 int argc
, const char **argv
)
1808 struct spoolss_SetPrinterInfoCtr info_ctr
;
1809 struct spoolss_SetPrinterInfo2 info2
;
1811 /* parse the command arguments */
1814 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1818 /* Fill in the DRIVER_INFO_2 struct */
1821 info2
.printername
= argv
[1];
1822 info2
.drivername
= argv
[3];
1823 info2
.sharename
= argv
[2];
1824 info2
.portname
= argv
[4];
1825 info2
.comment
= "Created by rpcclient";
1826 info2
.printprocessor
= "winprint";
1827 info2
.datatype
= "RAW";
1828 info2
.devmode_ptr
= NULL
;
1829 info2
.secdesc_ptr
= NULL
;
1830 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1832 info2
.defaultpriority
= 0;
1833 info2
.starttime
= 0;
1834 info2
.untiltime
= 0;
1836 /* These three fields must not be used by AddPrinter()
1837 as defined in the MS Platform SDK documentation..
1841 info2.averageppm = 0;
1845 info_ctr
.info
.info2
= &info2
;
1847 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1849 if (W_ERROR_IS_OK(result
))
1850 printf ("Printer %s successfully installed.\n", argv
[1]);
1855 /****************************************************************************
1856 ****************************************************************************/
1858 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1859 TALLOC_CTX
*mem_ctx
,
1860 int argc
, const char **argv
)
1862 struct policy_handle pol
;
1866 const char *printername
;
1867 union spoolss_PrinterInfo info
;
1868 struct spoolss_SetPrinterInfoCtr info_ctr
;
1869 struct spoolss_SetPrinterInfo2 info2
;
1870 struct spoolss_DevmodeContainer devmode_ctr
;
1871 struct sec_desc_buf secdesc_ctr
;
1872 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1874 ZERO_STRUCT(devmode_ctr
);
1875 ZERO_STRUCT(secdesc_ctr
);
1877 /* parse the command arguments */
1880 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1884 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1886 /* Get a printer handle */
1888 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1892 if (!W_ERROR_IS_OK(result
))
1895 /* Get printer info */
1897 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1902 if (!W_ERROR_IS_OK(result
)) {
1903 printf ("Unable to retrieve printer information!\n");
1907 /* Set the printer driver */
1909 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
1910 info2
.drivername
= argv
[2];
1913 info_ctr
.info
.info2
= &info2
;
1915 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
1922 if (!NT_STATUS_IS_OK(status
)) {
1923 result
= ntstatus_to_werror(status
);
1926 if (!W_ERROR_IS_OK(result
)) {
1927 printf("SetPrinter call failed!\n");
1931 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1936 if (is_valid_policy_hnd(&pol
)) {
1938 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1945 /****************************************************************************
1946 ****************************************************************************/
1948 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1949 TALLOC_CTX
*mem_ctx
,
1950 int argc
, const char **argv
)
1952 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1954 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1959 const char *arch
= NULL
;
1960 uint32_t delete_flags
= 0;
1962 /* parse the command arguments */
1963 if (argc
< 2 || argc
> 5) {
1964 printf("Usage: %s <driver> [arch] [version] [flags]\n", argv
[0]);
1971 vers
= atoi(argv
[3]);
1972 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1975 delete_flags
= atoi(argv
[4]);
1977 /* delete the driver for all architectures */
1978 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1980 if (arch
&& !strequal(archi_table
[i
].long_archi
, arch
))
1983 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1986 /* make the call to remove the driver */
1987 status
= dcerpc_spoolss_DeletePrinterDriverEx(b
, mem_ctx
,
1988 cli
->srv_name_slash
,
1989 archi_table
[i
].long_archi
,
1992 archi_table
[i
].version
,
1994 if (!NT_STATUS_IS_OK(status
)) {
1995 return ntstatus_to_werror(status
);
1997 if ( !W_ERROR_IS_OK(result
) )
1999 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
2000 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
2001 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
2006 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
2007 archi_table
[i
].long_archi
, archi_table
[i
].version
);
2016 /****************************************************************************
2017 ****************************************************************************/
2019 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
2020 TALLOC_CTX
*mem_ctx
,
2021 int argc
, const char **argv
)
2023 WERROR result
= WERR_OK
;
2026 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2028 /* parse the command arguments */
2030 printf ("Usage: %s <driver>\n", argv
[0]);
2034 /* delete the driver for all architectures */
2035 for (i
=0; archi_table
[i
].long_archi
; i
++) {
2038 /* make the call to remove the driver */
2039 status
= dcerpc_spoolss_DeletePrinterDriver(b
, mem_ctx
,
2040 cli
->srv_name_slash
,
2041 archi_table
[i
].long_archi
,
2044 if (!NT_STATUS_IS_OK(status
)) {
2045 result
= ntstatus_to_werror(status
);
2048 if ( !W_ERROR_IS_OK(result
) ) {
2049 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
2050 printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
2051 argv
[1], archi_table
[i
].long_archi
,
2052 win_errstr(result
));
2055 printf ("Driver %s removed for arch [%s].\n", argv
[1],
2056 archi_table
[i
].long_archi
);
2063 /****************************************************************************
2064 ****************************************************************************/
2066 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
2067 TALLOC_CTX
*mem_ctx
,
2068 int argc
, const char **argv
)
2072 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
2075 union spoolss_PrintProcessorDirectoryInfo info
;
2077 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2079 /* parse the command arguments */
2081 printf ("Usage: %s [environment]\n", argv
[0]);
2086 environment
= argv
[1];
2089 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2090 cli
->srv_name_slash
,
2098 if (!NT_STATUS_IS_OK(status
)) {
2099 return ntstatus_to_werror(status
);
2101 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
2103 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2105 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2106 cli
->srv_name_slash
,
2114 if (!NT_STATUS_IS_OK(status
)) {
2115 return ntstatus_to_werror(status
);
2119 if (W_ERROR_IS_OK(result
)) {
2120 printf("%s\n", info
.info1
.directory_name
);
2126 /****************************************************************************
2127 ****************************************************************************/
2129 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2130 int argc
, const char **argv
)
2132 struct policy_handle handle
;
2135 const char *printername
;
2136 struct spoolss_AddFormInfoCtr info_ctr
;
2137 struct spoolss_AddFormInfo1 info1
;
2138 struct spoolss_AddFormInfo2 info2
;
2140 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2142 /* Parse the command arguments */
2144 if (argc
< 3 || argc
> 5) {
2145 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2149 /* Get a printer handle */
2151 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2153 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2157 if (!W_ERROR_IS_OK(werror
))
2160 /* Dummy up some values for the form data */
2163 level
= atoi(argv
[3]);
2168 info1
.flags
= SPOOLSS_FORM_USER
;
2169 info1
.form_name
= argv
[2];
2170 info1
.size
.width
= 100;
2171 info1
.size
.height
= 100;
2172 info1
.area
.left
= 0;
2173 info1
.area
.top
= 10;
2174 info1
.area
.right
= 20;
2175 info1
.area
.bottom
= 30;
2178 info_ctr
.info
.info1
= &info1
;
2182 info2
.flags
= SPOOLSS_FORM_USER
;
2183 info2
.form_name
= argv
[2];
2184 info2
.size
.width
= 100;
2185 info2
.size
.height
= 100;
2186 info2
.area
.left
= 0;
2187 info2
.area
.top
= 10;
2188 info2
.area
.right
= 20;
2189 info2
.area
.bottom
= 30;
2190 info2
.keyword
= argv
[2];
2191 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2192 info2
.mui_dll
= NULL
;
2193 info2
.ressource_id
= 0;
2194 info2
.display_name
= argv
[2];
2198 info_ctr
.info
.info2
= &info2
;
2202 werror
= WERR_INVALID_PARAM
;
2208 status
= dcerpc_spoolss_AddForm(b
, mem_ctx
,
2212 if (!NT_STATUS_IS_OK(status
)) {
2213 werror
= ntstatus_to_werror(status
);
2217 if (is_valid_policy_hnd(&handle
)) {
2219 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2225 /****************************************************************************
2226 ****************************************************************************/
2228 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2229 int argc
, const char **argv
)
2231 struct policy_handle handle
;
2234 const char *printername
;
2235 struct spoolss_AddFormInfoCtr info_ctr
;
2236 struct spoolss_AddFormInfo1 info1
;
2237 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2239 /* Parse the command arguments */
2242 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2246 /* Get a printer handle */
2248 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2250 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2252 SEC_FLAG_MAXIMUM_ALLOWED
,
2254 if (!W_ERROR_IS_OK(werror
))
2257 /* Dummy up some values for the form data */
2259 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2260 info1
.size
.width
= 100;
2261 info1
.size
.height
= 100;
2262 info1
.area
.left
= 0;
2263 info1
.area
.top
= 1000;
2264 info1
.area
.right
= 2000;
2265 info1
.area
.bottom
= 3000;
2266 info1
.form_name
= argv
[2];
2268 info_ctr
.info
.info1
= &info1
;
2273 status
= dcerpc_spoolss_SetForm(b
, mem_ctx
,
2278 if (!NT_STATUS_IS_OK(status
)) {
2279 werror
= ntstatus_to_werror(status
);
2283 if (is_valid_policy_hnd(&handle
)) {
2285 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2291 /****************************************************************************
2292 ****************************************************************************/
2294 static const char *get_form_flag(int form_flag
)
2296 switch (form_flag
) {
2297 case SPOOLSS_FORM_USER
:
2299 case SPOOLSS_FORM_BUILTIN
:
2300 return "FORM_BUILTIN";
2301 case SPOOLSS_FORM_PRINTER
:
2302 return "FORM_PRINTER";
2308 /****************************************************************************
2309 ****************************************************************************/
2311 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2314 "\tflag: %s (%d)\n" \
2315 "\twidth: %d, length: %d\n" \
2316 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2317 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2318 r
->size
.width
, r
->size
.height
,
2319 r
->area
.left
, r
->area
.right
,
2320 r
->area
.top
, r
->area
.bottom
);
2323 /****************************************************************************
2324 ****************************************************************************/
2326 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2329 "\tflag: %s (%d)\n" \
2330 "\twidth: %d, length: %d\n" \
2331 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2332 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2333 r
->size
.width
, r
->size
.height
,
2334 r
->area
.left
, r
->area
.right
,
2335 r
->area
.top
, r
->area
.bottom
);
2336 printf("\tkeyword: %s\n", r
->keyword
);
2337 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2338 printf("\tmui_dll: %s\n", r
->mui_dll
);
2339 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2340 printf("\tdisplay_name: %s\n", r
->display_name
);
2341 printf("\tlang_id: %d\n", r
->lang_id
);
2345 /****************************************************************************
2346 ****************************************************************************/
2348 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2349 int argc
, const char **argv
)
2351 struct policy_handle handle
;
2354 const char *printername
;
2356 uint32_t offered
= 0;
2357 union spoolss_FormInfo info
;
2360 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2362 /* Parse the command arguments */
2364 if (argc
< 3 || argc
> 5) {
2365 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2369 /* Get a printer handle */
2371 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2373 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2375 SEC_FLAG_MAXIMUM_ALLOWED
,
2377 if (!W_ERROR_IS_OK(werror
))
2381 level
= atoi(argv
[3]);
2386 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2395 if (!NT_STATUS_IS_OK(status
)) {
2396 werror
= ntstatus_to_werror(status
);
2399 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2400 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2402 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2411 if (!NT_STATUS_IS_OK(status
)) {
2412 werror
= ntstatus_to_werror(status
);
2417 if (!W_ERROR_IS_OK(werror
)) {
2423 display_form_info1(&info
.info1
);
2426 display_form_info2(&info
.info2
);
2431 if (is_valid_policy_hnd(&handle
)) {
2433 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2439 /****************************************************************************
2440 ****************************************************************************/
2442 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2443 TALLOC_CTX
*mem_ctx
, int argc
,
2446 struct policy_handle handle
;
2449 const char *printername
;
2450 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2452 /* Parse the command arguments */
2455 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2459 /* Get a printer handle */
2461 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2463 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2465 SEC_FLAG_MAXIMUM_ALLOWED
,
2467 if (!W_ERROR_IS_OK(werror
))
2470 /* Delete the form */
2472 status
= dcerpc_spoolss_DeleteForm(b
, mem_ctx
,
2476 if (!NT_STATUS_IS_OK(status
)) {
2477 werror
= ntstatus_to_werror(status
);
2482 if (is_valid_policy_hnd(&handle
)) {
2484 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2490 /****************************************************************************
2491 ****************************************************************************/
2493 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2494 TALLOC_CTX
*mem_ctx
, int argc
,
2497 struct policy_handle handle
;
2499 const char *printername
;
2500 uint32_t num_forms
, level
= 1, i
;
2501 union spoolss_FormInfo
*forms
;
2502 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2504 /* Parse the command arguments */
2506 if (argc
< 2 || argc
> 4) {
2507 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2511 /* Get a printer handle */
2513 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2515 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2517 SEC_FLAG_MAXIMUM_ALLOWED
,
2519 if (!W_ERROR_IS_OK(werror
))
2523 level
= atoi(argv
[2]);
2526 /* Enumerate forms */
2528 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2535 if (!W_ERROR_IS_OK(werror
))
2538 /* Display output */
2540 for (i
= 0; i
< num_forms
; i
++) {
2543 display_form_info1(&forms
[i
].info1
);
2546 display_form_info2(&forms
[i
].info2
);
2552 if (is_valid_policy_hnd(&handle
)) {
2554 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2560 /****************************************************************************
2561 ****************************************************************************/
2563 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2564 TALLOC_CTX
*mem_ctx
,
2565 int argc
, const char **argv
)
2569 const char *printername
;
2570 struct policy_handle pol
= { 0, };
2571 union spoolss_PrinterInfo info
;
2572 enum winreg_Type type
;
2573 union spoolss_PrinterData data
;
2575 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2577 /* parse the command arguments */
2579 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2580 " <value> <data>\n",
2585 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2589 if (strequal(argv
[2], "string")) {
2593 if (strequal(argv
[2], "binary")) {
2597 if (strequal(argv
[2], "dword")) {
2601 if (strequal(argv
[2], "multistring")) {
2602 type
= REG_MULTI_SZ
;
2605 if (type
== REG_NONE
) {
2606 printf("Unknown data type: %s\n", argv
[2]);
2607 result
= WERR_INVALID_PARAM
;
2611 /* get a printer handle */
2613 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2615 SEC_FLAG_MAXIMUM_ALLOWED
,
2617 if (!W_ERROR_IS_OK(result
)) {
2621 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2626 if (!W_ERROR_IS_OK(result
)) {
2630 printf("%s\n", current_timestring(mem_ctx
, true));
2631 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2633 /* Set the printer data */
2637 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2638 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2641 data
.value
= strtoul(argv
[4], NULL
, 10);
2644 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2646 case REG_MULTI_SZ
: {
2649 const char **strings
= NULL
;
2653 for (i
=4; i
<argc
; i
++) {
2654 if (strcmp(argv
[i
], "NULL") == 0) {
2657 if (!add_string_to_array(mem_ctx
, argv
[i
],
2660 result
= WERR_NOMEM
;
2664 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2665 if (!data
.string_array
) {
2666 result
= WERR_NOMEM
;
2669 for (i
=0; i
< num_strings
; i
++) {
2670 data
.string_array
[i
] = strings
[i
];
2675 printf("Unknown data type: %s\n", argv
[2]);
2676 result
= WERR_INVALID_PARAM
;
2680 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2681 if (!W_ERROR_IS_OK(result
)) {
2685 status
= dcerpc_spoolss_SetPrinterData(b
, mem_ctx
,
2687 argv
[3], /* value_name */
2692 if (!NT_STATUS_IS_OK(status
)) {
2693 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2694 result
= ntstatus_to_werror(status
);
2697 if (!W_ERROR_IS_OK(result
)) {
2698 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2701 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2703 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2708 if (!W_ERROR_IS_OK(result
)) {
2712 printf("%s\n", current_timestring(mem_ctx
, true));
2713 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2717 if (is_valid_policy_hnd(&pol
)) {
2719 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
2725 /****************************************************************************
2726 ****************************************************************************/
2728 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2730 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2731 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2735 /****************************************************************************
2736 ****************************************************************************/
2738 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2740 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2741 r
->position
, r
->job_id
,
2742 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2743 r
->total_pages
, r
->size
);
2746 /****************************************************************************
2747 ****************************************************************************/
2749 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2751 printf("jobid[%d], next_jobid[%d]\n",
2752 r
->job_id
, r
->next_job_id
);
2755 /****************************************************************************
2756 ****************************************************************************/
2758 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2760 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2761 r
->position
, r
->job_id
,
2762 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2763 r
->total_pages
, r
->size
, r
->size_high
);
2766 /****************************************************************************
2767 ****************************************************************************/
2769 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2770 TALLOC_CTX
*mem_ctx
, int argc
,
2774 uint32_t level
= 1, count
, i
;
2775 const char *printername
;
2776 struct policy_handle hnd
;
2777 union spoolss_JobInfo
*info
;
2778 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2780 if (argc
< 2 || argc
> 3) {
2781 printf("Usage: %s printername [level]\n", argv
[0]);
2786 level
= atoi(argv
[2]);
2789 /* Open printer handle */
2791 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2793 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2795 SEC_FLAG_MAXIMUM_ALLOWED
,
2797 if (!W_ERROR_IS_OK(result
))
2800 /* Enumerate ports */
2802 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2810 if (!W_ERROR_IS_OK(result
)) {
2814 for (i
= 0; i
< count
; i
++) {
2817 display_job_info1(&info
[i
].info1
);
2820 display_job_info2(&info
[i
].info2
);
2823 d_printf("unknown info level %d\n", level
);
2829 if (is_valid_policy_hnd(&hnd
)) {
2831 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2837 /****************************************************************************
2838 ****************************************************************************/
2840 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2841 TALLOC_CTX
*mem_ctx
, int argc
,
2845 const char *printername
;
2846 struct policy_handle hnd
;
2849 union spoolss_JobInfo info
;
2850 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2852 if (argc
< 3 || argc
> 4) {
2853 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2857 job_id
= atoi(argv
[2]);
2860 level
= atoi(argv
[3]);
2863 /* Open printer handle */
2865 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2867 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2869 SEC_FLAG_MAXIMUM_ALLOWED
,
2871 if (!W_ERROR_IS_OK(result
)) {
2875 /* Enumerate ports */
2877 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2884 if (!W_ERROR_IS_OK(result
)) {
2890 display_job_info1(&info
.info1
);
2893 display_job_info2(&info
.info2
);
2896 display_job_info3(&info
.info3
);
2899 display_job_info4(&info
.info4
);
2902 d_printf("unknown info level %d\n", level
);
2907 if (is_valid_policy_hnd(&hnd
)) {
2909 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2915 /****************************************************************************
2916 ****************************************************************************/
2920 enum spoolss_JobControl val
;
2922 {"PAUSE", SPOOLSS_JOB_CONTROL_PAUSE
},
2923 {"RESUME", SPOOLSS_JOB_CONTROL_RESUME
},
2924 {"CANCEL", SPOOLSS_JOB_CONTROL_CANCEL
},
2925 {"RESTART", SPOOLSS_JOB_CONTROL_RESTART
},
2926 {"DELETE", SPOOLSS_JOB_CONTROL_DELETE
},
2927 {"SEND_TO_PRINTER", SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER
},
2928 {"EJECTED", SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED
},
2929 {"RETAIN", SPOOLSS_JOB_CONTROL_RETAIN
},
2930 {"RELEASE", SPOOLSS_JOB_CONTROL_RELEASE
}
2933 static enum spoolss_JobControl
parse_setjob_command(const char *cmd
)
2937 for (i
= 0; i
< sizeof(cmdvals
)/sizeof(cmdvals
[0]); i
++) {
2938 if (strequal(cmdvals
[i
].name
, cmd
)) {
2939 return cmdvals
[i
].val
;
2942 return (enum spoolss_JobControl
)atoi(cmd
);
2945 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2946 TALLOC_CTX
*mem_ctx
, int argc
,
2951 const char *printername
;
2952 struct policy_handle hnd
;
2954 enum spoolss_JobControl command
;
2955 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2958 printf("Usage: %s printername job_id command\n", argv
[0]);
2959 printf("command = [PAUSE|RESUME|CANCEL|RESTART|DELETE|"
2960 "SEND_TO_PRINTER|EJECTED|RETAIN|RELEASE]\n");
2964 job_id
= atoi(argv
[2]);
2965 command
= parse_setjob_command(argv
[3]);
2967 /* Open printer handle */
2969 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2971 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2973 SEC_FLAG_MAXIMUM_ALLOWED
,
2975 if (!W_ERROR_IS_OK(result
)) {
2981 status
= dcerpc_spoolss_SetJob(b
, mem_ctx
,
2987 if (!NT_STATUS_IS_OK(status
)) {
2988 result
= ntstatus_to_werror(status
);
2991 if (!W_ERROR_IS_OK(result
)) {
2996 if (is_valid_policy_hnd(&hnd
)) {
2998 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3004 /****************************************************************************
3005 ****************************************************************************/
3007 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
3008 TALLOC_CTX
*mem_ctx
, int argc
,
3013 const char *printername
;
3014 struct policy_handle hnd
;
3015 uint32_t value_needed
;
3016 enum winreg_Type type
;
3017 uint32_t data_needed
;
3018 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3019 struct spoolss_EnumPrinterData r
;
3022 printf("Usage: %s printername\n", argv
[0]);
3026 /* Open printer handle */
3028 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3030 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3032 SEC_FLAG_MAXIMUM_ALLOWED
,
3034 if (!W_ERROR_IS_OK(result
)) {
3038 /* Enumerate data */
3041 r
.in
.enum_index
= 0;
3042 r
.in
.value_offered
= 0;
3043 r
.in
.data_offered
= 0;
3044 r
.out
.value_name
= NULL
;
3045 r
.out
.value_needed
= &value_needed
;
3048 r
.out
.data_needed
= &data_needed
;
3050 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3051 if (!NT_STATUS_IS_OK(status
)) {
3052 result
= ntstatus_to_werror(status
);
3056 if (!W_ERROR_IS_OK(r
.out
.result
)) {
3057 result
= r
.out
.result
;
3061 r
.in
.data_offered
= *r
.out
.data_needed
;
3062 r
.in
.value_offered
= *r
.out
.value_needed
;
3063 r
.out
.data
= talloc_zero_array(mem_ctx
, uint8_t, r
.in
.data_offered
);
3064 r
.out
.value_name
= talloc_zero_array(mem_ctx
, char, r
.in
.value_offered
);
3068 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3069 if (!NT_STATUS_IS_OK(status
)) {
3070 result
= ntstatus_to_werror(status
);
3074 if (W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
3081 display_reg_value(r
.out
.value_name
, *r
.out
.type
,
3082 data_blob_const(r
.out
.data
, r
.in
.data_offered
));
3084 } while (W_ERROR_IS_OK(r
.out
.result
));
3087 if (is_valid_policy_hnd(&hnd
)) {
3089 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3095 /****************************************************************************
3096 ****************************************************************************/
3098 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
3099 TALLOC_CTX
*mem_ctx
, int argc
,
3104 const char *printername
;
3105 struct policy_handle hnd
;
3107 struct spoolss_PrinterEnumValues
*info
;
3108 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3111 printf("Usage: %s printername <keyname>\n", argv
[0]);
3115 /* Open printer handle */
3117 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3119 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3121 SEC_FLAG_MAXIMUM_ALLOWED
,
3123 if (!W_ERROR_IS_OK(result
)) {
3127 /* Enumerate subkeys */
3129 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
3135 if (!W_ERROR_IS_OK(result
)) {
3139 for (i
=0; i
< count
; i
++) {
3140 display_printer_data(info
[i
].value_name
,
3143 info
[i
].data
->length
);
3147 if (is_valid_policy_hnd(&hnd
)) {
3149 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3155 /****************************************************************************
3156 ****************************************************************************/
3158 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
3159 TALLOC_CTX
*mem_ctx
, int argc
,
3163 const char *printername
;
3164 const char *keyname
= NULL
;
3165 struct policy_handle hnd
;
3166 const char **key_buffer
= NULL
;
3168 uint32_t offered
= 0;
3169 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3171 if (argc
< 2 || argc
> 4) {
3172 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
3183 offered
= atoi(argv
[3]);
3186 /* Open printer handle */
3188 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3190 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3192 SEC_FLAG_MAXIMUM_ALLOWED
,
3194 if (!W_ERROR_IS_OK(result
)) {
3198 /* Enumerate subkeys */
3200 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
3206 if (!W_ERROR_IS_OK(result
)) {
3210 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
3211 printf("%s\n", key_buffer
[i
]);
3216 if (is_valid_policy_hnd(&hnd
)) {
3218 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3224 /****************************************************************************
3225 ****************************************************************************/
3227 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
3228 TALLOC_CTX
*mem_ctx
, int argc
,
3231 const char *printername
;
3232 const char *clientname
;
3233 struct policy_handle hnd
= { 0, };
3236 struct spoolss_NotifyOption option
;
3237 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3240 printf("Usage: %s printername\n", argv
[0]);
3247 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3249 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3251 SEC_FLAG_MAXIMUM_ALLOWED
,
3253 if (!W_ERROR_IS_OK(result
)) {
3254 printf("Error opening %s\n", argv
[1]);
3258 /* Create spool options */
3263 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3264 if (option
.types
== NULL
) {
3265 result
= WERR_NOMEM
;
3269 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3270 option
.types
[0].count
= 1;
3271 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3272 if (option
.types
[0].fields
== NULL
) {
3273 result
= WERR_NOMEM
;
3276 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3278 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3279 option
.types
[1].count
= 1;
3280 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3281 if (option
.types
[1].fields
== NULL
) {
3282 result
= WERR_NOMEM
;
3285 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3287 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", lp_netbios_name());
3289 result
= WERR_NOMEM
;
3295 status
= dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(b
, mem_ctx
,
3303 if (!NT_STATUS_IS_OK(status
)) {
3304 result
= ntstatus_to_werror(status
);
3307 if (!W_ERROR_IS_OK(result
)) {
3308 printf("Error rffpcnex %s\n", argv
[1]);
3313 if (is_valid_policy_hnd(&hnd
)) {
3315 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3321 /****************************************************************************
3322 ****************************************************************************/
3324 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3325 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3327 union spoolss_PrinterInfo info1
, info2
;
3329 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3331 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3332 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3337 if ( !W_ERROR_IS_OK(werror
) ) {
3338 printf("failed (%s)\n", win_errstr(werror
));
3339 talloc_destroy(mem_ctx
);
3344 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3345 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3350 if ( !W_ERROR_IS_OK(werror
) ) {
3351 printf("failed (%s)\n", win_errstr(werror
));
3352 talloc_destroy(mem_ctx
);
3357 talloc_destroy(mem_ctx
);
3362 /****************************************************************************
3363 ****************************************************************************/
3365 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3366 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3368 union spoolss_PrinterInfo info1
, info2
;
3370 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3371 struct security_descriptor
*sd1
, *sd2
;
3375 printf("Retrieving printer security for %s...", cli1
->desthost
);
3376 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3381 if ( !W_ERROR_IS_OK(werror
) ) {
3382 printf("failed (%s)\n", win_errstr(werror
));
3388 printf("Retrieving printer security for %s...", cli2
->desthost
);
3389 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3394 if ( !W_ERROR_IS_OK(werror
) ) {
3395 printf("failed (%s)\n", win_errstr(werror
));
3404 sd1
= info1
.info3
.secdesc
;
3405 sd2
= info2
.info3
.secdesc
;
3407 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3408 printf("NULL secdesc!\n");
3413 if (!security_descriptor_equal( sd1
, sd2
) ) {
3414 printf("Security Descriptors *not* equal!\n");
3419 printf("Security descriptors match\n");
3422 talloc_destroy(mem_ctx
);
3427 /****************************************************************************
3428 ****************************************************************************/
3430 extern struct user_auth_info
*rpcclient_auth_info
;
3432 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3433 TALLOC_CTX
*mem_ctx
, int argc
,
3436 const char *printername
;
3437 char *printername_path
= NULL
;
3438 struct cli_state
*cli_server2
= NULL
;
3439 struct rpc_pipe_client
*cli2
= NULL
;
3440 struct policy_handle hPrinter1
, hPrinter2
;
3445 printf("Usage: %s <printer> <server>\n", argv
[0]);
3449 printername
= argv
[1];
3451 /* first get the connection to the remote server */
3453 nt_status
= cli_full_connection(&cli_server2
, lp_netbios_name(), argv
[2],
3456 get_cmdline_auth_info_username(rpcclient_auth_info
),
3458 get_cmdline_auth_info_password(rpcclient_auth_info
),
3459 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3460 get_cmdline_auth_info_signing_state(rpcclient_auth_info
));
3462 if ( !NT_STATUS_IS_OK(nt_status
) )
3463 return WERR_GENERAL_FAILURE
;
3465 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
,
3467 if (!NT_STATUS_IS_OK(nt_status
)) {
3468 printf("failed to open spoolss pipe on server %s (%s)\n",
3469 argv
[2], nt_errstr(nt_status
));
3470 return WERR_GENERAL_FAILURE
;
3473 /* now open up both printers */
3475 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3477 printf("Opening %s...", printername_path
);
3479 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3483 if ( !W_ERROR_IS_OK(werror
) ) {
3484 printf("failed (%s)\n", win_errstr(werror
));
3489 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3491 printf("Opening %s...", printername_path
);
3492 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3496 if ( !W_ERROR_IS_OK(werror
) ) {
3497 printf("failed (%s)\n", win_errstr(werror
));
3502 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3503 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3505 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3512 printf("Closing printers...");
3515 dcerpc_spoolss_ClosePrinter(cli
->binding_handle
, mem_ctx
, &hPrinter1
, &_result
);
3516 dcerpc_spoolss_ClosePrinter(cli2
->binding_handle
, mem_ctx
, &hPrinter2
, &_result
);
3520 /* close the second remote connection */
3522 cli_shutdown( cli_server2
);
3526 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3528 printf("print_processor_name: %s\n", r
->print_processor_name
);
3531 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3532 TALLOC_CTX
*mem_ctx
, int argc
,
3536 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3537 uint32_t num_procs
, level
= 1, i
;
3538 union spoolss_PrintProcessorInfo
*procs
;
3540 /* Parse the command arguments */
3542 if (argc
< 1 || argc
> 4) {
3543 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3548 environment
= argv
[1];
3552 level
= atoi(argv
[2]);
3555 /* Enumerate Print Processors */
3557 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3558 cli
->srv_name_slash
,
3564 if (!W_ERROR_IS_OK(werror
))
3567 /* Display output */
3569 for (i
= 0; i
< num_procs
; i
++) {
3572 display_proc_info1(&procs
[i
].info1
);
3581 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3583 printf("name_array: %s\n", r
->name_array
);
3586 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3587 TALLOC_CTX
*mem_ctx
, int argc
,
3591 const char *print_processor_name
= "winprint";
3592 uint32_t num_procs
, level
= 1, i
;
3593 union spoolss_PrintProcDataTypesInfo
*procs
;
3595 /* Parse the command arguments */
3597 if (argc
< 1 || argc
> 4) {
3598 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3603 print_processor_name
= argv
[1];
3607 level
= atoi(argv
[2]);
3610 /* Enumerate Print Processor Data Types */
3612 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3613 cli
->srv_name_slash
,
3614 print_processor_name
,
3619 if (!W_ERROR_IS_OK(werror
))
3622 /* Display output */
3624 for (i
= 0; i
< num_procs
; i
++) {
3627 display_proc_data_types_info1(&procs
[i
].info1
);
3636 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3638 printf("monitor_name: %s\n", r
->monitor_name
);
3641 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3643 printf("monitor_name: %s\n", r
->monitor_name
);
3644 printf("environment: %s\n", r
->environment
);
3645 printf("dll_name: %s\n", r
->dll_name
);
3648 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3649 TALLOC_CTX
*mem_ctx
, int argc
,
3653 uint32_t count
, level
= 1, i
;
3654 union spoolss_MonitorInfo
*info
;
3656 /* Parse the command arguments */
3659 printf("Usage: %s [level]\n", argv
[0]);
3664 level
= atoi(argv
[1]);
3667 /* Enumerate Print Monitors */
3669 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3670 cli
->srv_name_slash
,
3675 if (!W_ERROR_IS_OK(werror
)) {
3679 /* Display output */
3681 for (i
= 0; i
< count
; i
++) {
3684 display_monitor1(&info
[i
].info1
);
3687 display_monitor2(&info
[i
].info2
);
3696 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3697 TALLOC_CTX
*mem_ctx
, int argc
,
3702 struct policy_handle handle
, gdi_handle
;
3703 const char *printername
;
3704 struct spoolss_DevmodeContainer devmode_ctr
;
3705 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3707 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3709 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3711 SEC_FLAG_MAXIMUM_ALLOWED
,
3713 if (!W_ERROR_IS_OK(result
)) {
3717 ZERO_STRUCT(devmode_ctr
);
3719 status
= dcerpc_spoolss_CreatePrinterIC(b
, mem_ctx
,
3724 if (!NT_STATUS_IS_OK(status
)) {
3725 result
= ntstatus_to_werror(status
);
3728 if (!W_ERROR_IS_OK(result
)) {
3733 if (is_valid_policy_hnd(&gdi_handle
)) {
3735 dcerpc_spoolss_DeletePrinterIC(b
, mem_ctx
, &gdi_handle
, &_result
);
3737 if (is_valid_policy_hnd(&handle
)) {
3739 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
3745 static WERROR
cmd_spoolss_play_gdi_script_on_printer_ic(struct rpc_pipe_client
*cli
,
3746 TALLOC_CTX
*mem_ctx
, int argc
,
3751 struct policy_handle handle
, gdi_handle
;
3752 const char *printername
;
3753 struct spoolss_DevmodeContainer devmode_ctr
;
3754 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3758 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3760 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3762 SEC_FLAG_MAXIMUM_ALLOWED
,
3764 if (!W_ERROR_IS_OK(result
)) {
3768 ZERO_STRUCT(devmode_ctr
);
3770 status
= dcerpc_spoolss_CreatePrinterIC(b
, mem_ctx
,
3775 if (!NT_STATUS_IS_OK(status
)) {
3776 result
= ntstatus_to_werror(status
);
3779 if (!W_ERROR_IS_OK(result
)) {
3783 in
= data_blob_string_const("");
3784 out
= data_blob_talloc_zero(mem_ctx
, 4);
3786 status
= dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b
, mem_ctx
,
3794 if (!NT_STATUS_IS_OK(status
)) {
3795 result
= ntstatus_to_werror(status
);
3798 if (!W_ERROR_IS_OK(result
)) {
3802 count
= IVAL(out
.data
, 0);
3804 out
= data_blob_talloc_zero(mem_ctx
,
3805 count
* sizeof(struct UNIVERSAL_FONT_ID
) + 4);
3807 status
= dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b
, mem_ctx
,
3815 if (!NT_STATUS_IS_OK(status
)) {
3816 result
= ntstatus_to_werror(status
);
3819 if (!W_ERROR_IS_OK(result
)) {
3824 enum ndr_err_code ndr_err
;
3825 struct UNIVERSAL_FONT_ID_ctr r
;
3827 ndr_err
= ndr_pull_struct_blob(&out
, mem_ctx
, &r
,
3828 (ndr_pull_flags_fn_t
)ndr_pull_UNIVERSAL_FONT_ID_ctr
);
3829 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
3830 NDR_PRINT_DEBUG(UNIVERSAL_FONT_ID_ctr
, &r
);
3835 if (is_valid_policy_hnd(&gdi_handle
)) {
3837 dcerpc_spoolss_DeletePrinterIC(b
, mem_ctx
, &gdi_handle
, &_result
);
3839 if (is_valid_policy_hnd(&handle
)) {
3841 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
3847 /* List of commands exported by this module */
3848 struct cmd_set spoolss_commands
[] = {
3852 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
, NULL
, "Add a print driver", "" },
3853 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
, NULL
, "Add a printer", "" },
3854 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
, NULL
, "Delete a printer driver", "" },
3855 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
, NULL
, "Delete a printer driver with files", "" },
3856 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
, NULL
, "Enumerate printer data", "" },
3857 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
, NULL
, "Enumerate printer data for a key", "" },
3858 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
, NULL
, "Enumerate printer keys", "" },
3859 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
, NULL
, "Enumerate print jobs", "" },
3860 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
, NULL
, "Get print job", "" },
3861 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
, NULL
, "Set print job", "" },
3862 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
, NULL
, "Enumerate printer ports", "" },
3863 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
, NULL
, "Enumerate installed printer drivers", "" },
3864 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
, NULL
, "Enumerate printers", "" },
3865 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
, NULL
, "Get print driver data", "" },
3866 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
, NULL
, "Get printer driver data with keyname", ""},
3867 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
, NULL
, "Get print driver information", "" },
3868 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
, NULL
, "Get print driver upload directory", "" },
3869 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
, NULL
, "Get printer info", "" },
3870 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer
, &ndr_table_spoolss
, NULL
, "Open printer handle", "" },
3871 { "openprinter_ex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
, NULL
, "Open printer handle", "" },
3872 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
, NULL
, "Set printer driver", "" },
3873 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
, NULL
, "Get print processor directory", "" },
3874 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
, NULL
, "Add form", "" },
3875 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
, NULL
, "Set form", "" },
3876 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
, NULL
, "Get form", "" },
3877 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
, NULL
, "Delete form", "" },
3878 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
, NULL
, "Enumerate forms", "" },
3879 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
, NULL
, "Set printer comment", "" },
3880 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
, NULL
, "Set printername", "" },
3881 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
, NULL
, "Set REG_SZ printer data", "" },
3882 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
, NULL
, "Rffpcnex test", "" },
3883 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
, NULL
, "Printer comparison test", "" },
3884 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
, NULL
, "Enumerate Print Processors", "" },
3885 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
, NULL
, "Enumerate Print Processor Data Types", "" },
3886 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
, NULL
, "Enumerate Print Monitors", "" },
3887 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
, NULL
, "Create Printer IC", "" },
3888 { "playgdiscriptonprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_play_gdi_script_on_printer_ic
, &ndr_table_spoolss
, NULL
, "Create Printer IC", "" },