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
)) {
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') {
867 if (strequal(v
, "OsVersion")) {
868 struct spoolss_OSVersion os
;
869 ndr_err
= ndr_pull_struct_blob(&blob
, talloc_tos(), &os
,
870 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_OSVersion
);
871 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
872 printf("%s: OsVersion:\n", v
);
873 NDR_PRINT_DEBUG(spoolss_OSVersion
, &os
);
876 if (strequal(v
, "OsVersionEx")) {
877 struct spoolss_OSVersionEx os
;
878 ndr_err
= ndr_pull_struct_blob(&blob
, talloc_tos(), &os
,
879 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_OSVersionEx
);
880 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
881 printf("%s: OsVersionEx:\n", v
);
882 NDR_PRINT_DEBUG(spoolss_OSVersionEx
, &os
);
888 printf("%s: REG_MULTI_SZ: ", v
);
889 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
890 printf("%s ", r
.string_array
[i
]);
895 printf("%s: unknown type 0x%02x:\n", v
, type
);
900 /****************************************************************************
901 ****************************************************************************/
903 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
905 int argc
, const char **argv
)
907 struct policy_handle pol
;
910 const char *valuename
;
911 enum winreg_Type type
;
914 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
917 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
918 printf("<printername> of . queries print server\n");
923 /* Open a printer handle */
925 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
926 fstrcpy(printername
, cli
->srv_name_slash
);
928 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
929 cli
->srv_name_slash
, argv
[1]);
931 /* get a printer handle */
933 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
935 SEC_FLAG_MAXIMUM_ALLOWED
,
937 if (!W_ERROR_IS_OK(result
))
940 /* Get printer info */
942 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
,
949 if (!W_ERROR_IS_OK(result
))
952 /* Display printer data */
954 display_printer_data(valuename
, type
, data
, needed
);
957 if (is_valid_policy_hnd(&pol
)) {
959 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
965 /****************************************************************************
966 ****************************************************************************/
968 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
970 int argc
, const char **argv
)
972 struct policy_handle pol
;
976 const char *valuename
, *keyname
;
978 enum winreg_Type type
;
979 uint8_t *data
= NULL
;
980 uint32_t offered
= 0;
982 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
985 printf("Usage: %s <printername> <keyname> <valuename>\n",
987 printf("<printername> of . queries print server\n");
993 /* Open a printer handle */
995 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
996 fstrcpy(printername
, cli
->srv_name_slash
);
998 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
999 cli
->srv_name_slash
, argv
[1]);
1001 /* get a printer handle */
1003 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1005 SEC_FLAG_MAXIMUM_ALLOWED
,
1007 if (!W_ERROR_IS_OK(result
))
1010 /* Get printer info */
1012 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
1017 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1026 if (!NT_STATUS_IS_OK(status
)) {
1027 result
= ntstatus_to_werror(status
);
1030 if (W_ERROR_EQUAL(result
, WERR_MORE_DATA
)) {
1032 data
= talloc_zero_array(mem_ctx
, uint8_t, offered
);
1036 status
= dcerpc_spoolss_GetPrinterDataEx(b
, mem_ctx
,
1047 if (!NT_STATUS_IS_OK(status
)) {
1048 result
= ntstatus_to_werror(status
);
1052 if (!W_ERROR_IS_OK(result
))
1055 /* Display printer data */
1057 display_printer_data(valuename
, type
, data
, needed
);
1061 if (is_valid_policy_hnd(&pol
)) {
1063 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1069 /****************************************************************************
1070 ****************************************************************************/
1072 static void display_print_driver1(struct spoolss_DriverInfo1
*r
)
1078 printf("Printer Driver Info 1:\n");
1079 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1083 /****************************************************************************
1084 ****************************************************************************/
1086 static void display_print_driver2(struct spoolss_DriverInfo2
*r
)
1092 printf("Printer Driver Info 2:\n");
1093 printf("\tVersion: [%x]\n", r
->version
);
1094 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1095 printf("\tArchitecture: [%s]\n", r
->architecture
);
1096 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1097 printf("\tDatafile: [%s]\n", r
->data_file
);
1098 printf("\tConfigfile: [%s]\n", r
->config_file
);
1102 /****************************************************************************
1103 ****************************************************************************/
1105 static void display_print_driver3(struct spoolss_DriverInfo3
*r
)
1113 printf("Printer Driver Info 3:\n");
1114 printf("\tVersion: [%x]\n", r
->version
);
1115 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1116 printf("\tArchitecture: [%s]\n", r
->architecture
);
1117 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1118 printf("\tDatafile: [%s]\n", r
->data_file
);
1119 printf("\tConfigfile: [%s]\n", r
->config_file
);
1120 printf("\tHelpfile: [%s]\n", r
->help_file
);
1122 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1123 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1126 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1127 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1131 /****************************************************************************
1132 ****************************************************************************/
1134 static void display_print_driver4(struct spoolss_DriverInfo4
*r
)
1142 printf("Printer Driver Info 4:\n");
1143 printf("\tVersion: [%x]\n", r
->version
);
1144 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1145 printf("\tArchitecture: [%s]\n", r
->architecture
);
1146 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1147 printf("\tDatafile: [%s]\n", r
->data_file
);
1148 printf("\tConfigfile: [%s]\n", r
->config_file
);
1149 printf("\tHelpfile: [%s]\n", r
->help_file
);
1151 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1152 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1155 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1156 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1158 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1159 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1164 /****************************************************************************
1165 ****************************************************************************/
1167 static void display_print_driver5(struct spoolss_DriverInfo5
*r
)
1173 printf("Printer Driver Info 5:\n");
1174 printf("\tVersion: [%x]\n", r
->version
);
1175 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1176 printf("\tArchitecture: [%s]\n", r
->architecture
);
1177 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1178 printf("\tDatafile: [%s]\n", r
->data_file
);
1179 printf("\tConfigfile: [%s]\n", r
->config_file
);
1180 printf("\tDriver Attributes: [0x%x]\n", r
->driver_attributes
);
1181 printf("\tConfig Version: [0x%x]\n", r
->config_version
);
1182 printf("\tDriver Version: [0x%x]\n", r
->driver_version
);
1186 /****************************************************************************
1187 ****************************************************************************/
1189 static void display_print_driver6(struct spoolss_DriverInfo6
*r
)
1197 printf("Printer Driver Info 6:\n");
1198 printf("\tVersion: [%x]\n", r
->version
);
1199 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1200 printf("\tArchitecture: [%s]\n", r
->architecture
);
1201 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1202 printf("\tDatafile: [%s]\n", r
->data_file
);
1203 printf("\tConfigfile: [%s]\n", r
->config_file
);
1204 printf("\tHelpfile: [%s]\n", r
->help_file
);
1206 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1207 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1210 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1211 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1213 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1214 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1217 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1218 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1219 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1220 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1221 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1222 printf("\tProvider: [%s]\n", r
->provider
);
1227 /****************************************************************************
1228 ****************************************************************************/
1230 static void display_print_driver8(struct spoolss_DriverInfo8
*r
)
1238 printf("Printer Driver Info 8:\n");
1239 printf("\tVersion: [%x]\n", r
->version
);
1240 printf("\tDriver Name: [%s]\n", r
->driver_name
);
1241 printf("\tArchitecture: [%s]\n", r
->architecture
);
1242 printf("\tDriver Path: [%s]\n", r
->driver_path
);
1243 printf("\tDatafile: [%s]\n", r
->data_file
);
1244 printf("\tConfigfile: [%s]\n", r
->config_file
);
1245 printf("\tHelpfile: [%s]\n", r
->help_file
);
1246 printf("\tMonitorname: [%s]\n", r
->monitor_name
);
1247 printf("\tDefaultdatatype: [%s]\n", r
->default_datatype
);
1249 for (i
=0; r
->dependent_files
&& r
->dependent_files
[i
] != NULL
; i
++) {
1250 printf("\tDependentfiles: [%s]\n", r
->dependent_files
[i
]);
1253 for (i
=0; r
->previous_names
&& r
->previous_names
[i
] != NULL
; i
++) {
1254 printf("\tPrevious Names: [%s]\n", r
->previous_names
[i
]);
1257 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r
->driver_date
));
1258 printf("\tDriver Version: [0x%016llx]\n", (long long unsigned int)r
->driver_version
);
1259 printf("\tManufacturer Name: [%s]\n", r
->manufacturer_name
);
1260 printf("\tManufacturer Url: [%s]\n", r
->manufacturer_url
);
1261 printf("\tHardware ID: [%s]\n", r
->hardware_id
);
1262 printf("\tProvider: [%s]\n", r
->provider
);
1263 printf("\tPrint Processor: [%s]\n", r
->print_processor
);
1264 printf("\tVendor Setup: [%s]\n", r
->vendor_setup
);
1265 for (i
=0; r
->color_profiles
&& r
->color_profiles
[i
] != NULL
; i
++) {
1266 printf("\tColor Profiles: [%s]\n", r
->color_profiles
[i
]);
1268 printf("\tInf Path: [%s]\n", r
->inf_path
);
1269 printf("\tPrinter Driver Attributes: [0x%x]\n", r
->printer_driver_attributes
);
1270 for (i
=0; r
->core_driver_dependencies
&& r
->core_driver_dependencies
[i
] != NULL
; i
++) {
1271 printf("\tCore Driver Dependencies: [%s]\n", r
->core_driver_dependencies
[i
]);
1273 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r
->min_inbox_driver_ver_date
));
1274 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n",
1275 (long long unsigned int)r
->min_inbox_driver_ver_version
);
1280 /****************************************************************************
1281 ****************************************************************************/
1283 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
1284 TALLOC_CTX
*mem_ctx
,
1285 int argc
, const char **argv
)
1287 struct policy_handle pol
;
1290 const char *printername
;
1292 bool success
= false;
1293 union spoolss_DriverInfo info
;
1294 uint32_t server_major_version
;
1295 uint32_t server_minor_version
;
1296 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1298 if ((argc
== 1) || (argc
> 3)) {
1299 printf("Usage: %s <printername> [level]\n", argv
[0]);
1303 /* get the arguments need to open the printer handle */
1305 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1308 level
= atoi(argv
[2]);
1311 /* Open a printer handle */
1313 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1317 if (!W_ERROR_IS_OK(werror
)) {
1318 printf("Error opening printer handle for %s!\n", printername
);
1322 /* loop through and print driver info level for each architecture */
1324 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1326 werror
= rpccli_spoolss_getprinterdriver2(cli
, mem_ctx
,
1328 archi_table
[i
].long_archi
,
1331 archi_table
[i
].version
,
1334 &server_major_version
,
1335 &server_minor_version
);
1336 if (!W_ERROR_IS_OK(werror
)) {
1340 /* need at least one success */
1344 printf("\n[%s]\n", archi_table
[i
].long_archi
);
1348 display_print_driver1(&info
.info1
);
1351 display_print_driver2(&info
.info2
);
1354 display_print_driver3(&info
.info3
);
1357 display_print_driver4(&info
.info4
);
1360 display_print_driver5(&info
.info5
);
1363 display_print_driver6(&info
.info6
);
1366 display_print_driver8(&info
.info8
);
1369 printf("unknown info level %d\n", level
);
1376 if (is_valid_policy_hnd(&pol
)) {
1378 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1388 /****************************************************************************
1389 ****************************************************************************/
1391 static WERROR
enum_driver_by_architecture(struct rpc_pipe_client
*cli
,
1392 TALLOC_CTX
*mem_ctx
,
1393 const char *architecture
,
1398 union spoolss_DriverInfo
*info
= NULL
;
1401 werror
= rpccli_spoolss_enumprinterdrivers(cli
, mem_ctx
,
1402 cli
->srv_name_slash
,
1409 if (W_ERROR_EQUAL(werror
, WERR_INVALID_ENVIRONMENT
)) {
1410 printf("Server does not support environment [%s]\n",
1419 if (!W_ERROR_IS_OK(werror
)) {
1420 printf("Error getting driver for environment [%s] - %s\n",
1421 architecture
, win_errstr(werror
));
1425 printf("\n[%s]\n", architecture
);
1429 for (j
=0; j
< count
; j
++) {
1430 display_print_driver1(&info
[j
].info1
);
1434 for (j
=0; j
< count
; j
++) {
1435 display_print_driver2(&info
[j
].info2
);
1439 for (j
=0; j
< count
; j
++) {
1440 display_print_driver3(&info
[j
].info3
);
1444 for (j
=0; j
< count
; j
++) {
1445 display_print_driver4(&info
[j
].info4
);
1449 for (j
=0; j
< count
; j
++) {
1450 display_print_driver5(&info
[j
].info5
);
1454 for (j
=0; j
< count
; j
++) {
1455 display_print_driver6(&info
[j
].info6
);
1459 for (j
=0; j
< count
; j
++) {
1460 display_print_driver8(&info
[j
].info8
);
1464 printf("unknown info level %d\n", level
);
1465 return WERR_UNKNOWN_LEVEL
;
1471 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1472 TALLOC_CTX
*mem_ctx
,
1473 int argc
, const char **argv
)
1475 WERROR werror
= WERR_OK
;
1478 const char *architecture
= NULL
;
1481 printf("Usage: enumdrivers [level] [architecture]\n");
1486 level
= atoi(argv
[1]);
1490 architecture
= argv
[2];
1494 return enum_driver_by_architecture(cli
, mem_ctx
,
1499 /* loop through and print driver info level for each architecture */
1500 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1501 /* check to see if we already asked for this architecture string */
1503 if (i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
)) {
1507 werror
= enum_driver_by_architecture(cli
, mem_ctx
,
1508 archi_table
[i
].long_archi
,
1510 if (!W_ERROR_IS_OK(werror
)) {
1518 /****************************************************************************
1519 ****************************************************************************/
1521 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1
*r
)
1523 printf("\tDirectory Name:[%s]\n", r
->directory_name
);
1526 /****************************************************************************
1527 ****************************************************************************/
1529 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1530 TALLOC_CTX
*mem_ctx
,
1531 int argc
, const char **argv
)
1535 const char *env
= SPOOLSS_ARCHITECTURE_NT_X86
;
1538 union spoolss_DriverDirectoryInfo info
;
1540 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1543 printf("Usage: %s [environment]\n", argv
[0]);
1547 /* Get the arguments need to open the printer handle */
1553 /* Get the directory. Only use Info level 1 */
1555 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1556 cli
->srv_name_slash
,
1564 if (!NT_STATUS_IS_OK(status
)) {
1565 return ntstatus_to_werror(status
);
1567 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
1569 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
1571 status
= dcerpc_spoolss_GetPrinterDriverDirectory(b
, mem_ctx
,
1572 cli
->srv_name_slash
,
1580 if (!NT_STATUS_IS_OK(status
)) {
1581 return ntstatus_to_werror(status
);
1585 if (W_ERROR_IS_OK(result
)) {
1586 display_printdriverdir_1(&info
.info1
);
1592 /****************************************************************************
1593 ****************************************************************************/
1595 static void set_drv_info_3_env(TALLOC_CTX
*mem_ctx
,
1596 struct spoolss_AddDriverInfo3
*info
,
1602 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1604 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1606 info
->version
= archi_table
[i
].version
;
1607 info
->architecture
= talloc_strdup(mem_ctx
, archi_table
[i
].long_archi
);
1612 if (archi_table
[i
].long_archi
== NULL
)
1614 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1621 /**************************************************************************
1622 wrapper for strtok to get the next parameter from a delimited list.
1623 Needed to handle the empty parameter string denoted by "NULL"
1624 *************************************************************************/
1626 static char *get_driver_3_param(TALLOC_CTX
*mem_ctx
, char *str
,
1627 const char *delim
, const char **dest
,
1632 /* get the next token */
1633 ptr
= strtok_r(str
, delim
, saveptr
);
1635 /* a string of 'NULL' is used to represent an empty
1636 parameter because two consecutive delimiters
1637 will not return an empty string. See man strtok(3)
1639 if (ptr
&& (strcasecmp_m(ptr
, "NULL") == 0)) {
1644 *dest
= talloc_strdup(mem_ctx
, ptr
);
1650 /********************************************************************************
1651 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1652 string in the form of
1653 <Long Driver Name>:<Driver File Name>:<Data File Name>:\
1654 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1655 <Default Data Type>:<Comma Separated list of Files>
1656 *******************************************************************************/
1658 static bool init_drv_info_3_members(TALLOC_CTX
*mem_ctx
, struct spoolss_AddDriverInfo3
*r
,
1663 char *saveptr
= NULL
;
1664 struct spoolss_StringArray
*deps
;
1665 const char **file_array
= NULL
;
1668 /* fill in the UNISTR fields */
1669 str
= get_driver_3_param(mem_ctx
, args
, ":", &r
->driver_name
, &saveptr
);
1670 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->driver_path
, &saveptr
);
1671 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->data_file
, &saveptr
);
1672 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->config_file
, &saveptr
);
1673 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->help_file
, &saveptr
);
1674 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->monitor_name
, &saveptr
);
1675 str
= get_driver_3_param(mem_ctx
, NULL
, ":", &r
->default_datatype
, &saveptr
);
1677 /* <Comma Separated List of Dependent Files> */
1678 /* save the beginning of the string */
1679 str2
= get_driver_3_param(mem_ctx
, NULL
, ":", NULL
, &saveptr
);
1682 /* begin to strip out each filename */
1683 str
= strtok_r(str
, ",", &saveptr
);
1685 /* no dependent files, we are done */
1690 deps
= talloc_zero(mem_ctx
, struct spoolss_StringArray
);
1695 while (str
!= NULL
) {
1697 ok
= add_string_to_array(deps
, str
, &file_array
, &count
);
1701 str
= strtok_r(NULL
, ",", &saveptr
);
1704 deps
->string
= talloc_zero_array(deps
, const char *, count
+ 1);
1705 if (!deps
->string
) {
1709 for (i
=0; i
< count
; i
++) {
1710 deps
->string
[i
] = file_array
[i
];
1713 r
->dependent_files
= deps
;
1718 /****************************************************************************
1719 ****************************************************************************/
1721 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1722 TALLOC_CTX
*mem_ctx
,
1723 int argc
, const char **argv
)
1728 struct spoolss_AddDriverInfoCtr info_ctr
;
1729 struct spoolss_AddDriverInfo3 info3
;
1732 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1734 /* parse the command arguments */
1735 if (argc
!= 3 && argc
!= 4)
1737 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1738 printf ("\t<Long Driver Name>:<Driver File Name>:<Data File Name>:\\\n");
1739 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1740 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1741 printf ("\t[version]\n");
1746 /* Fill in the spoolss_AddDriverInfo3 struct */
1749 arch
= cmd_spoolss_get_short_archi(argv
[1]);
1751 printf ("Error Unknown architecture [%s]\n", argv
[1]);
1752 return WERR_INVALID_PARAM
;
1755 set_drv_info_3_env(mem_ctx
, &info3
, arch
);
1757 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1758 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1760 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1761 return WERR_INVALID_PARAM
;
1764 /* if printer driver version specified, override the default version
1765 * used by the architecture. This allows installation of Windows
1766 * 2000 (version 3) printer drivers. */
1769 info3
.version
= atoi(argv
[3]);
1773 info_ctr
.level
= level
;
1774 info_ctr
.info
.info3
= &info3
;
1776 status
= dcerpc_spoolss_AddPrinterDriver(b
, mem_ctx
,
1777 cli
->srv_name_slash
,
1780 if (!NT_STATUS_IS_OK(status
)) {
1781 return ntstatus_to_werror(status
);
1783 if (W_ERROR_IS_OK(result
)) {
1784 printf ("Printer Driver %s successfully installed.\n",
1792 /****************************************************************************
1793 ****************************************************************************/
1795 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1796 TALLOC_CTX
*mem_ctx
,
1797 int argc
, const char **argv
)
1800 struct spoolss_SetPrinterInfoCtr info_ctr
;
1801 struct spoolss_SetPrinterInfo2 info2
;
1803 /* parse the command arguments */
1806 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1810 /* Fill in the DRIVER_INFO_2 struct */
1813 info2
.printername
= argv
[1];
1814 info2
.drivername
= argv
[3];
1815 info2
.sharename
= argv
[2];
1816 info2
.portname
= argv
[4];
1817 info2
.comment
= "Created by rpcclient";
1818 info2
.printprocessor
= "winprint";
1819 info2
.datatype
= "RAW";
1820 info2
.devmode_ptr
= NULL
;
1821 info2
.secdesc_ptr
= NULL
;
1822 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1824 info2
.defaultpriority
= 0;
1825 info2
.starttime
= 0;
1826 info2
.untiltime
= 0;
1828 /* These three fields must not be used by AddPrinter()
1829 as defined in the MS Platform SDK documentation..
1833 info2.averageppm = 0;
1837 info_ctr
.info
.info2
= &info2
;
1839 result
= rpccli_spoolss_addprinterex(cli
, mem_ctx
,
1841 if (W_ERROR_IS_OK(result
))
1842 printf ("Printer %s successfully installed.\n", argv
[1]);
1847 /****************************************************************************
1848 ****************************************************************************/
1850 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1851 TALLOC_CTX
*mem_ctx
,
1852 int argc
, const char **argv
)
1854 struct policy_handle pol
;
1858 const char *printername
;
1859 union spoolss_PrinterInfo info
;
1860 struct spoolss_SetPrinterInfoCtr info_ctr
;
1861 struct spoolss_SetPrinterInfo2 info2
;
1862 struct spoolss_DevmodeContainer devmode_ctr
;
1863 struct sec_desc_buf secdesc_ctr
;
1864 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1866 ZERO_STRUCT(devmode_ctr
);
1867 ZERO_STRUCT(secdesc_ctr
);
1869 /* parse the command arguments */
1872 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1876 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
1878 /* Get a printer handle */
1880 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
1884 if (!W_ERROR_IS_OK(result
))
1887 /* Get printer info */
1889 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
1894 if (!W_ERROR_IS_OK(result
)) {
1895 printf ("Unable to retrieve printer information!\n");
1899 /* Set the printer driver */
1901 spoolss_printerinfo2_to_setprinterinfo2(&info
.info2
, &info2
);
1902 info2
.drivername
= argv
[2];
1905 info_ctr
.info
.info2
= &info2
;
1907 status
= dcerpc_spoolss_SetPrinter(b
, mem_ctx
,
1914 if (!NT_STATUS_IS_OK(status
)) {
1915 result
= ntstatus_to_werror(status
);
1918 if (!W_ERROR_IS_OK(result
)) {
1919 printf("SetPrinter call failed!\n");
1923 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1928 if (is_valid_policy_hnd(&pol
)) {
1930 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
1937 /****************************************************************************
1938 ****************************************************************************/
1940 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1941 TALLOC_CTX
*mem_ctx
,
1942 int argc
, const char **argv
)
1944 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1946 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
1951 const char *arch
= NULL
;
1952 uint32_t delete_flags
= 0;
1954 /* parse the command arguments */
1955 if (argc
< 2 || argc
> 5) {
1956 printf("Usage: %s <driver> [arch] [version] [flags]\n", argv
[0]);
1963 vers
= atoi(argv
[3]);
1964 delete_flags
|= DPD_DELETE_SPECIFIC_VERSION
;
1967 delete_flags
= atoi(argv
[4]);
1969 /* delete the driver for all architectures */
1970 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1972 if (arch
&& !strequal(archi_table
[i
].long_archi
, arch
))
1975 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1978 /* make the call to remove the driver */
1979 status
= dcerpc_spoolss_DeletePrinterDriverEx(b
, mem_ctx
,
1980 cli
->srv_name_slash
,
1981 archi_table
[i
].long_archi
,
1984 archi_table
[i
].version
,
1986 if (!NT_STATUS_IS_OK(status
)) {
1987 return ntstatus_to_werror(status
);
1989 if ( !W_ERROR_IS_OK(result
) )
1991 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1992 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1993 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, win_errstr(result
));
1998 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1999 archi_table
[i
].long_archi
, archi_table
[i
].version
);
2008 /****************************************************************************
2009 ****************************************************************************/
2011 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
2012 TALLOC_CTX
*mem_ctx
,
2013 int argc
, const char **argv
)
2015 WERROR result
= WERR_OK
;
2018 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2020 /* parse the command arguments */
2022 printf ("Usage: %s <driver>\n", argv
[0]);
2026 /* delete the driver for all architectures */
2027 for (i
=0; archi_table
[i
].long_archi
; i
++) {
2030 /* make the call to remove the driver */
2031 status
= dcerpc_spoolss_DeletePrinterDriver(b
, mem_ctx
,
2032 cli
->srv_name_slash
,
2033 archi_table
[i
].long_archi
,
2036 if (!NT_STATUS_IS_OK(status
)) {
2037 result
= ntstatus_to_werror(status
);
2040 if ( !W_ERROR_IS_OK(result
) ) {
2041 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
2042 printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
2043 argv
[1], archi_table
[i
].long_archi
,
2044 win_errstr(result
));
2047 printf ("Driver %s removed for arch [%s].\n", argv
[1],
2048 archi_table
[i
].long_archi
);
2055 /****************************************************************************
2056 ****************************************************************************/
2058 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
2059 TALLOC_CTX
*mem_ctx
,
2060 int argc
, const char **argv
)
2064 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
2067 union spoolss_PrintProcessorDirectoryInfo info
;
2069 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2071 /* parse the command arguments */
2073 printf ("Usage: %s [environment]\n", argv
[0]);
2078 environment
= argv
[1];
2081 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2082 cli
->srv_name_slash
,
2090 if (!NT_STATUS_IS_OK(status
)) {
2091 return ntstatus_to_werror(status
);
2093 if (W_ERROR_EQUAL(result
, WERR_INSUFFICIENT_BUFFER
)) {
2095 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2097 status
= dcerpc_spoolss_GetPrintProcessorDirectory(b
, mem_ctx
,
2098 cli
->srv_name_slash
,
2106 if (!NT_STATUS_IS_OK(status
)) {
2107 return ntstatus_to_werror(status
);
2111 if (W_ERROR_IS_OK(result
)) {
2112 printf("%s\n", info
.info1
.directory_name
);
2118 /****************************************************************************
2119 ****************************************************************************/
2121 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2122 int argc
, const char **argv
)
2124 struct policy_handle handle
;
2127 const char *printername
;
2128 struct spoolss_AddFormInfoCtr info_ctr
;
2129 struct spoolss_AddFormInfo1 info1
;
2130 struct spoolss_AddFormInfo2 info2
;
2132 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2134 /* Parse the command arguments */
2136 if (argc
< 3 || argc
> 5) {
2137 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2141 /* Get a printer handle */
2143 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2145 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2149 if (!W_ERROR_IS_OK(werror
))
2152 /* Dummy up some values for the form data */
2155 level
= atoi(argv
[3]);
2160 info1
.flags
= SPOOLSS_FORM_USER
;
2161 info1
.form_name
= argv
[2];
2162 info1
.size
.width
= 100;
2163 info1
.size
.height
= 100;
2164 info1
.area
.left
= 0;
2165 info1
.area
.top
= 10;
2166 info1
.area
.right
= 20;
2167 info1
.area
.bottom
= 30;
2170 info_ctr
.info
.info1
= &info1
;
2174 info2
.flags
= SPOOLSS_FORM_USER
;
2175 info2
.form_name
= argv
[2];
2176 info2
.size
.width
= 100;
2177 info2
.size
.height
= 100;
2178 info2
.area
.left
= 0;
2179 info2
.area
.top
= 10;
2180 info2
.area
.right
= 20;
2181 info2
.area
.bottom
= 30;
2182 info2
.keyword
= argv
[2];
2183 info2
.string_type
= SPOOLSS_FORM_STRING_TYPE_NONE
;
2184 info2
.mui_dll
= NULL
;
2185 info2
.ressource_id
= 0;
2186 info2
.display_name
= argv
[2];
2190 info_ctr
.info
.info2
= &info2
;
2194 werror
= WERR_INVALID_PARAM
;
2200 status
= dcerpc_spoolss_AddForm(b
, mem_ctx
,
2204 if (!NT_STATUS_IS_OK(status
)) {
2205 werror
= ntstatus_to_werror(status
);
2209 if (is_valid_policy_hnd(&handle
)) {
2211 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2217 /****************************************************************************
2218 ****************************************************************************/
2220 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2221 int argc
, const char **argv
)
2223 struct policy_handle handle
;
2226 const char *printername
;
2227 struct spoolss_AddFormInfoCtr info_ctr
;
2228 struct spoolss_AddFormInfo1 info1
;
2229 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2231 /* Parse the command arguments */
2234 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2238 /* Get a printer handle */
2240 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2242 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2244 SEC_FLAG_MAXIMUM_ALLOWED
,
2246 if (!W_ERROR_IS_OK(werror
))
2249 /* Dummy up some values for the form data */
2251 info1
.flags
= SPOOLSS_FORM_PRINTER
;
2252 info1
.size
.width
= 100;
2253 info1
.size
.height
= 100;
2254 info1
.area
.left
= 0;
2255 info1
.area
.top
= 1000;
2256 info1
.area
.right
= 2000;
2257 info1
.area
.bottom
= 3000;
2258 info1
.form_name
= argv
[2];
2260 info_ctr
.info
.info1
= &info1
;
2265 status
= dcerpc_spoolss_SetForm(b
, mem_ctx
,
2270 if (!NT_STATUS_IS_OK(status
)) {
2271 werror
= ntstatus_to_werror(status
);
2275 if (is_valid_policy_hnd(&handle
)) {
2277 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2283 /****************************************************************************
2284 ****************************************************************************/
2286 static const char *get_form_flag(int form_flag
)
2288 switch (form_flag
) {
2289 case SPOOLSS_FORM_USER
:
2291 case SPOOLSS_FORM_BUILTIN
:
2292 return "FORM_BUILTIN";
2293 case SPOOLSS_FORM_PRINTER
:
2294 return "FORM_PRINTER";
2300 /****************************************************************************
2301 ****************************************************************************/
2303 static void display_form_info1(struct spoolss_FormInfo1
*r
)
2306 "\tflag: %s (%d)\n" \
2307 "\twidth: %d, length: %d\n" \
2308 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2309 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2310 r
->size
.width
, r
->size
.height
,
2311 r
->area
.left
, r
->area
.right
,
2312 r
->area
.top
, r
->area
.bottom
);
2315 /****************************************************************************
2316 ****************************************************************************/
2318 static void display_form_info2(struct spoolss_FormInfo2
*r
)
2321 "\tflag: %s (%d)\n" \
2322 "\twidth: %d, length: %d\n" \
2323 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2324 r
->form_name
, get_form_flag(r
->flags
), r
->flags
,
2325 r
->size
.width
, r
->size
.height
,
2326 r
->area
.left
, r
->area
.right
,
2327 r
->area
.top
, r
->area
.bottom
);
2328 printf("\tkeyword: %s\n", r
->keyword
);
2329 printf("\tstring_type: 0x%08x\n", r
->string_type
);
2330 printf("\tmui_dll: %s\n", r
->mui_dll
);
2331 printf("\tressource_id: 0x%08x\n", r
->ressource_id
);
2332 printf("\tdisplay_name: %s\n", r
->display_name
);
2333 printf("\tlang_id: %d\n", r
->lang_id
);
2337 /****************************************************************************
2338 ****************************************************************************/
2340 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
2341 int argc
, const char **argv
)
2343 struct policy_handle handle
;
2346 const char *printername
;
2348 uint32_t offered
= 0;
2349 union spoolss_FormInfo info
;
2352 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2354 /* Parse the command arguments */
2356 if (argc
< 3 || argc
> 5) {
2357 printf ("Usage: %s <printer> <formname> [level]\n", argv
[0]);
2361 /* Get a printer handle */
2363 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2365 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2367 SEC_FLAG_MAXIMUM_ALLOWED
,
2369 if (!W_ERROR_IS_OK(werror
))
2373 level
= atoi(argv
[3]);
2378 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2387 if (!NT_STATUS_IS_OK(status
)) {
2388 werror
= ntstatus_to_werror(status
);
2391 if (W_ERROR_EQUAL(werror
, WERR_INSUFFICIENT_BUFFER
)) {
2392 buffer
= data_blob_talloc_zero(mem_ctx
, needed
);
2394 status
= dcerpc_spoolss_GetForm(b
, mem_ctx
,
2403 if (!NT_STATUS_IS_OK(status
)) {
2404 werror
= ntstatus_to_werror(status
);
2409 if (!W_ERROR_IS_OK(werror
)) {
2415 display_form_info1(&info
.info1
);
2418 display_form_info2(&info
.info2
);
2423 if (is_valid_policy_hnd(&handle
)) {
2425 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2431 /****************************************************************************
2432 ****************************************************************************/
2434 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
2435 TALLOC_CTX
*mem_ctx
, int argc
,
2438 struct policy_handle handle
;
2441 const char *printername
;
2442 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2444 /* Parse the command arguments */
2447 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
2451 /* Get a printer handle */
2453 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2455 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2457 SEC_FLAG_MAXIMUM_ALLOWED
,
2459 if (!W_ERROR_IS_OK(werror
))
2462 /* Delete the form */
2464 status
= dcerpc_spoolss_DeleteForm(b
, mem_ctx
,
2468 if (!NT_STATUS_IS_OK(status
)) {
2469 werror
= ntstatus_to_werror(status
);
2474 if (is_valid_policy_hnd(&handle
)) {
2476 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2482 /****************************************************************************
2483 ****************************************************************************/
2485 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
2486 TALLOC_CTX
*mem_ctx
, int argc
,
2489 struct policy_handle handle
;
2491 const char *printername
;
2492 uint32_t num_forms
, level
= 1, i
;
2493 union spoolss_FormInfo
*forms
;
2494 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2496 /* Parse the command arguments */
2498 if (argc
< 2 || argc
> 4) {
2499 printf ("Usage: %s <printer> [level]\n", argv
[0]);
2503 /* Get a printer handle */
2505 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2507 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2509 SEC_FLAG_MAXIMUM_ALLOWED
,
2511 if (!W_ERROR_IS_OK(werror
))
2515 level
= atoi(argv
[2]);
2518 /* Enumerate forms */
2520 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
,
2527 if (!W_ERROR_IS_OK(werror
))
2530 /* Display output */
2532 for (i
= 0; i
< num_forms
; i
++) {
2535 display_form_info1(&forms
[i
].info1
);
2538 display_form_info2(&forms
[i
].info2
);
2544 if (is_valid_policy_hnd(&handle
)) {
2546 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
2552 /****************************************************************************
2553 ****************************************************************************/
2555 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
2556 TALLOC_CTX
*mem_ctx
,
2557 int argc
, const char **argv
)
2561 const char *printername
;
2562 struct policy_handle pol
= { 0, };
2563 union spoolss_PrinterInfo info
;
2564 enum winreg_Type type
;
2565 union spoolss_PrinterData data
;
2567 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2569 /* parse the command arguments */
2571 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2572 " <value> <data>\n",
2577 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2581 if (strequal(argv
[2], "string")) {
2585 if (strequal(argv
[2], "binary")) {
2589 if (strequal(argv
[2], "dword")) {
2593 if (strequal(argv
[2], "multistring")) {
2594 type
= REG_MULTI_SZ
;
2597 if (type
== REG_NONE
) {
2598 printf("Unknown data type: %s\n", argv
[2]);
2599 result
= WERR_INVALID_PARAM
;
2603 /* get a printer handle */
2605 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2607 SEC_FLAG_MAXIMUM_ALLOWED
,
2609 if (!W_ERROR_IS_OK(result
)) {
2613 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2618 if (!W_ERROR_IS_OK(result
)) {
2622 printf("%s\n", current_timestring(mem_ctx
, true));
2623 printf("\tchange_id (before set)\t:[0x%x]\n", info
.info0
.change_id
);
2625 /* Set the printer data */
2629 data
.string
= talloc_strdup(mem_ctx
, argv
[4]);
2630 W_ERROR_HAVE_NO_MEMORY(data
.string
);
2633 data
.value
= strtoul(argv
[4], NULL
, 10);
2636 data
.binary
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2638 case REG_MULTI_SZ
: {
2640 const char **strings
= NULL
;
2644 for (i
=4; i
<argc
; i
++) {
2645 if (strcmp(argv
[i
], "NULL") == 0) {
2648 if (!add_string_to_array(mem_ctx
, argv
[i
],
2651 result
= WERR_NOMEM
;
2655 data
.string_array
= talloc_zero_array(mem_ctx
, const char *, num_strings
+ 1);
2656 if (!data
.string_array
) {
2657 result
= WERR_NOMEM
;
2660 for (i
=0; i
< num_strings
; i
++) {
2661 data
.string_array
[i
] = strings
[i
];
2666 printf("Unknown data type: %s\n", argv
[2]);
2667 result
= WERR_INVALID_PARAM
;
2671 result
= push_spoolss_PrinterData(mem_ctx
, &blob
, type
, &data
);
2672 if (!W_ERROR_IS_OK(result
)) {
2676 status
= dcerpc_spoolss_SetPrinterData(b
, mem_ctx
,
2678 argv
[3], /* value_name */
2683 if (!NT_STATUS_IS_OK(status
)) {
2684 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2685 result
= ntstatus_to_werror(status
);
2688 if (!W_ERROR_IS_OK(result
)) {
2689 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2692 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2694 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
,
2699 if (!W_ERROR_IS_OK(result
)) {
2703 printf("%s\n", current_timestring(mem_ctx
, true));
2704 printf("\tchange_id (after set)\t:[0x%x]\n", info
.info0
.change_id
);
2708 if (is_valid_policy_hnd(&pol
)) {
2710 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &pol
, &_result
);
2716 /****************************************************************************
2717 ****************************************************************************/
2719 static void display_job_info1(struct spoolss_JobInfo1
*r
)
2721 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r
->position
, r
->job_id
,
2722 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2726 /****************************************************************************
2727 ****************************************************************************/
2729 static void display_job_info2(struct spoolss_JobInfo2
*r
)
2731 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2732 r
->position
, r
->job_id
,
2733 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2734 r
->total_pages
, r
->size
);
2737 /****************************************************************************
2738 ****************************************************************************/
2740 static void display_job_info3(struct spoolss_JobInfo3
*r
)
2742 printf("jobid[%d], next_jobid[%d]\n",
2743 r
->job_id
, r
->next_job_id
);
2746 /****************************************************************************
2747 ****************************************************************************/
2749 static void display_job_info4(struct spoolss_JobInfo4
*r
)
2751 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2752 r
->position
, r
->job_id
,
2753 r
->user_name
, r
->document_name
, r
->text_status
, r
->pages_printed
,
2754 r
->total_pages
, r
->size
, r
->size_high
);
2757 /****************************************************************************
2758 ****************************************************************************/
2760 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2761 TALLOC_CTX
*mem_ctx
, int argc
,
2765 uint32_t level
= 1, count
, i
;
2766 const char *printername
;
2767 struct policy_handle hnd
;
2768 union spoolss_JobInfo
*info
;
2769 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2771 if (argc
< 2 || argc
> 3) {
2772 printf("Usage: %s printername [level]\n", argv
[0]);
2777 level
= atoi(argv
[2]);
2780 /* Open printer handle */
2782 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2784 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2786 SEC_FLAG_MAXIMUM_ALLOWED
,
2788 if (!W_ERROR_IS_OK(result
))
2791 /* Enumerate ports */
2793 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
,
2801 if (!W_ERROR_IS_OK(result
)) {
2805 for (i
= 0; i
< count
; i
++) {
2808 display_job_info1(&info
[i
].info1
);
2811 display_job_info2(&info
[i
].info2
);
2814 d_printf("unknown info level %d\n", level
);
2820 if (is_valid_policy_hnd(&hnd
)) {
2822 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2828 /****************************************************************************
2829 ****************************************************************************/
2831 static WERROR
cmd_spoolss_get_job(struct rpc_pipe_client
*cli
,
2832 TALLOC_CTX
*mem_ctx
, int argc
,
2836 const char *printername
;
2837 struct policy_handle hnd
;
2840 union spoolss_JobInfo info
;
2841 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2843 if (argc
< 3 || argc
> 4) {
2844 printf("Usage: %s printername job_id [level]\n", argv
[0]);
2848 job_id
= atoi(argv
[2]);
2851 level
= atoi(argv
[3]);
2854 /* Open printer handle */
2856 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2858 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2860 SEC_FLAG_MAXIMUM_ALLOWED
,
2862 if (!W_ERROR_IS_OK(result
)) {
2866 /* Enumerate ports */
2868 result
= rpccli_spoolss_getjob(cli
, mem_ctx
,
2875 if (!W_ERROR_IS_OK(result
)) {
2881 display_job_info1(&info
.info1
);
2884 display_job_info2(&info
.info2
);
2887 display_job_info3(&info
.info3
);
2890 display_job_info4(&info
.info4
);
2893 d_printf("unknown info level %d\n", level
);
2898 if (is_valid_policy_hnd(&hnd
)) {
2900 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2906 /****************************************************************************
2907 ****************************************************************************/
2911 enum spoolss_JobControl val
;
2913 {"PAUSE", SPOOLSS_JOB_CONTROL_PAUSE
},
2914 {"RESUME", SPOOLSS_JOB_CONTROL_RESUME
},
2915 {"CANCEL", SPOOLSS_JOB_CONTROL_CANCEL
},
2916 {"RESTART", SPOOLSS_JOB_CONTROL_RESTART
},
2917 {"DELETE", SPOOLSS_JOB_CONTROL_DELETE
},
2918 {"SEND_TO_PRINTER", SPOOLSS_JOB_CONTROL_SEND_TO_PRINTER
},
2919 {"EJECTED", SPOOLSS_JOB_CONTROL_LAST_PAGE_EJECTED
},
2920 {"RETAIN", SPOOLSS_JOB_CONTROL_RETAIN
},
2921 {"RELEASE", SPOOLSS_JOB_CONTROL_RELEASE
}
2924 static enum spoolss_JobControl
parse_setjob_command(const char *cmd
)
2928 for (i
= 0; i
< sizeof(cmdvals
)/sizeof(cmdvals
[0]); i
++) {
2929 if (strequal(cmdvals
[i
].name
, cmd
)) {
2930 return cmdvals
[i
].val
;
2933 return (enum spoolss_JobControl
)atoi(cmd
);
2936 static WERROR
cmd_spoolss_set_job(struct rpc_pipe_client
*cli
,
2937 TALLOC_CTX
*mem_ctx
, int argc
,
2942 const char *printername
;
2943 struct policy_handle hnd
;
2945 enum spoolss_JobControl command
;
2946 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
2949 printf("Usage: %s printername job_id command\n", argv
[0]);
2950 printf("command = [PAUSE|RESUME|CANCEL|RESTART|DELETE|"
2951 "SEND_TO_PRINTER|EJECTED|RETAIN|RELEASE]\n");
2955 job_id
= atoi(argv
[2]);
2956 command
= parse_setjob_command(argv
[3]);
2958 /* Open printer handle */
2960 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
2962 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
2964 SEC_FLAG_MAXIMUM_ALLOWED
,
2966 if (!W_ERROR_IS_OK(result
)) {
2972 status
= dcerpc_spoolss_SetJob(b
, mem_ctx
,
2978 if (!NT_STATUS_IS_OK(status
)) {
2979 result
= ntstatus_to_werror(status
);
2982 if (!W_ERROR_IS_OK(result
)) {
2987 if (is_valid_policy_hnd(&hnd
)) {
2989 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
2995 /****************************************************************************
2996 ****************************************************************************/
2998 static WERROR
cmd_spoolss_enum_data(struct rpc_pipe_client
*cli
,
2999 TALLOC_CTX
*mem_ctx
, int argc
,
3004 const char *printername
;
3005 struct policy_handle hnd
;
3006 uint32_t value_needed
;
3007 enum winreg_Type type
;
3008 uint32_t data_needed
;
3009 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3010 struct spoolss_EnumPrinterData r
;
3013 printf("Usage: %s printername\n", argv
[0]);
3017 /* Open printer handle */
3019 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3021 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3023 SEC_FLAG_MAXIMUM_ALLOWED
,
3025 if (!W_ERROR_IS_OK(result
)) {
3029 /* Enumerate data */
3032 r
.in
.enum_index
= 0;
3033 r
.in
.value_offered
= 0;
3034 r
.in
.data_offered
= 0;
3035 r
.out
.value_name
= NULL
;
3036 r
.out
.value_needed
= &value_needed
;
3039 r
.out
.data_needed
= &data_needed
;
3041 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3042 if (!NT_STATUS_IS_OK(status
)) {
3043 result
= ntstatus_to_werror(status
);
3047 if (!W_ERROR_IS_OK(r
.out
.result
)) {
3048 result
= r
.out
.result
;
3052 r
.in
.data_offered
= *r
.out
.data_needed
;
3053 r
.in
.value_offered
= *r
.out
.value_needed
;
3054 r
.out
.data
= talloc_zero_array(mem_ctx
, uint8_t, r
.in
.data_offered
);
3055 r
.out
.value_name
= talloc_zero_array(mem_ctx
, char, r
.in
.value_offered
);
3059 status
= dcerpc_spoolss_EnumPrinterData_r(b
, mem_ctx
, &r
);
3060 if (!NT_STATUS_IS_OK(status
)) {
3061 result
= ntstatus_to_werror(status
);
3065 if (W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
3072 display_reg_value(r
.out
.value_name
, *r
.out
.type
,
3073 data_blob_const(r
.out
.data
, r
.in
.data_offered
));
3075 } while (W_ERROR_IS_OK(r
.out
.result
));
3078 if (is_valid_policy_hnd(&hnd
)) {
3080 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3086 /****************************************************************************
3087 ****************************************************************************/
3089 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
3090 TALLOC_CTX
*mem_ctx
, int argc
,
3095 const char *printername
;
3096 struct policy_handle hnd
;
3098 struct spoolss_PrinterEnumValues
*info
;
3099 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3102 printf("Usage: %s printername <keyname>\n", argv
[0]);
3106 /* Open printer handle */
3108 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3110 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3112 SEC_FLAG_MAXIMUM_ALLOWED
,
3114 if (!W_ERROR_IS_OK(result
)) {
3118 /* Enumerate subkeys */
3120 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
,
3126 if (!W_ERROR_IS_OK(result
)) {
3130 for (i
=0; i
< count
; i
++) {
3131 display_printer_data(info
[i
].value_name
,
3134 info
[i
].data
->length
);
3138 if (is_valid_policy_hnd(&hnd
)) {
3140 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3146 /****************************************************************************
3147 ****************************************************************************/
3149 static WERROR
cmd_spoolss_enum_printerkey(struct rpc_pipe_client
*cli
,
3150 TALLOC_CTX
*mem_ctx
, int argc
,
3154 const char *printername
;
3155 const char *keyname
= NULL
;
3156 struct policy_handle hnd
;
3157 const char **key_buffer
= NULL
;
3159 uint32_t offered
= 0;
3160 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3162 if (argc
< 2 || argc
> 4) {
3163 printf("Usage: %s printername [keyname] [offered]\n", argv
[0]);
3174 offered
= atoi(argv
[3]);
3177 /* Open printer handle */
3179 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3181 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3183 SEC_FLAG_MAXIMUM_ALLOWED
,
3185 if (!W_ERROR_IS_OK(result
)) {
3189 /* Enumerate subkeys */
3191 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
,
3197 if (!W_ERROR_IS_OK(result
)) {
3201 for (i
=0; key_buffer
&& key_buffer
[i
]; i
++) {
3202 printf("%s\n", key_buffer
[i
]);
3207 if (is_valid_policy_hnd(&hnd
)) {
3209 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3215 /****************************************************************************
3216 ****************************************************************************/
3218 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
3219 TALLOC_CTX
*mem_ctx
, int argc
,
3222 const char *printername
;
3223 const char *clientname
;
3224 struct policy_handle hnd
= { 0, };
3227 struct spoolss_NotifyOption option
;
3228 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3231 printf("Usage: %s printername\n", argv
[0]);
3238 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3240 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3242 SEC_FLAG_MAXIMUM_ALLOWED
,
3244 if (!W_ERROR_IS_OK(result
)) {
3245 printf("Error opening %s\n", argv
[1]);
3249 /* Create spool options */
3254 option
.types
= talloc_array(mem_ctx
, struct spoolss_NotifyOptionType
, 2);
3255 if (option
.types
== NULL
) {
3256 result
= WERR_NOMEM
;
3260 option
.types
[0].type
= PRINTER_NOTIFY_TYPE
;
3261 option
.types
[0].count
= 1;
3262 option
.types
[0].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3263 if (option
.types
[0].fields
== NULL
) {
3264 result
= WERR_NOMEM
;
3267 option
.types
[0].fields
[0].field
= PRINTER_NOTIFY_FIELD_SERVER_NAME
;
3269 option
.types
[1].type
= JOB_NOTIFY_TYPE
;
3270 option
.types
[1].count
= 1;
3271 option
.types
[1].fields
= talloc_array(mem_ctx
, union spoolss_Field
, 1);
3272 if (option
.types
[1].fields
== NULL
) {
3273 result
= WERR_NOMEM
;
3276 option
.types
[1].fields
[0].field
= JOB_NOTIFY_FIELD_PRINTER_NAME
;
3278 clientname
= talloc_asprintf(mem_ctx
, "\\\\%s", lp_netbios_name());
3280 result
= WERR_NOMEM
;
3286 status
= dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(b
, mem_ctx
,
3294 if (!NT_STATUS_IS_OK(status
)) {
3295 result
= ntstatus_to_werror(status
);
3298 if (!W_ERROR_IS_OK(result
)) {
3299 printf("Error rffpcnex %s\n", argv
[1]);
3304 if (is_valid_policy_hnd(&hnd
)) {
3306 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &hnd
, &_result
);
3312 /****************************************************************************
3313 ****************************************************************************/
3315 static bool compare_printer( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3316 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3318 union spoolss_PrinterInfo info1
, info2
;
3320 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
3322 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
3323 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3328 if ( !W_ERROR_IS_OK(werror
) ) {
3329 printf("failed (%s)\n", win_errstr(werror
));
3330 talloc_destroy(mem_ctx
);
3335 printf("Retrieving printer properties for %s...", cli2
->desthost
);
3336 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3341 if ( !W_ERROR_IS_OK(werror
) ) {
3342 printf("failed (%s)\n", win_errstr(werror
));
3343 talloc_destroy(mem_ctx
);
3348 talloc_destroy(mem_ctx
);
3353 /****************************************************************************
3354 ****************************************************************************/
3356 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, struct policy_handle
*hnd1
,
3357 struct rpc_pipe_client
*cli2
, struct policy_handle
*hnd2
)
3359 union spoolss_PrinterInfo info1
, info2
;
3361 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
3362 struct security_descriptor
*sd1
, *sd2
;
3366 printf("Retrieving printer security for %s...", cli1
->desthost
);
3367 werror
= rpccli_spoolss_getprinter(cli1
, mem_ctx
,
3372 if ( !W_ERROR_IS_OK(werror
) ) {
3373 printf("failed (%s)\n", win_errstr(werror
));
3379 printf("Retrieving printer security for %s...", cli2
->desthost
);
3380 werror
= rpccli_spoolss_getprinter(cli2
, mem_ctx
,
3385 if ( !W_ERROR_IS_OK(werror
) ) {
3386 printf("failed (%s)\n", win_errstr(werror
));
3395 sd1
= info1
.info3
.secdesc
;
3396 sd2
= info2
.info3
.secdesc
;
3398 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
3399 printf("NULL secdesc!\n");
3404 if (!security_descriptor_equal( sd1
, sd2
) ) {
3405 printf("Security Descriptors *not* equal!\n");
3410 printf("Security descriptors match\n");
3413 talloc_destroy(mem_ctx
);
3418 /****************************************************************************
3419 ****************************************************************************/
3421 extern struct user_auth_info
*rpcclient_auth_info
;
3423 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
3424 TALLOC_CTX
*mem_ctx
, int argc
,
3427 const char *printername
;
3428 char *printername_path
= NULL
;
3429 struct cli_state
*cli_server2
= NULL
;
3430 struct rpc_pipe_client
*cli2
= NULL
;
3431 struct policy_handle hPrinter1
, hPrinter2
;
3436 printf("Usage: %s <printer> <server>\n", argv
[0]);
3440 printername
= argv
[1];
3442 /* first get the connection to the remote server */
3444 nt_status
= cli_full_connection(&cli_server2
, lp_netbios_name(), argv
[2],
3447 get_cmdline_auth_info_username(rpcclient_auth_info
),
3449 get_cmdline_auth_info_password(rpcclient_auth_info
),
3450 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info
) ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
3451 get_cmdline_auth_info_signing_state(rpcclient_auth_info
));
3453 if ( !NT_STATUS_IS_OK(nt_status
) )
3454 return WERR_GENERAL_FAILURE
;
3456 nt_status
= cli_rpc_pipe_open_noauth(cli_server2
, &ndr_table_spoolss
,
3458 if (!NT_STATUS_IS_OK(nt_status
)) {
3459 printf("failed to open spoolss pipe on server %s (%s)\n",
3460 argv
[2], nt_errstr(nt_status
));
3461 return WERR_GENERAL_FAILURE
;
3464 /* now open up both printers */
3466 RPCCLIENT_PRINTERNAME(printername_path
, cli
, printername
);
3468 printf("Opening %s...", printername_path
);
3470 werror
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3474 if ( !W_ERROR_IS_OK(werror
) ) {
3475 printf("failed (%s)\n", win_errstr(werror
));
3480 RPCCLIENT_PRINTERNAME(printername_path
, cli2
, printername
);
3482 printf("Opening %s...", printername_path
);
3483 werror
= rpccli_spoolss_openprinter_ex(cli2
, mem_ctx
,
3487 if ( !W_ERROR_IS_OK(werror
) ) {
3488 printf("failed (%s)\n", win_errstr(werror
));
3493 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3494 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
3496 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
3503 printf("Closing printers...");
3506 dcerpc_spoolss_ClosePrinter(cli
->binding_handle
, mem_ctx
, &hPrinter1
, &_result
);
3507 dcerpc_spoolss_ClosePrinter(cli2
->binding_handle
, mem_ctx
, &hPrinter2
, &_result
);
3511 /* close the second remote connection */
3513 cli_shutdown( cli_server2
);
3517 static void display_proc_info1(struct spoolss_PrintProcessorInfo1
*r
)
3519 printf("print_processor_name: %s\n", r
->print_processor_name
);
3522 static WERROR
cmd_spoolss_enum_procs(struct rpc_pipe_client
*cli
,
3523 TALLOC_CTX
*mem_ctx
, int argc
,
3527 const char *environment
= SPOOLSS_ARCHITECTURE_NT_X86
;
3528 uint32_t num_procs
, level
= 1, i
;
3529 union spoolss_PrintProcessorInfo
*procs
;
3531 /* Parse the command arguments */
3533 if (argc
< 1 || argc
> 4) {
3534 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3539 environment
= argv
[1];
3543 level
= atoi(argv
[2]);
3546 /* Enumerate Print Processors */
3548 werror
= rpccli_spoolss_enumprintprocessors(cli
, mem_ctx
,
3549 cli
->srv_name_slash
,
3555 if (!W_ERROR_IS_OK(werror
))
3558 /* Display output */
3560 for (i
= 0; i
< num_procs
; i
++) {
3563 display_proc_info1(&procs
[i
].info1
);
3572 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1
*r
)
3574 printf("name_array: %s\n", r
->name_array
);
3577 static WERROR
cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client
*cli
,
3578 TALLOC_CTX
*mem_ctx
, int argc
,
3582 const char *print_processor_name
= "winprint";
3583 uint32_t num_procs
, level
= 1, i
;
3584 union spoolss_PrintProcDataTypesInfo
*procs
;
3586 /* Parse the command arguments */
3588 if (argc
< 1 || argc
> 4) {
3589 printf ("Usage: %s [environment] [level]\n", argv
[0]);
3594 print_processor_name
= argv
[1];
3598 level
= atoi(argv
[2]);
3601 /* Enumerate Print Processor Data Types */
3603 werror
= rpccli_spoolss_enumprintprocessordatatypes(cli
, mem_ctx
,
3604 cli
->srv_name_slash
,
3605 print_processor_name
,
3610 if (!W_ERROR_IS_OK(werror
))
3613 /* Display output */
3615 for (i
= 0; i
< num_procs
; i
++) {
3618 display_proc_data_types_info1(&procs
[i
].info1
);
3627 static void display_monitor1(const struct spoolss_MonitorInfo1
*r
)
3629 printf("monitor_name: %s\n", r
->monitor_name
);
3632 static void display_monitor2(const struct spoolss_MonitorInfo2
*r
)
3634 printf("monitor_name: %s\n", r
->monitor_name
);
3635 printf("environment: %s\n", r
->environment
);
3636 printf("dll_name: %s\n", r
->dll_name
);
3639 static WERROR
cmd_spoolss_enum_monitors(struct rpc_pipe_client
*cli
,
3640 TALLOC_CTX
*mem_ctx
, int argc
,
3644 uint32_t count
, level
= 1, i
;
3645 union spoolss_MonitorInfo
*info
;
3647 /* Parse the command arguments */
3650 printf("Usage: %s [level]\n", argv
[0]);
3655 level
= atoi(argv
[1]);
3658 /* Enumerate Print Monitors */
3660 werror
= rpccli_spoolss_enummonitors(cli
, mem_ctx
,
3661 cli
->srv_name_slash
,
3666 if (!W_ERROR_IS_OK(werror
)) {
3670 /* Display output */
3672 for (i
= 0; i
< count
; i
++) {
3675 display_monitor1(&info
[i
].info1
);
3678 display_monitor2(&info
[i
].info2
);
3687 static WERROR
cmd_spoolss_create_printer_ic(struct rpc_pipe_client
*cli
,
3688 TALLOC_CTX
*mem_ctx
, int argc
,
3693 struct policy_handle handle
, gdi_handle
;
3694 const char *printername
;
3695 struct spoolss_DevmodeContainer devmode_ctr
;
3696 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3698 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3700 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3702 SEC_FLAG_MAXIMUM_ALLOWED
,
3704 if (!W_ERROR_IS_OK(result
)) {
3708 ZERO_STRUCT(devmode_ctr
);
3710 status
= dcerpc_spoolss_CreatePrinterIC(b
, mem_ctx
,
3715 if (!NT_STATUS_IS_OK(status
)) {
3716 result
= ntstatus_to_werror(status
);
3719 if (!W_ERROR_IS_OK(result
)) {
3724 if (is_valid_policy_hnd(&gdi_handle
)) {
3726 dcerpc_spoolss_DeletePrinterIC(b
, mem_ctx
, &gdi_handle
, &_result
);
3728 if (is_valid_policy_hnd(&handle
)) {
3730 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
3736 static WERROR
cmd_spoolss_play_gdi_script_on_printer_ic(struct rpc_pipe_client
*cli
,
3737 TALLOC_CTX
*mem_ctx
, int argc
,
3742 struct policy_handle handle
, gdi_handle
;
3743 const char *printername
;
3744 struct spoolss_DevmodeContainer devmode_ctr
;
3745 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
3749 RPCCLIENT_PRINTERNAME(printername
, cli
, argv
[1]);
3751 result
= rpccli_spoolss_openprinter_ex(cli
, mem_ctx
,
3753 SEC_FLAG_MAXIMUM_ALLOWED
,
3755 if (!W_ERROR_IS_OK(result
)) {
3759 ZERO_STRUCT(devmode_ctr
);
3761 status
= dcerpc_spoolss_CreatePrinterIC(b
, mem_ctx
,
3766 if (!NT_STATUS_IS_OK(status
)) {
3767 result
= ntstatus_to_werror(status
);
3770 if (!W_ERROR_IS_OK(result
)) {
3774 in
= data_blob_string_const("");
3775 out
= data_blob_talloc_zero(mem_ctx
, 4);
3777 status
= dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b
, mem_ctx
,
3785 if (!NT_STATUS_IS_OK(status
)) {
3786 result
= ntstatus_to_werror(status
);
3789 if (!W_ERROR_IS_OK(result
)) {
3793 count
= IVAL(out
.data
, 0);
3795 out
= data_blob_talloc_zero(mem_ctx
,
3796 count
* sizeof(struct UNIVERSAL_FONT_ID
) + 4);
3798 status
= dcerpc_spoolss_PlayGDIScriptOnPrinterIC(b
, mem_ctx
,
3806 if (!NT_STATUS_IS_OK(status
)) {
3807 result
= ntstatus_to_werror(status
);
3810 if (!W_ERROR_IS_OK(result
)) {
3815 enum ndr_err_code ndr_err
;
3816 struct UNIVERSAL_FONT_ID_ctr r
;
3818 ndr_err
= ndr_pull_struct_blob(&out
, mem_ctx
, &r
,
3819 (ndr_pull_flags_fn_t
)ndr_pull_UNIVERSAL_FONT_ID_ctr
);
3820 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
3821 NDR_PRINT_DEBUG(UNIVERSAL_FONT_ID_ctr
, &r
);
3826 if (is_valid_policy_hnd(&gdi_handle
)) {
3828 dcerpc_spoolss_DeletePrinterIC(b
, mem_ctx
, &gdi_handle
, &_result
);
3830 if (is_valid_policy_hnd(&handle
)) {
3832 dcerpc_spoolss_ClosePrinter(b
, mem_ctx
, &handle
, &_result
);
3838 /* List of commands exported by this module */
3839 struct cmd_set spoolss_commands
[] = {
3843 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, &ndr_table_spoolss
, NULL
, "Add a print driver", "" },
3844 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, &ndr_table_spoolss
, NULL
, "Add a printer", "" },
3845 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, &ndr_table_spoolss
, NULL
, "Delete a printer driver", "" },
3846 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, &ndr_table_spoolss
, NULL
, "Delete a printer driver with files", "" },
3847 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, &ndr_table_spoolss
, NULL
, "Enumerate printer data", "" },
3848 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, &ndr_table_spoolss
, NULL
, "Enumerate printer data for a key", "" },
3849 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, &ndr_table_spoolss
, NULL
, "Enumerate printer keys", "" },
3850 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, &ndr_table_spoolss
, NULL
, "Enumerate print jobs", "" },
3851 { "getjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_get_job
, &ndr_table_spoolss
, NULL
, "Get print job", "" },
3852 { "setjob", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_set_job
, &ndr_table_spoolss
, NULL
, "Set print job", "" },
3853 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, &ndr_table_spoolss
, NULL
, "Enumerate printer ports", "" },
3854 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, &ndr_table_spoolss
, NULL
, "Enumerate installed printer drivers", "" },
3855 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, &ndr_table_spoolss
, NULL
, "Enumerate printers", "" },
3856 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, &ndr_table_spoolss
, NULL
, "Get print driver data", "" },
3857 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, &ndr_table_spoolss
, NULL
, "Get printer driver data with keyname", ""},
3858 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, &ndr_table_spoolss
, NULL
, "Get print driver information", "" },
3859 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, &ndr_table_spoolss
, NULL
, "Get print driver upload directory", "" },
3860 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, &ndr_table_spoolss
, NULL
, "Get printer info", "" },
3861 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer
, &ndr_table_spoolss
, NULL
, "Open printer handle", "" },
3862 { "openprinter_ex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, &ndr_table_spoolss
, NULL
, "Open printer handle", "" },
3863 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, &ndr_table_spoolss
, NULL
, "Set printer driver", "" },
3864 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, &ndr_table_spoolss
, NULL
, "Get print processor directory", "" },
3865 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, &ndr_table_spoolss
, NULL
, "Add form", "" },
3866 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, &ndr_table_spoolss
, NULL
, "Set form", "" },
3867 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, &ndr_table_spoolss
, NULL
, "Get form", "" },
3868 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, &ndr_table_spoolss
, NULL
, "Delete form", "" },
3869 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, &ndr_table_spoolss
, NULL
, "Enumerate forms", "" },
3870 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, &ndr_table_spoolss
, NULL
, "Set printer comment", "" },
3871 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, &ndr_table_spoolss
, NULL
, "Set printername", "" },
3872 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, &ndr_table_spoolss
, NULL
, "Set REG_SZ printer data", "" },
3873 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, &ndr_table_spoolss
, NULL
, "Rffpcnex test", "" },
3874 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, &ndr_table_spoolss
, NULL
, "Printer comparison test", "" },
3875 { "enumprocs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_procs
, &ndr_table_spoolss
, NULL
, "Enumerate Print Processors", "" },
3876 { "enumprocdatatypes", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_proc_data_types
, &ndr_table_spoolss
, NULL
, "Enumerate Print Processor Data Types", "" },
3877 { "enummonitors", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_monitors
, &ndr_table_spoolss
, NULL
, "Enumerate Print Monitors", "" },
3878 { "createprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_create_printer_ic
, &ndr_table_spoolss
, NULL
, "Create Printer IC", "" },
3879 { "playgdiscriptonprinteric", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_play_gdi_script_on_printer_ic
, &ndr_table_spoolss
, NULL
, "Create Printer IC", "" },