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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpcclient.h"
28 const char *long_archi
;
29 const char *short_archi
;
33 /* The version int is used by getdrivers. Note that
34 all architecture strings that support mutliple
35 versions must be grouped together since enumdrivers
36 uses this property to prevent issuing multiple
37 enumdriver calls for the same arch */
40 static const struct table_node archi_table
[]= {
42 {"Windows 4.0", "WIN40", 0 },
43 {"Windows NT x86", "W32X86", 2 },
44 {"Windows NT x86", "W32X86", 3 },
45 {"Windows NT R4000", "W32MIPS", 2 },
46 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
47 {"Windows NT PowerPC", "W32PPC", 2 },
48 {"Windows IA64", "IA64", 3 },
49 {"Windows x64", "x64", 3 },
56 * rpcclient module for SPOOLSS rpc pipe.
58 * This generally just parses and checks command lines, and then calls
59 * a cli_spoolss function.
62 /****************************************************************************
63 function to do the mapping between the long architecture name and
65 ****************************************************************************/
67 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
71 DEBUG(107,("Getting architecture dependant directory\n"));
74 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
75 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
77 if (archi_table
[i
].long_archi
==NULL
) {
78 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
82 /* this might be client code - but shouldn't this be an fstrcpy etc? */
85 DEBUGADD(108,("index: [%d]\n", i
));
86 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
87 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
89 return archi_table
[i
].short_archi
;
92 /****************************************************************************
93 ****************************************************************************/
95 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
97 int argc
, const char **argv
)
101 fstring servername
, user
;
105 printf("Usage: %s <printername>\n", argv
[0]);
110 return WERR_GENERAL_FAILURE
;
112 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
113 strupper_m(servername
);
114 fstrcpy(user
, cli
->user_name
);
115 fstrcpy(printername
, argv
[1]);
117 /* Open the printer handle */
119 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
120 "", PRINTER_ALL_ACCESS
,
121 servername
, user
, &hnd
);
123 if (W_ERROR_IS_OK(werror
)) {
124 printf("Printer %s opened successfully\n", printername
);
125 werror
= rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
127 if (!W_ERROR_IS_OK(werror
)) {
128 printf("Error closing printer handle! (%s)\n",
129 get_dos_error_msg(werror
));
137 /****************************************************************************
138 ****************************************************************************/
140 static void display_print_info_0(PRINTER_INFO_0
*i0
)
143 fstring servername
= "";
148 rpcstr_pull(name
, i0
->printername
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
150 rpcstr_pull(servername
, i0
->servername
.buffer
, sizeof(servername
), -1,STR_TERMINATE
);
152 printf("\tprintername:[%s]\n", name
);
153 printf("\tservername:[%s]\n", servername
);
154 printf("\tcjobs:[0x%x]\n", i0
->cjobs
);
155 printf("\ttotal_jobs:[0x%x]\n", i0
->total_jobs
);
157 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0
->year
, i0
->month
,
158 i0
->day
, i0
->dayofweek
);
159 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0
->hour
, i0
->minute
,
160 i0
->second
, i0
->milliseconds
);
162 printf("\tglobal_counter:[0x%x]\n", i0
->global_counter
);
163 printf("\ttotal_pages:[0x%x]\n", i0
->total_pages
);
165 printf("\tmajorversion:[0x%x]\n", i0
->major_version
);
166 printf("\tbuildversion:[0x%x]\n", i0
->build_version
);
168 printf("\tunknown7:[0x%x]\n", i0
->unknown7
);
169 printf("\tunknown8:[0x%x]\n", i0
->unknown8
);
170 printf("\tunknown9:[0x%x]\n", i0
->unknown9
);
171 printf("\tsession_counter:[0x%x]\n", i0
->session_counter
);
172 printf("\tunknown11:[0x%x]\n", i0
->unknown11
);
173 printf("\tprinter_errors:[0x%x]\n", i0
->printer_errors
);
174 printf("\tunknown13:[0x%x]\n", i0
->unknown13
);
175 printf("\tunknown14:[0x%x]\n", i0
->unknown14
);
176 printf("\tunknown15:[0x%x]\n", i0
->unknown15
);
177 printf("\tunknown16:[0x%x]\n", i0
->unknown16
);
178 printf("\tchange_id:[0x%x]\n", i0
->change_id
);
179 printf("\tunknown18:[0x%x]\n", i0
->unknown18
);
180 printf("\tstatus:[0x%x]\n", i0
->status
);
181 printf("\tunknown20:[0x%x]\n", i0
->unknown20
);
182 printf("\tc_setprinter:[0x%x]\n", i0
->c_setprinter
);
183 printf("\tunknown22:[0x%x]\n", i0
->unknown22
);
184 printf("\tunknown23:[0x%x]\n", i0
->unknown23
);
185 printf("\tunknown24:[0x%x]\n", i0
->unknown24
);
186 printf("\tunknown25:[0x%x]\n", i0
->unknown25
);
187 printf("\tunknown26:[0x%x]\n", i0
->unknown26
);
188 printf("\tunknown27:[0x%x]\n", i0
->unknown27
);
189 printf("\tunknown28:[0x%x]\n", i0
->unknown28
);
190 printf("\tunknown29:[0x%x]\n", i0
->unknown29
);
195 /****************************************************************************
196 ****************************************************************************/
198 static void display_print_info_1(PRINTER_INFO_1
*i1
)
204 rpcstr_pull(desc
, i1
->description
.buffer
, sizeof(desc
), -1,
207 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
208 rpcstr_pull(comm
, i1
->comment
.buffer
, sizeof(comm
), -1, STR_TERMINATE
);
210 printf("\tflags:[0x%x]\n", i1
->flags
);
211 printf("\tname:[%s]\n", name
);
212 printf("\tdescription:[%s]\n", desc
);
213 printf("\tcomment:[%s]\n", comm
);
218 /****************************************************************************
219 ****************************************************************************/
221 static void display_print_info_2(PRINTER_INFO_2
*i2
)
223 fstring servername
= "";
224 fstring printername
= "";
225 fstring sharename
= "";
226 fstring portname
= "";
227 fstring drivername
= "";
228 fstring comment
= "";
229 fstring location
= "";
230 fstring sepfile
= "";
231 fstring printprocessor
= "";
232 fstring datatype
= "";
233 fstring parameters
= "";
235 rpcstr_pull(servername
, i2
->servername
.buffer
,sizeof(servername
), -1, STR_TERMINATE
);
236 rpcstr_pull(printername
, i2
->printername
.buffer
,sizeof(printername
), -1, STR_TERMINATE
);
237 rpcstr_pull(sharename
, i2
->sharename
.buffer
,sizeof(sharename
), -1, STR_TERMINATE
);
238 rpcstr_pull(portname
, i2
->portname
.buffer
,sizeof(portname
), -1, STR_TERMINATE
);
239 rpcstr_pull(drivername
, i2
->drivername
.buffer
,sizeof(drivername
), -1, STR_TERMINATE
);
240 rpcstr_pull(comment
, i2
->comment
.buffer
,sizeof(comment
), -1, STR_TERMINATE
);
241 rpcstr_pull(location
, i2
->location
.buffer
,sizeof(location
), -1, STR_TERMINATE
);
242 rpcstr_pull(sepfile
, i2
->sepfile
.buffer
,sizeof(sepfile
), -1, STR_TERMINATE
);
243 rpcstr_pull(printprocessor
, i2
->printprocessor
.buffer
,sizeof(printprocessor
), -1, STR_TERMINATE
);
244 rpcstr_pull(datatype
, i2
->datatype
.buffer
,sizeof(datatype
), -1, STR_TERMINATE
);
245 rpcstr_pull(parameters
, i2
->parameters
.buffer
,sizeof(parameters
), -1, STR_TERMINATE
);
247 printf("\tservername:[%s]\n", servername
);
248 printf("\tprintername:[%s]\n", printername
);
249 printf("\tsharename:[%s]\n", sharename
);
250 printf("\tportname:[%s]\n", portname
);
251 printf("\tdrivername:[%s]\n", drivername
);
252 printf("\tcomment:[%s]\n", comment
);
253 printf("\tlocation:[%s]\n", location
);
254 printf("\tsepfile:[%s]\n", sepfile
);
255 printf("\tprintprocessor:[%s]\n", printprocessor
);
256 printf("\tdatatype:[%s]\n", datatype
);
257 printf("\tparameters:[%s]\n", parameters
);
258 printf("\tattributes:[0x%x]\n", i2
->attributes
);
259 printf("\tpriority:[0x%x]\n", i2
->priority
);
260 printf("\tdefaultpriority:[0x%x]\n", i2
->defaultpriority
);
261 printf("\tstarttime:[0x%x]\n", i2
->starttime
);
262 printf("\tuntiltime:[0x%x]\n", i2
->untiltime
);
263 printf("\tstatus:[0x%x]\n", i2
->status
);
264 printf("\tcjobs:[0x%x]\n", i2
->cjobs
);
265 printf("\taverageppm:[0x%x]\n", i2
->averageppm
);
268 display_sec_desc(i2
->secdesc
);
273 /****************************************************************************
274 ****************************************************************************/
276 static void display_print_info_3(PRINTER_INFO_3
*i3
)
278 display_sec_desc(i3
->secdesc
);
283 /****************************************************************************
284 ****************************************************************************/
286 static void display_print_info_7(PRINTER_INFO_7
*i7
)
289 rpcstr_pull(guid
, i7
->guid
.buffer
,sizeof(guid
), -1, STR_TERMINATE
);
290 printf("\tguid:[%s]\n", guid
);
291 printf("\taction:[0x%x]\n", i7
->action
);
295 /****************************************************************************
296 ****************************************************************************/
298 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
300 int argc
, const char **argv
)
303 uint32 info_level
= 1;
304 PRINTER_INFO_CTR ctr
;
305 uint32 i
= 0, num_printers
;
310 printf("Usage: %s [level] [name]\n", argv
[0]);
315 info_level
= atoi(argv
[1]);
318 fstrcpy(name
, argv
[2]);
320 slprintf(name
, sizeof(name
)-1, "\\\\%s", cli
->cli
->desthost
);
326 result
= rpccli_spoolss_enum_printers(cli
, mem_ctx
, name
, PRINTER_ENUM_LOCAL
,
327 info_level
, &num_printers
, &ctr
);
329 if (W_ERROR_IS_OK(result
)) {
332 printf ("No printers returned.\n");
336 for (i
= 0; i
< num_printers
; i
++) {
339 display_print_info_0(&ctr
.printers_0
[i
]);
342 display_print_info_1(&ctr
.printers_1
[i
]);
345 display_print_info_2(&ctr
.printers_2
[i
]);
348 display_print_info_3(&ctr
.printers_3
[i
]);
351 printf("unknown info level %d\n", info_level
);
361 /****************************************************************************
362 ****************************************************************************/
364 static void display_port_info_1(PORT_INFO_1
*i1
)
368 rpcstr_pull(buffer
, i1
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
369 printf("\tPort Name:\t[%s]\n", buffer
);
372 /****************************************************************************
373 ****************************************************************************/
375 static void display_port_info_2(PORT_INFO_2
*i2
)
379 rpcstr_pull(buffer
, i2
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
380 printf("\tPort Name:\t[%s]\n", buffer
);
381 rpcstr_pull(buffer
, i2
->monitor_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
383 printf("\tMonitor Name:\t[%s]\n", buffer
);
384 rpcstr_pull(buffer
, i2
->description
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
386 printf("\tDescription:\t[%s]\n", buffer
);
387 printf("\tPort Type:\t" );
388 if ( i2
->port_type
) {
389 int comma
= 0; /* hack */
391 if ( i2
->port_type
& PORT_TYPE_READ
) {
395 if ( i2
->port_type
& PORT_TYPE_WRITE
) {
396 printf( "%sWrite", comma
? ", " : "" );
399 /* These two have slightly different interpretations
400 on 95/98/ME but I'm disregarding that for now */
401 if ( i2
->port_type
& PORT_TYPE_REDIRECTED
) {
402 printf( "%sRedirected", comma
? ", " : "" );
405 if ( i2
->port_type
& PORT_TYPE_NET_ATTACHED
) {
406 printf( "%sNet-Attached", comma
? ", " : "" );
410 printf( "[Unset]\n" );
412 printf("\tReserved:\t[%d]\n", i2
->reserved
);
416 /****************************************************************************
417 ****************************************************************************/
419 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
420 TALLOC_CTX
*mem_ctx
, int argc
,
424 uint32 info_level
= 1;
429 printf("Usage: %s [level]\n", argv
[0]);
434 info_level
= atoi(argv
[1]);
436 /* Enumerate ports */
440 result
= rpccli_spoolss_enum_ports(cli
, mem_ctx
, info_level
, &returned
, &ctr
);
442 if (W_ERROR_IS_OK(result
)) {
445 for (i
= 0; i
< returned
; i
++) {
446 switch (info_level
) {
448 display_port_info_1(&ctr
.port
.info_1
[i
]);
451 display_port_info_2(&ctr
.port
.info_2
[i
]);
454 printf("unknown info level %d\n", info_level
);
463 /****************************************************************************
464 ****************************************************************************/
466 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
468 int argc
, const char **argv
)
472 uint32 info_level
= 2;
473 bool opened_hnd
= False
;
474 PRINTER_INFO_CTR ctr
;
480 if (argc
== 1 || argc
> 3) {
481 printf("Usage: %s printername comment\n", argv
[0]);
486 /* Open a printer handle */
488 fstrcpy(comment
, argv
[2]);
491 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
492 strupper_m(servername
);
493 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
494 fstrcpy(user
, cli
->user_name
);
496 /* get a printer handle */
497 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
498 PRINTER_ALL_ACCESS
, servername
,
501 if (!W_ERROR_IS_OK(result
))
506 /* Get printer info */
507 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
509 if (!W_ERROR_IS_OK(result
))
513 /* Modify the comment. */
514 init_unistr(&ctr
.printers_2
->comment
, comment
);
515 ctr
.printers_2
->devmode
= NULL
;
516 ctr
.printers_2
->secdesc
= NULL
;
518 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
, 0);
519 if (W_ERROR_IS_OK(result
))
520 printf("Success in setting comment.\n");
524 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
529 /****************************************************************************
530 ****************************************************************************/
532 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
534 int argc
, const char **argv
)
538 uint32 info_level
= 2;
539 bool opened_hnd
= False
;
540 PRINTER_INFO_CTR ctr
;
546 if (argc
== 1 || argc
> 3) {
547 printf("Usage: %s printername new_printername\n", argv
[0]);
552 /* Open a printer handle */
554 fstrcpy(new_printername
, argv
[2]);
557 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
558 strupper_m(servername
);
559 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
560 fstrcpy(user
, cli
->user_name
);
562 /* get a printer handle */
563 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
564 PRINTER_ALL_ACCESS
, servername
,
567 if (!W_ERROR_IS_OK(result
))
572 /* Get printer info */
573 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
575 if (!W_ERROR_IS_OK(result
))
578 /* Modify the printername. */
579 init_unistr(&ctr
.printers_2
->printername
, new_printername
);
580 ctr
.printers_2
->devmode
= NULL
;
581 ctr
.printers_2
->secdesc
= NULL
;
583 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
, 0);
584 if (W_ERROR_IS_OK(result
))
585 printf("Success in setting printername.\n");
589 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
594 /****************************************************************************
595 ****************************************************************************/
597 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
599 int argc
, const char **argv
)
603 uint32 info_level
= 1;
604 bool opened_hnd
= False
;
605 PRINTER_INFO_CTR ctr
;
610 if (argc
== 1 || argc
> 3) {
611 printf("Usage: %s <printername> [level]\n", argv
[0]);
615 /* Open a printer handle */
617 info_level
= atoi(argv
[2]);
620 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
621 strupper_m(servername
);
622 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
623 fstrcpy(user
, cli
->user_name
);
625 /* get a printer handle */
627 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
628 "", MAXIMUM_ALLOWED_ACCESS
,
629 servername
, user
, &pol
);
631 if (!W_ERROR_IS_OK(result
))
636 /* Get printer info */
638 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
640 if (!W_ERROR_IS_OK(result
))
643 /* Display printer info */
645 switch (info_level
) {
647 display_print_info_0(ctr
.printers_0
);
650 display_print_info_1(ctr
.printers_1
);
653 display_print_info_2(ctr
.printers_2
);
656 display_print_info_3(ctr
.printers_3
);
659 display_print_info_7(ctr
.printers_7
);
662 printf("unknown info level %d\n", info_level
);
668 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
673 /****************************************************************************
674 ****************************************************************************/
676 static void display_reg_value(REGISTRY_VALUE value
)
682 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
683 *((uint32
*) value
.data_p
));
686 rpcstr_pull_talloc(talloc_tos(),
691 printf("%s: REG_SZ: %s\n", value
.valuename
, text
? text
: "");
694 char *hex
= hex_encode(NULL
, value
.data_p
, value
.size
);
696 printf("%s: REG_BINARY:", value
.valuename
);
698 for (i
=0; i
<len
; i
++) {
699 if (hex
[i
] == '\0') {
712 uint32 i
, num_values
;
715 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL
, value
.data_p
,
716 value
.size
, &num_values
,
718 d_printf("reg_pull_multi_sz failed\n");
722 for (i
=0; i
<num_values
; i
++) {
723 d_printf("%s\n", values
[i
]);
729 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
734 /****************************************************************************
735 ****************************************************************************/
737 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
739 int argc
, const char **argv
)
743 bool opened_hnd
= False
;
747 const char *valuename
;
748 REGISTRY_VALUE value
;
751 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
752 printf("<printername> of . queries print server\n");
757 /* Open a printer handle */
759 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
760 strupper_m(servername
);
761 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
762 fstrcpy(printername
, servername
);
764 slprintf(printername
, sizeof(servername
)-1, "%s\\%s",
765 servername
, argv
[1]);
766 fstrcpy(user
, cli
->user_name
);
768 /* get a printer handle */
770 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
771 "", MAXIMUM_ALLOWED_ACCESS
,
772 servername
, user
, &pol
);
774 if (!W_ERROR_IS_OK(result
))
779 /* Get printer info */
781 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
783 if (!W_ERROR_IS_OK(result
))
786 /* Display printer data */
788 fstrcpy(value
.valuename
, valuename
);
789 display_reg_value(value
);
794 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
799 /****************************************************************************
800 ****************************************************************************/
802 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
804 int argc
, const char **argv
)
808 bool opened_hnd
= False
;
812 const char *valuename
, *keyname
;
813 REGISTRY_VALUE value
;
816 printf("Usage: %s <printername> <keyname> <valuename>\n",
818 printf("<printername> of . queries print server\n");
824 /* Open a printer handle */
826 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
827 strupper_m(servername
);
828 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
829 fstrcpy(printername
, servername
);
831 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
832 servername
, argv
[1]);
833 fstrcpy(user
, cli
->user_name
);
835 /* get a printer handle */
837 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
838 "", MAXIMUM_ALLOWED_ACCESS
,
839 servername
, user
, &pol
);
841 if (!W_ERROR_IS_OK(result
))
846 /* Get printer info */
848 result
= rpccli_spoolss_getprinterdataex(cli
, mem_ctx
, &pol
, keyname
,
851 if (!W_ERROR_IS_OK(result
))
854 /* Display printer data */
856 fstrcpy(value
.valuename
, valuename
);
857 display_reg_value(value
);
862 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
867 /****************************************************************************
868 ****************************************************************************/
870 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
876 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
878 printf ("Printer Driver Info 1:\n");
879 printf ("\tDriver Name: [%s]\n\n", name
);
884 /****************************************************************************
885 ****************************************************************************/
887 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
890 fstring architecture
;
897 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
898 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
899 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
900 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
901 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
903 printf ("Printer Driver Info 2:\n");
904 printf ("\tVersion: [%x]\n", i1
->version
);
905 printf ("\tDriver Name: [%s]\n", name
);
906 printf ("\tArchitecture: [%s]\n", architecture
);
907 printf ("\tDriver Path: [%s]\n", driverpath
);
908 printf ("\tDatafile: [%s]\n", datafile
);
909 printf ("\tConfigfile: [%s]\n\n", configfile
);
914 /****************************************************************************
915 ****************************************************************************/
917 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
920 fstring architecture
= "";
921 fstring driverpath
= "";
922 fstring datafile
= "";
923 fstring configfile
= "";
924 fstring helpfile
= "";
925 fstring dependentfiles
= "";
926 fstring monitorname
= "";
927 fstring defaultdatatype
= "";
935 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
936 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
937 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
938 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
939 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
940 rpcstr_pull(helpfile
, i1
->helpfile
.buffer
, sizeof(helpfile
), -1, STR_TERMINATE
);
941 rpcstr_pull(monitorname
, i1
->monitorname
.buffer
, sizeof(monitorname
), -1, STR_TERMINATE
);
942 rpcstr_pull(defaultdatatype
, i1
->defaultdatatype
.buffer
, sizeof(defaultdatatype
), -1, STR_TERMINATE
);
944 printf ("Printer Driver Info 3:\n");
945 printf ("\tVersion: [%x]\n", i1
->version
);
946 printf ("\tDriver Name: [%s]\n",name
);
947 printf ("\tArchitecture: [%s]\n", architecture
);
948 printf ("\tDriver Path: [%s]\n", driverpath
);
949 printf ("\tDatafile: [%s]\n", datafile
);
950 printf ("\tConfigfile: [%s]\n", configfile
);
951 printf ("\tHelpfile: [%s]\n\n", helpfile
);
955 rpcstr_pull(dependentfiles
, i1
->dependentfiles
+length
, sizeof(dependentfiles
), -1, STR_TERMINATE
);
957 length
+=strlen(dependentfiles
)+1;
959 if (strlen(dependentfiles
) > 0)
961 printf ("\tDependentfiles: [%s]\n", dependentfiles
);
971 printf ("\tMonitorname: [%s]\n", monitorname
);
972 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
977 /****************************************************************************
978 ****************************************************************************/
980 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
982 int argc
, const char **argv
)
986 uint32 info_level
= 3;
987 bool opened_hnd
= False
;
988 PRINTER_DRIVER_CTR ctr
;
993 bool success
= False
;
995 if ((argc
== 1) || (argc
> 3))
997 printf("Usage: %s <printername> [level]\n", argv
[0]);
1001 /* get the arguments need to open the printer handle */
1002 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1003 strupper_m(servername
);
1004 fstrcpy(user
, cli
->user_name
);
1005 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1007 info_level
= atoi(argv
[2]);
1009 /* Open a printer handle */
1011 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1013 servername
, user
, &pol
);
1015 if (!W_ERROR_IS_OK(werror
)) {
1016 printf("Error opening printer handle for %s!\n", printername
);
1022 /* loop through and print driver info level for each architecture */
1024 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1026 werror
= rpccli_spoolss_getprinterdriver( cli
, mem_ctx
, &pol
, info_level
,
1027 archi_table
[i
].long_archi
, archi_table
[i
].version
,
1030 if (!W_ERROR_IS_OK(werror
))
1033 /* need at least one success */
1037 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1039 switch (info_level
) {
1041 display_print_driver_1 (ctr
.info1
);
1044 display_print_driver_2 (ctr
.info2
);
1047 display_print_driver_3 (ctr
.info3
);
1050 printf("unknown info level %d\n", info_level
);
1058 rpccli_spoolss_close_printer (cli
, mem_ctx
, &pol
);
1066 /****************************************************************************
1067 ****************************************************************************/
1069 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1070 TALLOC_CTX
*mem_ctx
,
1071 int argc
, const char **argv
)
1073 WERROR werror
= WERR_OK
;
1074 uint32 info_level
= 1;
1075 PRINTER_DRIVER_CTR ctr
;
1080 printf("Usage: enumdrivers [level]\n");
1085 info_level
= atoi(argv
[1]);
1088 /* loop through and print driver info level for each architecture */
1089 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1090 /* check to see if we already asked for this architecture string */
1092 if ( i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
) )
1095 werror
= rpccli_spoolss_enumprinterdrivers(
1096 cli
, mem_ctx
, info_level
,
1097 archi_table
[i
].long_archi
, &returned
, &ctr
);
1099 if (W_ERROR_V(werror
) == W_ERROR_V(WERR_INVALID_ENVIRONMENT
)) {
1100 printf ("Server does not support environment [%s]\n",
1101 archi_table
[i
].long_archi
);
1109 if (!W_ERROR_IS_OK(werror
)) {
1110 printf ("Error getting driver for environment [%s] - %d\n",
1111 archi_table
[i
].long_archi
, W_ERROR_V(werror
));
1115 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1120 for (j
=0; j
< returned
; j
++) {
1121 display_print_driver_1 (&ctr
.info1
[j
]);
1125 for (j
=0; j
< returned
; j
++) {
1126 display_print_driver_2 (&ctr
.info2
[j
]);
1130 for (j
=0; j
< returned
; j
++) {
1131 display_print_driver_3 (&ctr
.info3
[j
]);
1135 printf("unknown info level %d\n", info_level
);
1136 return WERR_UNKNOWN_LEVEL
;
1143 /****************************************************************************
1144 ****************************************************************************/
1146 static void display_printdriverdir_1(DRIVER_DIRECTORY_1
*i1
)
1152 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
1154 printf ("\tDirectory Name:[%s]\n", name
);
1157 /****************************************************************************
1158 ****************************************************************************/
1160 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1161 TALLOC_CTX
*mem_ctx
,
1162 int argc
, const char **argv
)
1166 DRIVER_DIRECTORY_CTR ctr
;
1169 printf("Usage: %s [environment]\n", argv
[0]);
1173 /* Get the arguments need to open the printer handle */
1176 fstrcpy (env
, argv
[1]);
1178 fstrcpy (env
, "Windows NT x86");
1180 /* Get the directory. Only use Info level 1 */
1182 result
= rpccli_spoolss_getprinterdriverdir(cli
, mem_ctx
, 1, env
, &ctr
);
1184 if (W_ERROR_IS_OK(result
))
1185 display_printdriverdir_1(ctr
.info1
);
1190 /****************************************************************************
1191 ****************************************************************************/
1193 void set_drv_info_3_env (DRIVER_INFO_3
*info
, const char *arch
)
1198 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1200 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1202 info
->version
= archi_table
[i
].version
;
1203 init_unistr (&info
->architecture
, archi_table
[i
].long_archi
);
1208 if (archi_table
[i
].long_archi
== NULL
)
1210 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1217 /**************************************************************************
1218 wrapper for strtok to get the next parameter from a delimited list.
1219 Needed to handle the empty parameter string denoted by "NULL"
1220 *************************************************************************/
1222 static char* get_driver_3_param (char* str
, const char* delim
, UNISTR
* dest
)
1226 /* get the next token */
1227 ptr
= strtok(str
, delim
);
1229 /* a string of 'NULL' is used to represent an empty
1230 parameter because two consecutive delimiters
1231 will not return an empty string. See man strtok(3)
1233 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0))
1237 init_unistr(dest
, ptr
);
1242 /********************************************************************************
1243 fill in the members of a DRIVER_INFO_3 struct using a character
1244 string in the form of
1245 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1246 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1247 <Default Data Type>:<Comma Separated list of Files>
1248 *******************************************************************************/
1249 static bool init_drv_info_3_members ( TALLOC_CTX
*mem_ctx
, DRIVER_INFO_3
*info
,
1255 /* fill in the UNISTR fields */
1256 str
= get_driver_3_param (args
, ":", &info
->name
);
1257 str
= get_driver_3_param (NULL
, ":", &info
->driverpath
);
1258 str
= get_driver_3_param (NULL
, ":", &info
->datafile
);
1259 str
= get_driver_3_param (NULL
, ":", &info
->configfile
);
1260 str
= get_driver_3_param (NULL
, ":", &info
->helpfile
);
1261 str
= get_driver_3_param (NULL
, ":", &info
->monitorname
);
1262 str
= get_driver_3_param (NULL
, ":", &info
->defaultdatatype
);
1264 /* <Comma Separated List of Dependent Files> */
1265 str2
= get_driver_3_param (NULL
, ":", NULL
); /* save the beginning of the string */
1268 /* begin to strip out each filename */
1269 str
= strtok(str
, ",");
1273 /* keep a cumlative count of the str lengths */
1274 len
+= strlen(str
)+1;
1275 str
= strtok(NULL
, ",");
1278 /* allocate the space; add one extra slot for a terminating NULL.
1279 Each filename is NULL terminated and the end contains a double
1281 if ((info
->dependentfiles
=TALLOC_ARRAY(mem_ctx
, uint16
, len
+1)) == NULL
)
1283 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1286 for (i
=0; i
<len
; i
++)
1288 SSVAL(&info
->dependentfiles
[i
], 0, str2
[i
]);
1290 info
->dependentfiles
[len
] = '\0';
1296 /****************************************************************************
1297 ****************************************************************************/
1299 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1300 TALLOC_CTX
*mem_ctx
,
1301 int argc
, const char **argv
)
1305 PRINTER_DRIVER_CTR ctr
;
1306 DRIVER_INFO_3 info3
;
1308 fstring driver_name
;
1311 /* parse the command arguements */
1312 if (argc
!= 3 && argc
!= 4)
1314 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1315 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1316 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1317 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1318 printf ("\t[version]\n");
1323 /* Fill in the DRIVER_INFO_3 struct */
1325 if (!(arch
= cmd_spoolss_get_short_archi(argv
[1])))
1327 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1328 return WERR_INVALID_PARAM
;
1331 set_drv_info_3_env(&info3
, arch
);
1333 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1334 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1336 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1337 return WERR_INVALID_PARAM
;
1340 /* if printer driver version specified, override the default version
1341 * used by the architecture. This allows installation of Windows
1342 * 2000 (version 3) printer drivers. */
1345 info3
.version
= atoi(argv
[3]);
1350 result
= rpccli_spoolss_addprinterdriver (cli
, mem_ctx
, level
, &ctr
);
1352 if (W_ERROR_IS_OK(result
)) {
1353 rpcstr_pull(driver_name
, info3
.name
.buffer
,
1354 sizeof(driver_name
), -1, STR_TERMINATE
);
1355 printf ("Printer Driver %s successfully installed.\n",
1363 /****************************************************************************
1364 ****************************************************************************/
1366 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1367 TALLOC_CTX
*mem_ctx
,
1368 int argc
, const char **argv
)
1372 PRINTER_INFO_CTR ctr
;
1373 PRINTER_INFO_2 info2
;
1376 /* parse the command arguements */
1379 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1383 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1384 strupper_m(servername
);
1386 /* Fill in the DRIVER_INFO_2 struct */
1389 init_unistr( &info2
.printername
, argv
[1]);
1390 init_unistr( &info2
.sharename
, argv
[2]);
1391 init_unistr( &info2
.drivername
, argv
[3]);
1392 init_unistr( &info2
.portname
, argv
[4]);
1393 init_unistr( &info2
.comment
, "Created by rpcclient");
1394 init_unistr( &info2
.printprocessor
, "winprint");
1395 init_unistr( &info2
.datatype
, "RAW");
1396 info2
.devmode
= NULL
;
1397 info2
.secdesc
= NULL
;
1398 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1400 info2
.defaultpriority
= 0;
1401 info2
.starttime
= 0;
1402 info2
.untiltime
= 0;
1404 /* These three fields must not be used by AddPrinter()
1405 as defined in the MS Platform SDK documentation..
1409 info2.averageppm = 0;
1412 ctr
.printers_2
= &info2
;
1413 result
= rpccli_spoolss_addprinterex (cli
, mem_ctx
, level
, &ctr
);
1415 if (W_ERROR_IS_OK(result
))
1416 printf ("Printer %s successfully installed.\n", argv
[1]);
1421 /****************************************************************************
1422 ****************************************************************************/
1424 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1425 TALLOC_CTX
*mem_ctx
,
1426 int argc
, const char **argv
)
1431 bool opened_hnd
= False
;
1432 PRINTER_INFO_CTR ctr
;
1433 PRINTER_INFO_2 info2
;
1438 /* parse the command arguements */
1441 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1445 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1446 strupper_m(servername
);
1447 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
1448 fstrcpy(user
, cli
->user_name
);
1450 /* Get a printer handle */
1452 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1454 servername
, user
, &pol
);
1456 if (!W_ERROR_IS_OK(result
))
1461 /* Get printer info */
1463 ZERO_STRUCT (info2
);
1464 ctr
.printers_2
= &info2
;
1466 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, level
, &ctr
);
1468 if (!W_ERROR_IS_OK(result
)) {
1469 printf ("Unable to retrieve printer information!\n");
1473 /* Set the printer driver */
1475 init_unistr(&ctr
.printers_2
->drivername
, argv
[2]);
1477 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, level
, &ctr
, 0);
1479 if (!W_ERROR_IS_OK(result
)) {
1480 printf("SetPrinter call failed!\n");
1484 printf("Succesfully set %s to driver %s.\n", argv
[1], argv
[2]);
1490 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
1496 /****************************************************************************
1497 ****************************************************************************/
1499 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1500 TALLOC_CTX
*mem_ctx
,
1501 int argc
, const char **argv
)
1503 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1508 const char *arch
= NULL
;
1510 /* parse the command arguements */
1511 if (argc
< 2 || argc
> 4) {
1512 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1519 vers
= atoi (argv
[3]);
1522 /* delete the driver for all architectures */
1523 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1525 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1528 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1531 /* make the call to remove the driver */
1532 result
= rpccli_spoolss_deleteprinterdriverex(
1533 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1], archi_table
[i
].version
);
1535 if ( !W_ERROR_IS_OK(result
) )
1537 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1538 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1539 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, dos_errstr(result
));
1544 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1545 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1554 /****************************************************************************
1555 ****************************************************************************/
1557 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1558 TALLOC_CTX
*mem_ctx
,
1559 int argc
, const char **argv
)
1561 WERROR result
= WERR_OK
;
1565 /* parse the command arguements */
1567 printf ("Usage: %s <driver>\n", argv
[0]);
1571 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1572 strupper_m(servername
);
1574 /* delete the driver for all architectures */
1575 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1576 /* make the call to remove the driver */
1577 result
= rpccli_spoolss_deleteprinterdriver(
1578 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1]);
1580 if ( !W_ERROR_IS_OK(result
) ) {
1581 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1582 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1583 argv
[1], archi_table
[i
].long_archi
,
1587 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1588 archi_table
[i
].long_archi
);
1595 /****************************************************************************
1596 ****************************************************************************/
1598 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1599 TALLOC_CTX
*mem_ctx
,
1600 int argc
, const char **argv
)
1603 char *servername
= NULL
, *environment
= NULL
;
1606 /* parse the command arguements */
1608 printf ("Usage: %s [environment]\n", argv
[0]);
1612 if (asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
) < 0)
1614 strupper_m(servername
);
1616 if (asprintf(&environment
, "%s", (argc
== 2) ? argv
[1] :
1617 PRINTER_DRIVER_ARCHITECTURE
) < 0) {
1618 SAFE_FREE(servername
);
1622 result
= rpccli_spoolss_getprintprocessordirectory(
1623 cli
, mem_ctx
, servername
, environment
, procdir
);
1625 if (W_ERROR_IS_OK(result
))
1626 printf("%s\n", procdir
);
1628 SAFE_FREE(servername
);
1629 SAFE_FREE(environment
);
1634 /****************************************************************************
1635 ****************************************************************************/
1637 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1638 int argc
, const char **argv
)
1642 char *servername
= NULL
, *printername
= NULL
;
1644 bool got_handle
= False
;
1646 /* Parse the command arguements */
1649 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1653 /* Get a printer handle */
1655 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1656 strupper_m(servername
);
1657 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1659 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1661 servername
, cli
->user_name
, &handle
);
1663 if (!W_ERROR_IS_OK(werror
))
1668 /* Dummy up some values for the form data */
1670 form
.flags
= FORM_USER
;
1671 form
.size_x
= form
.size_y
= 100;
1677 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1682 werror
= rpccli_spoolss_addform(cli
, mem_ctx
, &handle
, 1, &form
);
1686 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1688 SAFE_FREE(servername
);
1689 SAFE_FREE(printername
);
1694 /****************************************************************************
1695 ****************************************************************************/
1697 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1698 int argc
, const char **argv
)
1702 char *servername
= NULL
, *printername
= NULL
;
1704 bool got_handle
= False
;
1706 /* Parse the command arguements */
1709 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1713 /* Get a printer handle */
1715 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1716 strupper_m(servername
);
1717 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1719 werror
= rpccli_spoolss_open_printer_ex(
1720 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1721 servername
, cli
->user_name
, &handle
);
1723 if (!W_ERROR_IS_OK(werror
))
1728 /* Dummy up some values for the form data */
1730 form
.flags
= FORM_PRINTER
;
1731 form
.size_x
= form
.size_y
= 100;
1737 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1741 werror
= rpccli_spoolss_setform(cli
, mem_ctx
, &handle
, 1, argv
[2], &form
);
1745 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1747 SAFE_FREE(servername
);
1748 SAFE_FREE(printername
);
1753 /****************************************************************************
1754 ****************************************************************************/
1756 static const char *get_form_flag(int form_flag
)
1758 switch (form_flag
) {
1762 return "FORM_BUILTIN";
1764 return "FORM_PRINTER";
1770 /****************************************************************************
1771 ****************************************************************************/
1773 static void display_form(FORM_1
*form
)
1775 fstring form_name
= "";
1777 if (form
->name
.buffer
)
1778 rpcstr_pull(form_name
, form
->name
.buffer
,
1779 sizeof(form_name
), -1, STR_TERMINATE
);
1782 "\tflag: %s (%d)\n" \
1783 "\twidth: %d, length: %d\n" \
1784 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1785 form_name
, get_form_flag(form
->flag
), form
->flag
,
1786 form
->width
, form
->length
,
1787 form
->left
, form
->right
,
1788 form
->top
, form
->bottom
);
1791 /****************************************************************************
1792 ****************************************************************************/
1794 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1795 int argc
, const char **argv
)
1799 char *servername
= NULL
, *printername
= NULL
;
1801 bool got_handle
= False
;
1803 /* Parse the command arguements */
1806 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1810 /* Get a printer handle */
1812 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1813 strupper_m(servername
);
1814 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1816 werror
= rpccli_spoolss_open_printer_ex(
1817 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1818 servername
, cli
->user_name
, &handle
);
1820 if (!W_ERROR_IS_OK(werror
))
1827 werror
= rpccli_spoolss_getform(cli
, mem_ctx
, &handle
, argv
[2], 1, &form
);
1829 if (!W_ERROR_IS_OK(werror
))
1832 display_form(&form
);
1836 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1838 SAFE_FREE(servername
);
1839 SAFE_FREE(printername
);
1844 /****************************************************************************
1845 ****************************************************************************/
1847 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
1848 TALLOC_CTX
*mem_ctx
, int argc
,
1853 char *servername
= NULL
, *printername
= NULL
;
1854 bool got_handle
= False
;
1856 /* Parse the command arguements */
1859 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1863 /* Get a printer handle */
1865 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1866 strupper_m(servername
);
1867 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1869 werror
= rpccli_spoolss_open_printer_ex(
1870 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1871 servername
, cli
->user_name
, &handle
);
1873 if (!W_ERROR_IS_OK(werror
))
1878 /* Delete the form */
1880 werror
= rpccli_spoolss_deleteform(cli
, mem_ctx
, &handle
, argv
[2]);
1884 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1886 SAFE_FREE(servername
);
1887 SAFE_FREE(printername
);
1892 /****************************************************************************
1893 ****************************************************************************/
1895 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
1896 TALLOC_CTX
*mem_ctx
, int argc
,
1901 char *servername
= NULL
, *printername
= NULL
;
1902 bool got_handle
= False
;
1903 uint32 num_forms
, level
= 1, i
;
1906 /* Parse the command arguements */
1909 printf ("Usage: %s <printer>\n", argv
[0]);
1913 /* Get a printer handle */
1915 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1916 strupper_m(servername
);
1917 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1919 werror
= rpccli_spoolss_open_printer_ex(
1920 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1921 servername
, cli
->user_name
, &handle
);
1923 if (!W_ERROR_IS_OK(werror
))
1928 /* Enumerate forms */
1930 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
, &handle
, level
, &num_forms
, &forms
);
1932 if (!W_ERROR_IS_OK(werror
))
1935 /* Display output */
1937 for (i
= 0; i
< num_forms
; i
++) {
1939 display_form(&forms
[i
]);
1945 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1947 SAFE_FREE(servername
);
1948 SAFE_FREE(printername
);
1953 /****************************************************************************
1954 ****************************************************************************/
1956 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
1957 TALLOC_CTX
*mem_ctx
,
1958 int argc
, const char **argv
)
1961 fstring servername
, printername
, user
;
1963 bool opened_hnd
= False
;
1964 PRINTER_INFO_CTR ctr
;
1965 PRINTER_INFO_0 info
;
1966 REGISTRY_VALUE value
;
1968 /* parse the command arguements */
1970 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
1971 " <value> <data>\n",
1973 return WERR_INVALID_PARAM
;
1976 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1977 strupper_m(servername
);
1978 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1979 fstrcpy(user
, cli
->user_name
);
1981 value
.type
= REG_NONE
;
1983 if (strequal(argv
[2], "string")) {
1984 value
.type
= REG_SZ
;
1987 if (strequal(argv
[2], "binary")) {
1988 value
.type
= REG_BINARY
;
1991 if (strequal(argv
[2], "dword")) {
1992 value
.type
= REG_DWORD
;
1995 if (strequal(argv
[2], "multistring")) {
1996 value
.type
= REG_MULTI_SZ
;
1999 if (value
.type
== REG_NONE
) {
2000 printf("Unknown data type: %s\n", argv
[2]);
2001 return WERR_INVALID_PARAM
;
2004 /* get a printer handle */
2005 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
2006 MAXIMUM_ALLOWED_ACCESS
, servername
,
2008 if (!W_ERROR_IS_OK(result
))
2013 ctr
.printers_0
= &info
;
2015 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2017 if (!W_ERROR_IS_OK(result
))
2020 printf("%s\n", current_timestring(True
));
2021 printf("\tchange_id (before set)\t:[0x%x]\n", info
.change_id
);
2023 /* Set the printer data */
2025 fstrcpy(value
.valuename
, argv
[3]);
2027 switch (value
.type
) {
2030 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2031 value
.size
= data
.uni_str_len
* 2;
2033 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, data
.buffer
,
2036 value
.data_p
= NULL
;
2041 uint32 data
= strtoul(argv
[4], NULL
, 10);
2042 value
.size
= sizeof(data
);
2044 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, &data
,
2047 value
.data_p
= NULL
;
2052 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2053 value
.data_p
= data
.data
;
2054 value
.size
= data
.length
;
2057 case REG_MULTI_SZ
: {
2062 for (i
=4; i
<argc
; i
++) {
2063 if (strcmp(argv
[i
], "NULL") == 0) {
2066 len
+= strlen(argv
[i
])+1;
2070 value
.data_p
= TALLOC_ARRAY(mem_ctx
, unsigned char, value
.size
);
2071 if (value
.data_p
== NULL
) {
2072 result
= WERR_NOMEM
;
2076 p
= (char *)value
.data_p
;
2078 for (i
=4; i
<argc
; i
++) {
2079 size_t l
= (strlen(argv
[i
])+1)*2;
2080 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2084 SMB_ASSERT(len
== 0);
2088 printf("Unknown data type: %s\n", argv
[2]);
2089 result
= WERR_INVALID_PARAM
;
2093 result
= rpccli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2095 if (!W_ERROR_IS_OK(result
)) {
2096 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2099 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2101 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2103 if (!W_ERROR_IS_OK(result
))
2106 printf("%s\n", current_timestring(True
));
2107 printf("\tchange_id (after set)\t:[0x%x]\n", info
.change_id
);
2112 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
2117 /****************************************************************************
2118 ****************************************************************************/
2120 static void display_job_info_1(JOB_INFO_1
*job
)
2122 fstring username
= "", document
= "", text_status
= "";
2124 rpcstr_pull(username
, job
->username
.buffer
,
2125 sizeof(username
), -1, STR_TERMINATE
);
2127 rpcstr_pull(document
, job
->document
.buffer
,
2128 sizeof(document
), -1, STR_TERMINATE
);
2130 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2131 sizeof(text_status
), -1, STR_TERMINATE
);
2133 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job
->position
, job
->jobid
,
2134 username
, document
, text_status
, job
->pagesprinted
,
2138 /****************************************************************************
2139 ****************************************************************************/
2141 static void display_job_info_2(JOB_INFO_2
*job
)
2143 fstring username
= "", document
= "", text_status
= "";
2145 rpcstr_pull(username
, job
->username
.buffer
,
2146 sizeof(username
), -1, STR_TERMINATE
);
2148 rpcstr_pull(document
, job
->document
.buffer
,
2149 sizeof(document
), -1, STR_TERMINATE
);
2151 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2152 sizeof(text_status
), -1, STR_TERMINATE
);
2154 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job
->position
, job
->jobid
,
2155 username
, document
, text_status
, job
->pagesprinted
,
2156 job
->totalpages
, job
->size
);
2159 /****************************************************************************
2160 ****************************************************************************/
2162 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2163 TALLOC_CTX
*mem_ctx
, int argc
,
2167 uint32 level
= 1, num_jobs
, i
;
2168 bool got_hnd
= False
;
2169 char *printername
= NULL
;
2170 fstring servername
, user
;
2174 if (argc
< 2 || argc
> 3) {
2175 printf("Usage: %s printername [level]\n", argv
[0]);
2180 level
= atoi(argv
[2]);
2182 /* Open printer handle */
2184 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2185 strupper_m(servername
);
2186 fstrcpy(user
, cli
->user_name
);
2187 printername
= talloc_asprintf(mem_ctx
,
2189 cli
->cli
->desthost
);
2193 strupper_m(printername
);
2194 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2199 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2200 "", MAXIMUM_ALLOWED_ACCESS
,
2201 servername
, user
, &hnd
);
2203 if (!W_ERROR_IS_OK(result
))
2208 /* Enumerate ports */
2210 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2213 if (!W_ERROR_IS_OK(result
))
2216 for (i
= 0; i
< num_jobs
; i
++) {
2219 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2222 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2225 d_printf("unknown info level %d\n", level
);
2232 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2237 /****************************************************************************
2238 ****************************************************************************/
2240 static WERROR
cmd_spoolss_enum_data( struct rpc_pipe_client
*cli
,
2241 TALLOC_CTX
*mem_ctx
, int argc
,
2245 uint32 i
=0, val_needed
, data_needed
;
2246 bool got_hnd
= False
;
2247 char *printername
= NULL
;
2248 fstring servername
, user
;
2252 printf("Usage: %s printername\n", argv
[0]);
2256 /* Open printer handle */
2258 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2259 strupper_m(servername
);
2260 fstrcpy(user
, cli
->user_name
);
2261 printername
= talloc_asprintf(mem_ctx
,
2263 cli
->cli
->desthost
);
2267 strupper_m(printername
);
2268 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2273 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2274 "", MAXIMUM_ALLOWED_ACCESS
,
2275 servername
, user
, &hnd
);
2277 if (!W_ERROR_IS_OK(result
))
2282 /* Enumerate data */
2284 result
= rpccli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2285 &val_needed
, &data_needed
,
2287 while (W_ERROR_IS_OK(result
)) {
2288 REGISTRY_VALUE value
;
2289 result
= rpccli_spoolss_enumprinterdata(
2290 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2291 data_needed
, 0, 0, &value
);
2292 if (W_ERROR_IS_OK(result
))
2293 display_reg_value(value
);
2295 if (W_ERROR_V(result
) == ERRnomoreitems
)
2296 result
= W_ERROR(ERRsuccess
);
2300 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2305 /****************************************************************************
2306 ****************************************************************************/
2308 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2309 TALLOC_CTX
*mem_ctx
, int argc
,
2314 bool got_hnd
= False
;
2315 char *printername
= NULL
;
2316 fstring servername
, user
;
2317 const char *keyname
= NULL
;
2319 REGVAL_CTR
*ctr
= NULL
;
2322 printf("Usage: %s printername <keyname>\n", argv
[0]);
2328 /* Open printer handle */
2330 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2331 strupper_m(servername
);
2332 fstrcpy(user
, cli
->user_name
);
2334 printername
= talloc_asprintf(mem_ctx
,
2336 cli
->cli
->desthost
);
2340 strupper_m(printername
);
2341 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2346 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2347 "", MAXIMUM_ALLOWED_ACCESS
,
2348 servername
, user
, &hnd
);
2350 if (!W_ERROR_IS_OK(result
))
2355 /* Enumerate subkeys */
2357 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2360 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2362 if (!W_ERROR_IS_OK(result
))
2365 for (i
=0; i
< ctr
->num_values
; i
++) {
2366 display_reg_value(*(ctr
->values
[i
]));
2373 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2378 /****************************************************************************
2379 ****************************************************************************/
2381 static WERROR
cmd_spoolss_enum_printerkey( struct rpc_pipe_client
*cli
,
2382 TALLOC_CTX
*mem_ctx
, int argc
,
2386 bool got_hnd
= False
;
2387 char *printername
= NULL
;
2388 fstring servername
, user
;
2389 const char *keyname
= NULL
;
2391 uint16
*keylist
= NULL
, *curkey
;
2393 if (argc
< 2 || argc
> 3) {
2394 printf("Usage: %s printername [keyname]\n", argv
[0]);
2403 /* Open printer handle */
2405 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2406 strupper_m(servername
);
2407 fstrcpy(user
, cli
->user_name
);
2409 printername
= talloc_asprintf(mem_ctx
,
2411 cli
->cli
->desthost
);
2415 strupper_m(printername
);
2416 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2422 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2423 "", MAXIMUM_ALLOWED_ACCESS
,
2424 servername
, user
, &hnd
);
2426 if (!W_ERROR_IS_OK(result
))
2431 /* Enumerate subkeys */
2433 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2435 if (!W_ERROR_IS_OK(result
))
2439 while (*curkey
!= 0) {
2440 char *subkey
= NULL
;
2441 rpcstr_pull_talloc(mem_ctx
, &subkey
, curkey
, -1,
2446 printf("%s\n", subkey
);
2447 curkey
+= strlen(subkey
) + 1;
2455 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2460 /****************************************************************************
2461 ****************************************************************************/
2463 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2464 TALLOC_CTX
*mem_ctx
, int argc
,
2467 fstring servername
, printername
;
2469 bool got_hnd
= False
;
2471 SPOOL_NOTIFY_OPTION option
;
2474 printf("Usage: %s printername\n", argv
[0]);
2481 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", cli
->cli
->desthost
);
2482 strupper_m(servername
);
2484 slprintf(printername
, sizeof(printername
) - 1, "\\\\%s\\%s", cli
->cli
->desthost
,
2486 strupper_m(printername
);
2488 result
= rpccli_spoolss_open_printer_ex(
2489 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
2490 servername
, cli
->user_name
, &hnd
);
2492 if (!W_ERROR_IS_OK(result
)) {
2493 printf("Error opening %s\n", argv
[1]);
2499 /* Create spool options */
2501 ZERO_STRUCT(option
);
2504 option
.option_type_ptr
= 1;
2505 option
.count
= option
.ctr
.count
= 2;
2507 option
.ctr
.type
= TALLOC_ARRAY(mem_ctx
, SPOOL_NOTIFY_OPTION_TYPE
, 2);
2508 if (option
.ctr
.type
== NULL
) {
2509 result
= WERR_NOMEM
;
2513 ZERO_STRUCT(option
.ctr
.type
[0]);
2514 option
.ctr
.type
[0].type
= PRINTER_NOTIFY_TYPE
;
2515 option
.ctr
.type
[0].count
= option
.ctr
.type
[0].count2
= 1;
2516 option
.ctr
.type
[0].fields_ptr
= 1;
2517 option
.ctr
.type
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2519 ZERO_STRUCT(option
.ctr
.type
[1]);
2520 option
.ctr
.type
[1].type
= JOB_NOTIFY_TYPE
;
2521 option
.ctr
.type
[1].count
= option
.ctr
.type
[1].count2
= 1;
2522 option
.ctr
.type
[1].fields_ptr
= 1;
2523 option
.ctr
.type
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2527 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", myhostname());
2528 strupper_m(servername
);
2530 result
= rpccli_spoolss_rffpcnex(
2531 cli
, mem_ctx
, &hnd
, 0, 0, servername
, 123, &option
);
2533 if (!W_ERROR_IS_OK(result
)) {
2534 printf("Error rffpcnex %s\n", argv
[1]);
2540 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2545 /****************************************************************************
2546 ****************************************************************************/
2548 static bool compare_printer( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2549 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2551 PRINTER_INFO_CTR ctr1
, ctr2
;
2553 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2555 printf("Retrieving printer propertiesfor %s...", cli1
->cli
->desthost
);
2556 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 2, &ctr1
);
2557 if ( !W_ERROR_IS_OK(werror
) ) {
2558 printf("failed (%s)\n", dos_errstr(werror
));
2559 talloc_destroy(mem_ctx
);
2564 printf("Retrieving printer properties for %s...", cli2
->cli
->desthost
);
2565 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 2, &ctr2
);
2566 if ( !W_ERROR_IS_OK(werror
) ) {
2567 printf("failed (%s)\n", dos_errstr(werror
));
2568 talloc_destroy(mem_ctx
);
2573 talloc_destroy(mem_ctx
);
2578 /****************************************************************************
2579 ****************************************************************************/
2581 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2582 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2584 PRINTER_INFO_CTR ctr1
, ctr2
;
2586 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2587 SEC_DESC
*sd1
, *sd2
;
2591 printf("Retreiving printer security for %s...", cli1
->cli
->desthost
);
2592 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 3, &ctr1
);
2593 if ( !W_ERROR_IS_OK(werror
) ) {
2594 printf("failed (%s)\n", dos_errstr(werror
));
2600 printf("Retrieving printer security for %s...", cli2
->cli
->desthost
);
2601 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 3, &ctr2
);
2602 if ( !W_ERROR_IS_OK(werror
) ) {
2603 printf("failed (%s)\n", dos_errstr(werror
));
2612 if ( (ctr1
.printers_3
!= ctr2
.printers_3
) && (!ctr1
.printers_3
|| !ctr2
.printers_3
) ) {
2613 printf("NULL PRINTER_INFO_3!\n");
2618 sd1
= ctr1
.printers_3
->secdesc
;
2619 sd2
= ctr2
.printers_3
->secdesc
;
2621 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2622 printf("NULL secdesc!\n");
2627 if (!sec_desc_equal( sd1
, sd2
) ) {
2628 printf("Security Descriptors *not* equal!\n");
2633 printf("Security descriptors match\n");
2636 talloc_destroy(mem_ctx
);
2641 /****************************************************************************
2642 ****************************************************************************/
2644 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
2645 TALLOC_CTX
*mem_ctx
, int argc
,
2648 fstring printername
, servername1
, servername2
;
2649 char *printername_path
= NULL
;
2650 struct cli_state
*cli_server1
= cli
->cli
;
2651 struct cli_state
*cli_server2
= NULL
;
2652 struct rpc_pipe_client
*cli2
= NULL
;
2653 POLICY_HND hPrinter1
, hPrinter2
;
2658 printf("Usage: %s <printer> <server>\n", argv
[0]);
2662 fstrcpy( printername
, argv
[1] );
2664 fstr_sprintf( servername1
, cli
->cli
->desthost
);
2665 fstrcpy( servername2
, argv
[2] );
2666 strupper_m( servername1
);
2667 strupper_m( servername2
);
2669 /* first get the connection to the remote server */
2671 nt_status
= cli_full_connection(&cli_server2
, global_myname(), servername2
,
2674 get_cmdline_auth_info_username(),
2676 get_cmdline_auth_info_password(),
2677 get_cmdline_auth_info_use_kerberos() ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2678 get_cmdline_auth_info_signing_state(), NULL
);
2680 if ( !NT_STATUS_IS_OK(nt_status
) )
2681 return WERR_GENERAL_FAILURE
;
2683 cli2
= cli_rpc_pipe_open_noauth(cli_server2
, PI_SPOOLSS
, &nt_status
);
2685 printf("failed to open spoolss pipe on server %s (%s)\n",
2686 servername2
, nt_errstr(nt_status
));
2687 return WERR_GENERAL_FAILURE
;
2690 /* now open up both printers */
2692 printername_path
= talloc_asprintf(mem_ctx
,
2696 if (!printername_path
) {
2699 printf("Opening %s...", printername_path
);
2700 werror
= rpccli_spoolss_open_printer_ex( cli
, mem_ctx
, printername_path
,
2701 "", PRINTER_ALL_ACCESS
, servername1
, cli_server1
->user_name
, &hPrinter1
);
2702 if ( !W_ERROR_IS_OK(werror
) ) {
2703 printf("failed (%s)\n", dos_errstr(werror
));
2708 printername_path
= talloc_asprintf(mem_ctx
,
2712 if (!printername_path
) {
2715 printf("Opening %s...", printername_path
);
2716 werror
= rpccli_spoolss_open_printer_ex( cli2
, mem_ctx
, printername_path
,
2717 "", PRINTER_ALL_ACCESS
, servername2
, cli_server2
->user_name
, &hPrinter2
);
2718 if ( !W_ERROR_IS_OK(werror
) ) {
2719 printf("failed (%s)\n", dos_errstr(werror
));
2724 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2725 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2727 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2734 printf("Closing printers...");
2735 rpccli_spoolss_close_printer( cli
, mem_ctx
, &hPrinter1
);
2736 rpccli_spoolss_close_printer( cli2
, mem_ctx
, &hPrinter2
);
2739 /* close the second remote connection */
2741 cli_shutdown( cli_server2
);
2745 /* List of commands exported by this module */
2746 struct cmd_set spoolss_commands
[] = {
2750 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, PI_SPOOLSS
, NULL
, "Add a print driver", "" },
2751 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, PI_SPOOLSS
, NULL
, "Add a printer", "" },
2752 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, PI_SPOOLSS
, NULL
, "Delete a printer driver", "" },
2753 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, PI_SPOOLSS
, NULL
, "Delete a printer driver with files", "" },
2754 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, PI_SPOOLSS
, NULL
, "Enumerate printer data", "" },
2755 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, PI_SPOOLSS
, NULL
, "Enumerate printer data for a key", "" },
2756 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, PI_SPOOLSS
, NULL
, "Enumerate printer keys", "" },
2757 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, PI_SPOOLSS
, NULL
, "Enumerate print jobs", "" },
2758 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, PI_SPOOLSS
, NULL
, "Enumerate printer ports", "" },
2759 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, PI_SPOOLSS
, NULL
, "Enumerate installed printer drivers", "" },
2760 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, PI_SPOOLSS
, NULL
, "Enumerate printers", "" },
2761 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, PI_SPOOLSS
, NULL
, "Get print driver data", "" },
2762 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, PI_SPOOLSS
, NULL
, "Get printer driver data with keyname", ""},
2763 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, PI_SPOOLSS
, NULL
, "Get print driver information", "" },
2764 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, PI_SPOOLSS
, NULL
, "Get print driver upload directory", "" },
2765 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, PI_SPOOLSS
, NULL
, "Get printer info", "" },
2766 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, PI_SPOOLSS
, NULL
, "Open printer handle", "" },
2767 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, PI_SPOOLSS
, NULL
, "Set printer driver", "" },
2768 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, PI_SPOOLSS
, NULL
, "Get print processor directory", "" },
2769 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, PI_SPOOLSS
, NULL
, "Add form", "" },
2770 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, PI_SPOOLSS
, NULL
, "Set form", "" },
2771 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, PI_SPOOLSS
, NULL
, "Get form", "" },
2772 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, PI_SPOOLSS
, NULL
, "Delete form", "" },
2773 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, PI_SPOOLSS
, NULL
, "Enumerate forms", "" },
2774 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, PI_SPOOLSS
, NULL
, "Set printer comment", "" },
2775 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, PI_SPOOLSS
, NULL
, "Set printername", "" },
2776 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, PI_SPOOLSS
, NULL
, "Set REG_SZ printer data", "" },
2777 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, PI_SPOOLSS
, NULL
, "Rffpcnex test", "" },
2778 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, PI_SPOOLSS
, NULL
, "Printer comparison test", "" },