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
->desthost
);
113 strupper_m(servername
);
114 fstrcpy(user
, cli
->auth
->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
->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
->desthost
);
492 strupper_m(servername
);
493 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
494 fstrcpy(user
, cli
->auth
->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
->desthost
);
558 strupper_m(servername
);
559 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
560 fstrcpy(user
, cli
->auth
->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
->desthost
);
621 strupper_m(servername
);
622 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
623 fstrcpy(user
, cli
->auth
->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
->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
->auth
->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
->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
->auth
->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
->desthost
);
1003 strupper_m(servername
);
1004 fstrcpy(user
, cli
->auth
->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
)
1227 /* get the next token */
1228 ptr
= strtok_r(str
, delim
, &saveptr
);
1230 /* a string of 'NULL' is used to represent an empty
1231 parameter because two consecutive delimiters
1232 will not return an empty string. See man strtok(3)
1234 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0))
1238 init_unistr(dest
, ptr
);
1243 /********************************************************************************
1244 fill in the members of a DRIVER_INFO_3 struct using a character
1245 string in the form of
1246 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1247 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1248 <Default Data Type>:<Comma Separated list of Files>
1249 *******************************************************************************/
1250 static bool init_drv_info_3_members ( TALLOC_CTX
*mem_ctx
, DRIVER_INFO_3
*info
,
1255 char *saveptr
= NULL
;
1257 /* fill in the UNISTR fields */
1258 str
= get_driver_3_param (args
, ":", &info
->name
);
1259 str
= get_driver_3_param (NULL
, ":", &info
->driverpath
);
1260 str
= get_driver_3_param (NULL
, ":", &info
->datafile
);
1261 str
= get_driver_3_param (NULL
, ":", &info
->configfile
);
1262 str
= get_driver_3_param (NULL
, ":", &info
->helpfile
);
1263 str
= get_driver_3_param (NULL
, ":", &info
->monitorname
);
1264 str
= get_driver_3_param (NULL
, ":", &info
->defaultdatatype
);
1266 /* <Comma Separated List of Dependent Files> */
1267 str2
= get_driver_3_param (NULL
, ":", NULL
); /* save the beginning of the string */
1270 /* begin to strip out each filename */
1271 str
= strtok_r(str
, ",", &saveptr
);
1275 /* keep a cumlative count of the str lengths */
1276 len
+= strlen(str
)+1;
1277 str
= strtok_r(NULL
, ",", &saveptr
);
1280 /* allocate the space; add one extra slot for a terminating NULL.
1281 Each filename is NULL terminated and the end contains a double
1283 if ((info
->dependentfiles
=TALLOC_ARRAY(mem_ctx
, uint16
, len
+1)) == NULL
)
1285 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1288 for (i
=0; i
<len
; i
++)
1290 SSVAL(&info
->dependentfiles
[i
], 0, str2
[i
]);
1292 info
->dependentfiles
[len
] = '\0';
1298 /****************************************************************************
1299 ****************************************************************************/
1301 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1302 TALLOC_CTX
*mem_ctx
,
1303 int argc
, const char **argv
)
1307 PRINTER_DRIVER_CTR ctr
;
1308 DRIVER_INFO_3 info3
;
1310 fstring driver_name
;
1313 /* parse the command arguements */
1314 if (argc
!= 3 && argc
!= 4)
1316 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1317 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1318 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1319 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1320 printf ("\t[version]\n");
1325 /* Fill in the DRIVER_INFO_3 struct */
1327 if (!(arch
= cmd_spoolss_get_short_archi(argv
[1])))
1329 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1330 return WERR_INVALID_PARAM
;
1333 set_drv_info_3_env(&info3
, arch
);
1335 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1336 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1338 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1339 return WERR_INVALID_PARAM
;
1342 /* if printer driver version specified, override the default version
1343 * used by the architecture. This allows installation of Windows
1344 * 2000 (version 3) printer drivers. */
1347 info3
.version
= atoi(argv
[3]);
1352 result
= rpccli_spoolss_addprinterdriver (cli
, mem_ctx
, level
, &ctr
);
1354 if (W_ERROR_IS_OK(result
)) {
1355 rpcstr_pull(driver_name
, info3
.name
.buffer
,
1356 sizeof(driver_name
), -1, STR_TERMINATE
);
1357 printf ("Printer Driver %s successfully installed.\n",
1365 /****************************************************************************
1366 ****************************************************************************/
1368 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1369 TALLOC_CTX
*mem_ctx
,
1370 int argc
, const char **argv
)
1374 PRINTER_INFO_CTR ctr
;
1375 PRINTER_INFO_2 info2
;
1378 /* parse the command arguements */
1381 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1385 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1386 strupper_m(servername
);
1388 /* Fill in the DRIVER_INFO_2 struct */
1391 init_unistr( &info2
.printername
, argv
[1]);
1392 init_unistr( &info2
.sharename
, argv
[2]);
1393 init_unistr( &info2
.drivername
, argv
[3]);
1394 init_unistr( &info2
.portname
, argv
[4]);
1395 init_unistr( &info2
.comment
, "Created by rpcclient");
1396 init_unistr( &info2
.printprocessor
, "winprint");
1397 init_unistr( &info2
.datatype
, "RAW");
1398 info2
.devmode
= NULL
;
1399 info2
.secdesc
= NULL
;
1400 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1402 info2
.defaultpriority
= 0;
1403 info2
.starttime
= 0;
1404 info2
.untiltime
= 0;
1406 /* These three fields must not be used by AddPrinter()
1407 as defined in the MS Platform SDK documentation..
1411 info2.averageppm = 0;
1414 ctr
.printers_2
= &info2
;
1415 result
= rpccli_spoolss_addprinterex (cli
, mem_ctx
, level
, &ctr
);
1417 if (W_ERROR_IS_OK(result
))
1418 printf ("Printer %s successfully installed.\n", argv
[1]);
1423 /****************************************************************************
1424 ****************************************************************************/
1426 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1427 TALLOC_CTX
*mem_ctx
,
1428 int argc
, const char **argv
)
1433 bool opened_hnd
= False
;
1434 PRINTER_INFO_CTR ctr
;
1435 PRINTER_INFO_2 info2
;
1440 /* parse the command arguements */
1443 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1447 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1448 strupper_m(servername
);
1449 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
1450 fstrcpy(user
, cli
->auth
->user_name
);
1452 /* Get a printer handle */
1454 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1456 servername
, user
, &pol
);
1458 if (!W_ERROR_IS_OK(result
))
1463 /* Get printer info */
1465 ZERO_STRUCT (info2
);
1466 ctr
.printers_2
= &info2
;
1468 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, level
, &ctr
);
1470 if (!W_ERROR_IS_OK(result
)) {
1471 printf ("Unable to retrieve printer information!\n");
1475 /* Set the printer driver */
1477 init_unistr(&ctr
.printers_2
->drivername
, argv
[2]);
1479 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, level
, &ctr
, 0);
1481 if (!W_ERROR_IS_OK(result
)) {
1482 printf("SetPrinter call failed!\n");
1486 printf("Successfully set %s to driver %s.\n", argv
[1], argv
[2]);
1492 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
1498 /****************************************************************************
1499 ****************************************************************************/
1501 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1502 TALLOC_CTX
*mem_ctx
,
1503 int argc
, const char **argv
)
1505 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1510 const char *arch
= NULL
;
1512 /* parse the command arguements */
1513 if (argc
< 2 || argc
> 4) {
1514 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1521 vers
= atoi (argv
[3]);
1524 /* delete the driver for all architectures */
1525 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1527 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1530 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1533 /* make the call to remove the driver */
1534 result
= rpccli_spoolss_deleteprinterdriverex(
1535 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1], archi_table
[i
].version
);
1537 if ( !W_ERROR_IS_OK(result
) )
1539 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1540 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1541 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, dos_errstr(result
));
1546 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1547 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1556 /****************************************************************************
1557 ****************************************************************************/
1559 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1560 TALLOC_CTX
*mem_ctx
,
1561 int argc
, const char **argv
)
1563 WERROR result
= WERR_OK
;
1567 /* parse the command arguements */
1569 printf ("Usage: %s <driver>\n", argv
[0]);
1573 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1574 strupper_m(servername
);
1576 /* delete the driver for all architectures */
1577 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1578 /* make the call to remove the driver */
1579 result
= rpccli_spoolss_deleteprinterdriver(
1580 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1]);
1582 if ( !W_ERROR_IS_OK(result
) ) {
1583 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1584 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1585 argv
[1], archi_table
[i
].long_archi
,
1589 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1590 archi_table
[i
].long_archi
);
1597 /****************************************************************************
1598 ****************************************************************************/
1600 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1601 TALLOC_CTX
*mem_ctx
,
1602 int argc
, const char **argv
)
1605 char *servername
= NULL
, *environment
= NULL
;
1608 /* parse the command arguements */
1610 printf ("Usage: %s [environment]\n", argv
[0]);
1614 if (asprintf(&servername
, "\\\\%s", cli
->desthost
) < 0)
1616 strupper_m(servername
);
1618 if (asprintf(&environment
, "%s", (argc
== 2) ? argv
[1] :
1619 PRINTER_DRIVER_ARCHITECTURE
) < 0) {
1620 SAFE_FREE(servername
);
1624 result
= rpccli_spoolss_getprintprocessordirectory(
1625 cli
, mem_ctx
, servername
, environment
, procdir
);
1627 if (W_ERROR_IS_OK(result
))
1628 printf("%s\n", procdir
);
1630 SAFE_FREE(servername
);
1631 SAFE_FREE(environment
);
1636 /****************************************************************************
1637 ****************************************************************************/
1639 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1640 int argc
, const char **argv
)
1644 char *servername
= NULL
, *printername
= NULL
;
1646 bool got_handle
= False
;
1648 /* Parse the command arguements */
1651 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1655 /* Get a printer handle */
1657 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1658 strupper_m(servername
);
1659 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1661 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1663 servername
, cli
->auth
->user_name
,
1666 if (!W_ERROR_IS_OK(werror
))
1671 /* Dummy up some values for the form data */
1673 form
.flags
= FORM_USER
;
1674 form
.size_x
= form
.size_y
= 100;
1680 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1685 werror
= rpccli_spoolss_addform(cli
, mem_ctx
, &handle
, 1, &form
);
1689 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1691 SAFE_FREE(servername
);
1692 SAFE_FREE(printername
);
1697 /****************************************************************************
1698 ****************************************************************************/
1700 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1701 int argc
, const char **argv
)
1705 char *servername
= NULL
, *printername
= NULL
;
1707 bool got_handle
= False
;
1709 /* Parse the command arguements */
1712 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1716 /* Get a printer handle */
1718 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1719 strupper_m(servername
);
1720 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1722 werror
= rpccli_spoolss_open_printer_ex(
1723 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1724 servername
, cli
->auth
->user_name
, &handle
);
1726 if (!W_ERROR_IS_OK(werror
))
1731 /* Dummy up some values for the form data */
1733 form
.flags
= FORM_PRINTER
;
1734 form
.size_x
= form
.size_y
= 100;
1740 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1744 werror
= rpccli_spoolss_setform(cli
, mem_ctx
, &handle
, 1, argv
[2], &form
);
1748 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1750 SAFE_FREE(servername
);
1751 SAFE_FREE(printername
);
1756 /****************************************************************************
1757 ****************************************************************************/
1759 static const char *get_form_flag(int form_flag
)
1761 switch (form_flag
) {
1765 return "FORM_BUILTIN";
1767 return "FORM_PRINTER";
1773 /****************************************************************************
1774 ****************************************************************************/
1776 static void display_form(FORM_1
*form
)
1778 fstring form_name
= "";
1780 if (form
->name
.buffer
)
1781 rpcstr_pull(form_name
, form
->name
.buffer
,
1782 sizeof(form_name
), -1, STR_TERMINATE
);
1785 "\tflag: %s (%d)\n" \
1786 "\twidth: %d, length: %d\n" \
1787 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1788 form_name
, get_form_flag(form
->flag
), form
->flag
,
1789 form
->width
, form
->length
,
1790 form
->left
, form
->right
,
1791 form
->top
, form
->bottom
);
1794 /****************************************************************************
1795 ****************************************************************************/
1797 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1798 int argc
, const char **argv
)
1802 char *servername
= NULL
, *printername
= NULL
;
1804 bool got_handle
= False
;
1806 /* Parse the command arguements */
1809 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1813 /* Get a printer handle */
1815 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1816 strupper_m(servername
);
1817 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1819 werror
= rpccli_spoolss_open_printer_ex(
1820 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1821 servername
, cli
->auth
->user_name
, &handle
);
1823 if (!W_ERROR_IS_OK(werror
))
1830 werror
= rpccli_spoolss_getform(cli
, mem_ctx
, &handle
, argv
[2], 1, &form
);
1832 if (!W_ERROR_IS_OK(werror
))
1835 display_form(&form
);
1839 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1841 SAFE_FREE(servername
);
1842 SAFE_FREE(printername
);
1847 /****************************************************************************
1848 ****************************************************************************/
1850 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
1851 TALLOC_CTX
*mem_ctx
, int argc
,
1856 char *servername
= NULL
, *printername
= NULL
;
1857 bool got_handle
= False
;
1859 /* Parse the command arguements */
1862 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1866 /* Get a printer handle */
1868 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1869 strupper_m(servername
);
1870 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1872 werror
= rpccli_spoolss_open_printer_ex(
1873 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1874 servername
, cli
->auth
->user_name
, &handle
);
1876 if (!W_ERROR_IS_OK(werror
))
1881 /* Delete the form */
1883 werror
= rpccli_spoolss_deleteform(cli
, mem_ctx
, &handle
, argv
[2]);
1887 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1889 SAFE_FREE(servername
);
1890 SAFE_FREE(printername
);
1895 /****************************************************************************
1896 ****************************************************************************/
1898 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
1899 TALLOC_CTX
*mem_ctx
, int argc
,
1904 char *servername
= NULL
, *printername
= NULL
;
1905 bool got_handle
= False
;
1906 uint32 num_forms
, level
= 1, i
;
1909 /* Parse the command arguements */
1912 printf ("Usage: %s <printer>\n", argv
[0]);
1916 /* Get a printer handle */
1918 asprintf(&servername
, "\\\\%s", cli
->desthost
);
1919 strupper_m(servername
);
1920 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1922 werror
= rpccli_spoolss_open_printer_ex(
1923 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1924 servername
, cli
->auth
->user_name
, &handle
);
1926 if (!W_ERROR_IS_OK(werror
))
1931 /* Enumerate forms */
1933 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
, &handle
, level
, &num_forms
, &forms
);
1935 if (!W_ERROR_IS_OK(werror
))
1938 /* Display output */
1940 for (i
= 0; i
< num_forms
; i
++) {
1942 display_form(&forms
[i
]);
1948 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1950 SAFE_FREE(servername
);
1951 SAFE_FREE(printername
);
1956 /****************************************************************************
1957 ****************************************************************************/
1959 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
1960 TALLOC_CTX
*mem_ctx
,
1961 int argc
, const char **argv
)
1964 fstring servername
, printername
, user
;
1966 bool opened_hnd
= False
;
1967 PRINTER_INFO_CTR ctr
;
1968 PRINTER_INFO_0 info
;
1969 REGISTRY_VALUE value
;
1970 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1972 /* parse the command arguements */
1974 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
1975 " <value> <data>\n",
1977 result
= WERR_INVALID_PARAM
;
1981 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
1982 strupper_m(servername
);
1983 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1984 fstrcpy(user
, cli
->auth
->user_name
);
1986 value
.type
= REG_NONE
;
1988 if (strequal(argv
[2], "string")) {
1989 value
.type
= REG_SZ
;
1992 if (strequal(argv
[2], "binary")) {
1993 value
.type
= REG_BINARY
;
1996 if (strequal(argv
[2], "dword")) {
1997 value
.type
= REG_DWORD
;
2000 if (strequal(argv
[2], "multistring")) {
2001 value
.type
= REG_MULTI_SZ
;
2004 if (value
.type
== REG_NONE
) {
2005 printf("Unknown data type: %s\n", argv
[2]);
2006 result
= WERR_INVALID_PARAM
;
2010 /* get a printer handle */
2011 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
2012 MAXIMUM_ALLOWED_ACCESS
, servername
,
2014 if (!W_ERROR_IS_OK(result
))
2019 ctr
.printers_0
= &info
;
2021 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2023 if (!W_ERROR_IS_OK(result
))
2026 printf("%s\n", current_timestring(tmp_ctx
, True
));
2027 printf("\tchange_id (before set)\t:[0x%x]\n", info
.change_id
);
2029 /* Set the printer data */
2031 fstrcpy(value
.valuename
, argv
[3]);
2033 switch (value
.type
) {
2036 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2037 value
.size
= data
.uni_str_len
* 2;
2039 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, data
.buffer
,
2042 value
.data_p
= NULL
;
2047 uint32 data
= strtoul(argv
[4], NULL
, 10);
2048 value
.size
= sizeof(data
);
2050 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, &data
,
2053 value
.data_p
= NULL
;
2058 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2059 value
.data_p
= data
.data
;
2060 value
.size
= data
.length
;
2063 case REG_MULTI_SZ
: {
2068 for (i
=4; i
<argc
; i
++) {
2069 if (strcmp(argv
[i
], "NULL") == 0) {
2072 len
+= strlen(argv
[i
])+1;
2076 value
.data_p
= TALLOC_ARRAY(mem_ctx
, unsigned char, value
.size
);
2077 if (value
.data_p
== NULL
) {
2078 result
= WERR_NOMEM
;
2082 p
= (char *)value
.data_p
;
2084 for (i
=4; i
<argc
; i
++) {
2085 size_t l
= (strlen(argv
[i
])+1)*2;
2086 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2090 SMB_ASSERT(len
== 0);
2094 printf("Unknown data type: %s\n", argv
[2]);
2095 result
= WERR_INVALID_PARAM
;
2099 result
= rpccli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2101 if (!W_ERROR_IS_OK(result
)) {
2102 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2105 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2107 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2109 if (!W_ERROR_IS_OK(result
))
2112 printf("%s\n", current_timestring(tmp_ctx
, True
));
2113 printf("\tchange_id (after set)\t:[0x%x]\n", info
.change_id
);
2117 TALLOC_FREE(tmp_ctx
);
2119 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
2124 /****************************************************************************
2125 ****************************************************************************/
2127 static void display_job_info_1(JOB_INFO_1
*job
)
2129 fstring username
= "", document
= "", text_status
= "";
2131 rpcstr_pull(username
, job
->username
.buffer
,
2132 sizeof(username
), -1, STR_TERMINATE
);
2134 rpcstr_pull(document
, job
->document
.buffer
,
2135 sizeof(document
), -1, STR_TERMINATE
);
2137 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2138 sizeof(text_status
), -1, STR_TERMINATE
);
2140 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job
->position
, job
->jobid
,
2141 username
, document
, text_status
, job
->pagesprinted
,
2145 /****************************************************************************
2146 ****************************************************************************/
2148 static void display_job_info_2(JOB_INFO_2
*job
)
2150 fstring username
= "", document
= "", text_status
= "";
2152 rpcstr_pull(username
, job
->username
.buffer
,
2153 sizeof(username
), -1, STR_TERMINATE
);
2155 rpcstr_pull(document
, job
->document
.buffer
,
2156 sizeof(document
), -1, STR_TERMINATE
);
2158 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2159 sizeof(text_status
), -1, STR_TERMINATE
);
2161 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job
->position
, job
->jobid
,
2162 username
, document
, text_status
, job
->pagesprinted
,
2163 job
->totalpages
, job
->size
);
2166 /****************************************************************************
2167 ****************************************************************************/
2169 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2170 TALLOC_CTX
*mem_ctx
, int argc
,
2174 uint32 level
= 1, num_jobs
, i
;
2175 bool got_hnd
= False
;
2176 char *printername
= NULL
;
2177 fstring servername
, user
;
2181 if (argc
< 2 || argc
> 3) {
2182 printf("Usage: %s printername [level]\n", argv
[0]);
2187 level
= atoi(argv
[2]);
2189 /* Open printer handle */
2191 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2192 strupper_m(servername
);
2193 fstrcpy(user
, cli
->auth
->user_name
);
2194 printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\", cli
->desthost
);
2198 strupper_m(printername
);
2199 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2204 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2205 "", MAXIMUM_ALLOWED_ACCESS
,
2206 servername
, user
, &hnd
);
2208 if (!W_ERROR_IS_OK(result
))
2213 /* Enumerate ports */
2215 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2218 if (!W_ERROR_IS_OK(result
))
2221 for (i
= 0; i
< num_jobs
; i
++) {
2224 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2227 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2230 d_printf("unknown info level %d\n", level
);
2237 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2242 /****************************************************************************
2243 ****************************************************************************/
2245 static WERROR
cmd_spoolss_enum_data( struct rpc_pipe_client
*cli
,
2246 TALLOC_CTX
*mem_ctx
, int argc
,
2250 uint32 i
=0, val_needed
, data_needed
;
2251 bool got_hnd
= False
;
2252 char *printername
= NULL
;
2253 fstring servername
, user
;
2257 printf("Usage: %s printername\n", argv
[0]);
2261 /* Open printer handle */
2263 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2264 strupper_m(servername
);
2265 fstrcpy(user
, cli
->auth
->user_name
);
2266 printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\", cli
->desthost
);
2270 strupper_m(printername
);
2271 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2276 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2277 "", MAXIMUM_ALLOWED_ACCESS
,
2278 servername
, user
, &hnd
);
2280 if (!W_ERROR_IS_OK(result
))
2285 /* Enumerate data */
2287 result
= rpccli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2288 &val_needed
, &data_needed
,
2290 while (W_ERROR_IS_OK(result
)) {
2291 REGISTRY_VALUE value
;
2292 result
= rpccli_spoolss_enumprinterdata(
2293 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2294 data_needed
, 0, 0, &value
);
2295 if (W_ERROR_IS_OK(result
))
2296 display_reg_value(value
);
2298 if (W_ERROR_V(result
) == ERRnomoreitems
)
2299 result
= W_ERROR(ERRsuccess
);
2303 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2308 /****************************************************************************
2309 ****************************************************************************/
2311 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2312 TALLOC_CTX
*mem_ctx
, int argc
,
2317 bool got_hnd
= False
;
2318 char *printername
= NULL
;
2319 fstring servername
, user
;
2320 const char *keyname
= NULL
;
2322 REGVAL_CTR
*ctr
= NULL
;
2325 printf("Usage: %s printername <keyname>\n", argv
[0]);
2331 /* Open printer handle */
2333 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2334 strupper_m(servername
);
2335 fstrcpy(user
, cli
->auth
->user_name
);
2337 printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\", cli
->desthost
);
2341 strupper_m(printername
);
2342 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2347 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2348 "", MAXIMUM_ALLOWED_ACCESS
,
2349 servername
, user
, &hnd
);
2351 if (!W_ERROR_IS_OK(result
))
2356 /* Enumerate subkeys */
2358 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2361 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2363 if (!W_ERROR_IS_OK(result
))
2366 for (i
=0; i
< ctr
->num_values
; i
++) {
2367 display_reg_value(*(ctr
->values
[i
]));
2374 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2379 /****************************************************************************
2380 ****************************************************************************/
2382 static WERROR
cmd_spoolss_enum_printerkey( struct rpc_pipe_client
*cli
,
2383 TALLOC_CTX
*mem_ctx
, int argc
,
2387 bool got_hnd
= False
;
2388 char *printername
= NULL
;
2389 fstring servername
, user
;
2390 const char *keyname
= NULL
;
2392 uint16
*keylist
= NULL
, *curkey
;
2394 if (argc
< 2 || argc
> 3) {
2395 printf("Usage: %s printername [keyname]\n", argv
[0]);
2404 /* Open printer handle */
2406 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->desthost
);
2407 strupper_m(servername
);
2408 fstrcpy(user
, cli
->auth
->user_name
);
2410 printername
= talloc_asprintf(mem_ctx
, "\\\\%s\\", cli
->desthost
);
2414 strupper_m(printername
);
2415 printername
= talloc_asprintf_append(printername
, "%s", argv
[1]);
2421 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2422 "", MAXIMUM_ALLOWED_ACCESS
,
2423 servername
, user
, &hnd
);
2425 if (!W_ERROR_IS_OK(result
))
2430 /* Enumerate subkeys */
2432 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2434 if (!W_ERROR_IS_OK(result
))
2438 while (*curkey
!= 0) {
2439 char *subkey
= NULL
;
2440 rpcstr_pull_talloc(mem_ctx
, &subkey
, curkey
, -1,
2445 printf("%s\n", subkey
);
2446 curkey
+= strlen(subkey
) + 1;
2454 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2459 /****************************************************************************
2460 ****************************************************************************/
2462 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2463 TALLOC_CTX
*mem_ctx
, int argc
,
2466 fstring servername
, printername
;
2468 bool got_hnd
= False
;
2470 SPOOL_NOTIFY_OPTION option
;
2473 printf("Usage: %s printername\n", argv
[0]);
2480 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", cli
->desthost
);
2481 strupper_m(servername
);
2483 slprintf(printername
, sizeof(printername
) - 1, "\\\\%s\\%s",
2484 cli
->desthost
, argv
[1]);
2485 strupper_m(printername
);
2487 result
= rpccli_spoolss_open_printer_ex(
2488 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
2489 servername
, cli
->auth
->user_name
, &hnd
);
2491 if (!W_ERROR_IS_OK(result
)) {
2492 printf("Error opening %s\n", argv
[1]);
2498 /* Create spool options */
2500 ZERO_STRUCT(option
);
2503 option
.option_type_ptr
= 1;
2504 option
.count
= option
.ctr
.count
= 2;
2506 option
.ctr
.type
= TALLOC_ARRAY(mem_ctx
, SPOOL_NOTIFY_OPTION_TYPE
, 2);
2507 if (option
.ctr
.type
== NULL
) {
2508 result
= WERR_NOMEM
;
2512 ZERO_STRUCT(option
.ctr
.type
[0]);
2513 option
.ctr
.type
[0].type
= PRINTER_NOTIFY_TYPE
;
2514 option
.ctr
.type
[0].count
= option
.ctr
.type
[0].count2
= 1;
2515 option
.ctr
.type
[0].fields_ptr
= 1;
2516 option
.ctr
.type
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2518 ZERO_STRUCT(option
.ctr
.type
[1]);
2519 option
.ctr
.type
[1].type
= JOB_NOTIFY_TYPE
;
2520 option
.ctr
.type
[1].count
= option
.ctr
.type
[1].count2
= 1;
2521 option
.ctr
.type
[1].fields_ptr
= 1;
2522 option
.ctr
.type
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2526 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", myhostname());
2527 strupper_m(servername
);
2529 result
= rpccli_spoolss_rffpcnex(
2530 cli
, mem_ctx
, &hnd
, 0, 0, servername
, 123, &option
);
2532 if (!W_ERROR_IS_OK(result
)) {
2533 printf("Error rffpcnex %s\n", argv
[1]);
2539 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2544 /****************************************************************************
2545 ****************************************************************************/
2547 static bool compare_printer( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2548 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2550 PRINTER_INFO_CTR ctr1
, ctr2
;
2552 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2554 printf("Retrieving printer propertiesfor %s...", cli1
->desthost
);
2555 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 2, &ctr1
);
2556 if ( !W_ERROR_IS_OK(werror
) ) {
2557 printf("failed (%s)\n", dos_errstr(werror
));
2558 talloc_destroy(mem_ctx
);
2563 printf("Retrieving printer properties for %s...", cli2
->desthost
);
2564 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 2, &ctr2
);
2565 if ( !W_ERROR_IS_OK(werror
) ) {
2566 printf("failed (%s)\n", dos_errstr(werror
));
2567 talloc_destroy(mem_ctx
);
2572 talloc_destroy(mem_ctx
);
2577 /****************************************************************************
2578 ****************************************************************************/
2580 static bool compare_printer_secdesc( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2581 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2583 PRINTER_INFO_CTR ctr1
, ctr2
;
2585 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2586 SEC_DESC
*sd1
, *sd2
;
2590 printf("Retrieving printer security for %s...", cli1
->desthost
);
2591 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 3, &ctr1
);
2592 if ( !W_ERROR_IS_OK(werror
) ) {
2593 printf("failed (%s)\n", dos_errstr(werror
));
2599 printf("Retrieving printer security for %s...", cli2
->desthost
);
2600 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 3, &ctr2
);
2601 if ( !W_ERROR_IS_OK(werror
) ) {
2602 printf("failed (%s)\n", dos_errstr(werror
));
2611 if ( (ctr1
.printers_3
!= ctr2
.printers_3
) && (!ctr1
.printers_3
|| !ctr2
.printers_3
) ) {
2612 printf("NULL PRINTER_INFO_3!\n");
2617 sd1
= ctr1
.printers_3
->secdesc
;
2618 sd2
= ctr2
.printers_3
->secdesc
;
2620 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2621 printf("NULL secdesc!\n");
2626 if (!sec_desc_equal( sd1
, sd2
) ) {
2627 printf("Security Descriptors *not* equal!\n");
2632 printf("Security descriptors match\n");
2635 talloc_destroy(mem_ctx
);
2640 /****************************************************************************
2641 ****************************************************************************/
2643 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
2644 TALLOC_CTX
*mem_ctx
, int argc
,
2647 fstring printername
, servername1
, servername2
;
2648 char *printername_path
= NULL
;
2649 struct cli_state
*cli_server1
= rpc_pipe_np_smb_conn(cli
);
2650 struct cli_state
*cli_server2
= NULL
;
2651 struct rpc_pipe_client
*cli2
= NULL
;
2652 POLICY_HND hPrinter1
, hPrinter2
;
2657 printf("Usage: %s <printer> <server>\n", argv
[0]);
2661 fstrcpy( printername
, argv
[1] );
2663 fstrcpy( servername1
, cli
->desthost
);
2664 fstrcpy( servername2
, argv
[2] );
2665 strupper_m( servername1
);
2666 strupper_m( servername2
);
2668 /* first get the connection to the remote server */
2670 nt_status
= cli_full_connection(&cli_server2
, global_myname(), servername2
,
2673 get_cmdline_auth_info_username(),
2675 get_cmdline_auth_info_password(),
2676 get_cmdline_auth_info_use_kerberos() ? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2677 get_cmdline_auth_info_signing_state(), NULL
);
2679 if ( !NT_STATUS_IS_OK(nt_status
) )
2680 return WERR_GENERAL_FAILURE
;
2682 cli2
= cli_rpc_pipe_open_noauth(cli_server2
, PI_SPOOLSS
, &nt_status
);
2684 printf("failed to open spoolss pipe on server %s (%s)\n",
2685 servername2
, nt_errstr(nt_status
));
2686 return WERR_GENERAL_FAILURE
;
2689 /* now open up both printers */
2691 printername_path
= talloc_asprintf(mem_ctx
,
2695 if (!printername_path
) {
2698 printf("Opening %s...", printername_path
);
2699 werror
= rpccli_spoolss_open_printer_ex( cli
, mem_ctx
, printername_path
,
2700 "", PRINTER_ALL_ACCESS
, servername1
, cli_server1
->user_name
, &hPrinter1
);
2701 if ( !W_ERROR_IS_OK(werror
) ) {
2702 printf("failed (%s)\n", dos_errstr(werror
));
2707 printername_path
= talloc_asprintf(mem_ctx
,
2711 if (!printername_path
) {
2714 printf("Opening %s...", printername_path
);
2715 werror
= rpccli_spoolss_open_printer_ex( cli2
, mem_ctx
, printername_path
,
2716 "", PRINTER_ALL_ACCESS
, servername2
, cli_server2
->user_name
, &hPrinter2
);
2717 if ( !W_ERROR_IS_OK(werror
) ) {
2718 printf("failed (%s)\n", dos_errstr(werror
));
2723 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2724 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2726 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2733 printf("Closing printers...");
2734 rpccli_spoolss_close_printer( cli
, mem_ctx
, &hPrinter1
);
2735 rpccli_spoolss_close_printer( cli2
, mem_ctx
, &hPrinter2
);
2738 /* close the second remote connection */
2740 cli_shutdown( cli_server2
);
2744 /* List of commands exported by this module */
2745 struct cmd_set spoolss_commands
[] = {
2749 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, PI_SPOOLSS
, NULL
, "Add a print driver", "" },
2750 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, PI_SPOOLSS
, NULL
, "Add a printer", "" },
2751 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, PI_SPOOLSS
, NULL
, "Delete a printer driver", "" },
2752 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, PI_SPOOLSS
, NULL
, "Delete a printer driver with files", "" },
2753 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, PI_SPOOLSS
, NULL
, "Enumerate printer data", "" },
2754 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, PI_SPOOLSS
, NULL
, "Enumerate printer data for a key", "" },
2755 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, PI_SPOOLSS
, NULL
, "Enumerate printer keys", "" },
2756 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, PI_SPOOLSS
, NULL
, "Enumerate print jobs", "" },
2757 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, PI_SPOOLSS
, NULL
, "Enumerate printer ports", "" },
2758 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, PI_SPOOLSS
, NULL
, "Enumerate installed printer drivers", "" },
2759 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, PI_SPOOLSS
, NULL
, "Enumerate printers", "" },
2760 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, PI_SPOOLSS
, NULL
, "Get print driver data", "" },
2761 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, PI_SPOOLSS
, NULL
, "Get printer driver data with keyname", ""},
2762 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, PI_SPOOLSS
, NULL
, "Get print driver information", "" },
2763 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, PI_SPOOLSS
, NULL
, "Get print driver upload directory", "" },
2764 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, PI_SPOOLSS
, NULL
, "Get printer info", "" },
2765 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, PI_SPOOLSS
, NULL
, "Open printer handle", "" },
2766 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, PI_SPOOLSS
, NULL
, "Set printer driver", "" },
2767 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, PI_SPOOLSS
, NULL
, "Get print processor directory", "" },
2768 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, PI_SPOOLSS
, NULL
, "Add form", "" },
2769 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, PI_SPOOLSS
, NULL
, "Set form", "" },
2770 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, PI_SPOOLSS
, NULL
, "Get form", "" },
2771 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, PI_SPOOLSS
, NULL
, "Delete form", "" },
2772 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, PI_SPOOLSS
, NULL
, "Enumerate forms", "" },
2773 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, PI_SPOOLSS
, NULL
, "Set printer comment", "" },
2774 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, PI_SPOOLSS
, NULL
, "Set printername", "" },
2775 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, PI_SPOOLSS
, NULL
, "Set REG_SZ printer data", "" },
2776 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, PI_SPOOLSS
, NULL
, "Rffpcnex test", "" },
2777 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, PI_SPOOLSS
, NULL
, "Printer comparison test", "" },