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 2 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, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "rpcclient.h"
29 const char *long_archi
;
30 const char *short_archi
;
34 /* The version int is used by getdrivers. Note that
35 all architecture strings that support mutliple
36 versions must be grouped together since enumdrivers
37 uses this property to prevent issuing multiple
38 enumdriver calls for the same arch */
41 static const struct table_node archi_table
[]= {
43 {"Windows 4.0", "WIN40", 0 },
44 {"Windows NT x86", "W32X86", 2 },
45 {"Windows NT x86", "W32X86", 3 },
46 {"Windows NT R4000", "W32MIPS", 2 },
47 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
48 {"Windows NT PowerPC", "W32PPC", 2 },
49 {"Windows IA64", "IA64", 3 },
50 {"Windows x64", "x64", 3 },
57 * rpcclient module for SPOOLSS rpc pipe.
59 * This generally just parses and checks command lines, and then calls
60 * a cli_spoolss function.
63 /****************************************************************************
64 function to do the mapping between the long architecture name and
66 ****************************************************************************/
68 static const char *cmd_spoolss_get_short_archi(const char *long_archi
)
72 DEBUG(107,("Getting architecture dependant directory\n"));
75 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
76 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
78 if (archi_table
[i
].long_archi
==NULL
) {
79 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
83 /* this might be client code - but shouldn't this be an fstrcpy etc? */
86 DEBUGADD(108,("index: [%d]\n", i
));
87 DEBUGADD(108,("long architecture: [%s]\n", archi_table
[i
].long_archi
));
88 DEBUGADD(108,("short architecture: [%s]\n", archi_table
[i
].short_archi
));
90 return archi_table
[i
].short_archi
;
93 /****************************************************************************
94 ****************************************************************************/
96 static WERROR
cmd_spoolss_open_printer_ex(struct rpc_pipe_client
*cli
,
98 int argc
, const char **argv
)
102 fstring servername
, user
;
106 printf("Usage: %s <printername>\n", argv
[0]);
111 return WERR_GENERAL_FAILURE
;
113 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
114 strupper_m(servername
);
115 fstrcpy(user
, cli
->user_name
);
116 fstrcpy(printername
, argv
[1]);
118 /* Open the printer handle */
120 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
121 "", PRINTER_ALL_ACCESS
,
122 servername
, user
, &hnd
);
124 if (W_ERROR_IS_OK(werror
)) {
125 printf("Printer %s opened successfully\n", printername
);
126 werror
= rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
128 if (!W_ERROR_IS_OK(werror
)) {
129 printf("Error closing printer handle! (%s)\n",
130 get_dos_error_msg(werror
));
138 /****************************************************************************
139 ****************************************************************************/
141 static void display_print_info_0(PRINTER_INFO_0
*i0
)
144 fstring servername
= "";
149 rpcstr_pull(name
, i0
->printername
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
151 rpcstr_pull(servername
, i0
->servername
.buffer
, sizeof(servername
), -1,STR_TERMINATE
);
153 printf("\tprintername:[%s]\n", name
);
154 printf("\tservername:[%s]\n", servername
);
155 printf("\tcjobs:[0x%x]\n", i0
->cjobs
);
156 printf("\ttotal_jobs:[0x%x]\n", i0
->total_jobs
);
158 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0
->year
, i0
->month
,
159 i0
->day
, i0
->dayofweek
);
160 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0
->hour
, i0
->minute
,
161 i0
->second
, i0
->milliseconds
);
163 printf("\tglobal_counter:[0x%x]\n", i0
->global_counter
);
164 printf("\ttotal_pages:[0x%x]\n", i0
->total_pages
);
166 printf("\tmajorversion:[0x%x]\n", i0
->major_version
);
167 printf("\tbuildversion:[0x%x]\n", i0
->build_version
);
169 printf("\tunknown7:[0x%x]\n", i0
->unknown7
);
170 printf("\tunknown8:[0x%x]\n", i0
->unknown8
);
171 printf("\tunknown9:[0x%x]\n", i0
->unknown9
);
172 printf("\tsession_counter:[0x%x]\n", i0
->session_counter
);
173 printf("\tunknown11:[0x%x]\n", i0
->unknown11
);
174 printf("\tprinter_errors:[0x%x]\n", i0
->printer_errors
);
175 printf("\tunknown13:[0x%x]\n", i0
->unknown13
);
176 printf("\tunknown14:[0x%x]\n", i0
->unknown14
);
177 printf("\tunknown15:[0x%x]\n", i0
->unknown15
);
178 printf("\tunknown16:[0x%x]\n", i0
->unknown16
);
179 printf("\tchange_id:[0x%x]\n", i0
->change_id
);
180 printf("\tunknown18:[0x%x]\n", i0
->unknown18
);
181 printf("\tstatus:[0x%x]\n", i0
->status
);
182 printf("\tunknown20:[0x%x]\n", i0
->unknown20
);
183 printf("\tc_setprinter:[0x%x]\n", i0
->c_setprinter
);
184 printf("\tunknown22:[0x%x]\n", i0
->unknown22
);
185 printf("\tunknown23:[0x%x]\n", i0
->unknown23
);
186 printf("\tunknown24:[0x%x]\n", i0
->unknown24
);
187 printf("\tunknown25:[0x%x]\n", i0
->unknown25
);
188 printf("\tunknown26:[0x%x]\n", i0
->unknown26
);
189 printf("\tunknown27:[0x%x]\n", i0
->unknown27
);
190 printf("\tunknown28:[0x%x]\n", i0
->unknown28
);
191 printf("\tunknown29:[0x%x]\n", i0
->unknown29
);
196 /****************************************************************************
197 ****************************************************************************/
199 static void display_print_info_1(PRINTER_INFO_1
*i1
)
205 rpcstr_pull(desc
, i1
->description
.buffer
, sizeof(desc
), -1,
208 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
209 rpcstr_pull(comm
, i1
->comment
.buffer
, sizeof(comm
), -1, STR_TERMINATE
);
211 printf("\tflags:[0x%x]\n", i1
->flags
);
212 printf("\tname:[%s]\n", name
);
213 printf("\tdescription:[%s]\n", desc
);
214 printf("\tcomment:[%s]\n", comm
);
219 /****************************************************************************
220 ****************************************************************************/
222 static void display_print_info_2(PRINTER_INFO_2
*i2
)
224 fstring servername
= "";
225 fstring printername
= "";
226 fstring sharename
= "";
227 fstring portname
= "";
228 fstring drivername
= "";
229 fstring comment
= "";
230 fstring location
= "";
231 fstring sepfile
= "";
232 fstring printprocessor
= "";
233 fstring datatype
= "";
234 fstring parameters
= "";
236 rpcstr_pull(servername
, i2
->servername
.buffer
,sizeof(servername
), -1, STR_TERMINATE
);
237 rpcstr_pull(printername
, i2
->printername
.buffer
,sizeof(printername
), -1, STR_TERMINATE
);
238 rpcstr_pull(sharename
, i2
->sharename
.buffer
,sizeof(sharename
), -1, STR_TERMINATE
);
239 rpcstr_pull(portname
, i2
->portname
.buffer
,sizeof(portname
), -1, STR_TERMINATE
);
240 rpcstr_pull(drivername
, i2
->drivername
.buffer
,sizeof(drivername
), -1, STR_TERMINATE
);
241 rpcstr_pull(comment
, i2
->comment
.buffer
,sizeof(comment
), -1, STR_TERMINATE
);
242 rpcstr_pull(location
, i2
->location
.buffer
,sizeof(location
), -1, STR_TERMINATE
);
243 rpcstr_pull(sepfile
, i2
->sepfile
.buffer
,sizeof(sepfile
), -1, STR_TERMINATE
);
244 rpcstr_pull(printprocessor
, i2
->printprocessor
.buffer
,sizeof(printprocessor
), -1, STR_TERMINATE
);
245 rpcstr_pull(datatype
, i2
->datatype
.buffer
,sizeof(datatype
), -1, STR_TERMINATE
);
246 rpcstr_pull(parameters
, i2
->parameters
.buffer
,sizeof(parameters
), -1, STR_TERMINATE
);
248 printf("\tservername:[%s]\n", servername
);
249 printf("\tprintername:[%s]\n", printername
);
250 printf("\tsharename:[%s]\n", sharename
);
251 printf("\tportname:[%s]\n", portname
);
252 printf("\tdrivername:[%s]\n", drivername
);
253 printf("\tcomment:[%s]\n", comment
);
254 printf("\tlocation:[%s]\n", location
);
255 printf("\tsepfile:[%s]\n", sepfile
);
256 printf("\tprintprocessor:[%s]\n", printprocessor
);
257 printf("\tdatatype:[%s]\n", datatype
);
258 printf("\tparameters:[%s]\n", parameters
);
259 printf("\tattributes:[0x%x]\n", i2
->attributes
);
260 printf("\tpriority:[0x%x]\n", i2
->priority
);
261 printf("\tdefaultpriority:[0x%x]\n", i2
->defaultpriority
);
262 printf("\tstarttime:[0x%x]\n", i2
->starttime
);
263 printf("\tuntiltime:[0x%x]\n", i2
->untiltime
);
264 printf("\tstatus:[0x%x]\n", i2
->status
);
265 printf("\tcjobs:[0x%x]\n", i2
->cjobs
);
266 printf("\taverageppm:[0x%x]\n", i2
->averageppm
);
269 display_sec_desc(i2
->secdesc
);
274 /****************************************************************************
275 ****************************************************************************/
277 static void display_print_info_3(PRINTER_INFO_3
*i3
)
279 printf("\tflags:[0x%x]\n", i3
->flags
);
281 display_sec_desc(i3
->secdesc
);
286 /****************************************************************************
287 ****************************************************************************/
289 static void display_print_info_7(PRINTER_INFO_7
*i7
)
292 rpcstr_pull(guid
, i7
->guid
.buffer
,sizeof(guid
), -1, STR_TERMINATE
);
293 printf("\tguid:[%s]\n", guid
);
294 printf("\taction:[0x%x]\n", i7
->action
);
298 /****************************************************************************
299 ****************************************************************************/
301 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
303 int argc
, const char **argv
)
306 uint32 info_level
= 1;
307 PRINTER_INFO_CTR ctr
;
308 uint32 i
= 0, num_printers
;
313 printf("Usage: %s [level] [name]\n", argv
[0]);
318 info_level
= atoi(argv
[1]);
321 fstrcpy(name
, argv
[2]);
323 slprintf(name
, sizeof(name
)-1, "\\\\%s", cli
->cli
->desthost
);
329 result
= rpccli_spoolss_enum_printers(cli
, mem_ctx
, name
, PRINTER_ENUM_LOCAL
,
330 info_level
, &num_printers
, &ctr
);
332 if (W_ERROR_IS_OK(result
)) {
335 printf ("No printers returned.\n");
339 for (i
= 0; i
< num_printers
; i
++) {
342 display_print_info_0(&ctr
.printers_0
[i
]);
345 display_print_info_1(&ctr
.printers_1
[i
]);
348 display_print_info_2(&ctr
.printers_2
[i
]);
351 display_print_info_3(&ctr
.printers_3
[i
]);
354 printf("unknown info level %d\n", info_level
);
364 /****************************************************************************
365 ****************************************************************************/
367 static void display_port_info_1(PORT_INFO_1
*i1
)
371 rpcstr_pull(buffer
, i1
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
372 printf("\tPort Name:\t[%s]\n", buffer
);
375 /****************************************************************************
376 ****************************************************************************/
378 static void display_port_info_2(PORT_INFO_2
*i2
)
382 rpcstr_pull(buffer
, i2
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
383 printf("\tPort Name:\t[%s]\n", buffer
);
384 rpcstr_pull(buffer
, i2
->monitor_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
386 printf("\tMonitor Name:\t[%s]\n", buffer
);
387 rpcstr_pull(buffer
, i2
->description
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
389 printf("\tDescription:\t[%s]\n", buffer
);
390 printf("\tPort Type:\t" );
391 if ( i2
->port_type
) {
392 int comma
= 0; /* hack */
394 if ( i2
->port_type
& PORT_TYPE_READ
) {
398 if ( i2
->port_type
& PORT_TYPE_WRITE
) {
399 printf( "%sWrite", comma
? ", " : "" );
402 /* These two have slightly different interpretations
403 on 95/98/ME but I'm disregarding that for now */
404 if ( i2
->port_type
& PORT_TYPE_REDIRECTED
) {
405 printf( "%sRedirected", comma
? ", " : "" );
408 if ( i2
->port_type
& PORT_TYPE_NET_ATTACHED
) {
409 printf( "%sNet-Attached", comma
? ", " : "" );
413 printf( "[Unset]\n" );
415 printf("\tReserved:\t[%d]\n", i2
->reserved
);
419 /****************************************************************************
420 ****************************************************************************/
422 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
423 TALLOC_CTX
*mem_ctx
, int argc
,
427 uint32 info_level
= 1;
432 printf("Usage: %s [level]\n", argv
[0]);
437 info_level
= atoi(argv
[1]);
439 /* Enumerate ports */
443 result
= rpccli_spoolss_enum_ports(cli
, mem_ctx
, info_level
, &returned
, &ctr
);
445 if (W_ERROR_IS_OK(result
)) {
448 for (i
= 0; i
< returned
; i
++) {
449 switch (info_level
) {
451 display_port_info_1(&ctr
.port
.info_1
[i
]);
454 display_port_info_2(&ctr
.port
.info_2
[i
]);
457 printf("unknown info level %d\n", info_level
);
466 /****************************************************************************
467 ****************************************************************************/
469 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
471 int argc
, const char **argv
)
475 uint32 info_level
= 2;
476 BOOL opened_hnd
= False
;
477 PRINTER_INFO_CTR ctr
;
483 if (argc
== 1 || argc
> 3) {
484 printf("Usage: %s printername comment\n", argv
[0]);
489 /* Open a printer handle */
491 fstrcpy(comment
, argv
[2]);
494 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
495 strupper_m(servername
);
496 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
497 fstrcpy(user
, cli
->user_name
);
499 /* get a printer handle */
500 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
501 PRINTER_ALL_ACCESS
, servername
,
504 if (!W_ERROR_IS_OK(result
))
509 /* Get printer info */
510 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
512 if (!W_ERROR_IS_OK(result
))
516 /* Modify the comment. */
517 init_unistr(&ctr
.printers_2
->comment
, comment
);
518 ctr
.printers_2
->devmode
= NULL
;
519 ctr
.printers_2
->secdesc
= NULL
;
521 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
, 0);
522 if (W_ERROR_IS_OK(result
))
523 printf("Success in setting comment.\n");
527 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
532 /****************************************************************************
533 ****************************************************************************/
535 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
537 int argc
, const char **argv
)
541 uint32 info_level
= 2;
542 BOOL opened_hnd
= False
;
543 PRINTER_INFO_CTR ctr
;
549 if (argc
== 1 || argc
> 3) {
550 printf("Usage: %s printername new_printername\n", argv
[0]);
555 /* Open a printer handle */
557 fstrcpy(new_printername
, argv
[2]);
560 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
561 strupper_m(servername
);
562 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
563 fstrcpy(user
, cli
->user_name
);
565 /* get a printer handle */
566 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
567 PRINTER_ALL_ACCESS
, servername
,
570 if (!W_ERROR_IS_OK(result
))
575 /* Get printer info */
576 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
578 if (!W_ERROR_IS_OK(result
))
581 /* Modify the printername. */
582 init_unistr(&ctr
.printers_2
->printername
, new_printername
);
583 ctr
.printers_2
->devmode
= NULL
;
584 ctr
.printers_2
->secdesc
= NULL
;
586 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
, 0);
587 if (W_ERROR_IS_OK(result
))
588 printf("Success in setting printername.\n");
592 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
597 /****************************************************************************
598 ****************************************************************************/
600 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
602 int argc
, const char **argv
)
606 uint32 info_level
= 1;
607 BOOL opened_hnd
= False
;
608 PRINTER_INFO_CTR ctr
;
613 if (argc
== 1 || argc
> 3) {
614 printf("Usage: %s <printername> [level]\n", argv
[0]);
618 /* Open a printer handle */
620 info_level
= atoi(argv
[2]);
623 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
624 strupper_m(servername
);
625 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
626 fstrcpy(user
, cli
->user_name
);
628 /* get a printer handle */
630 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
631 "", MAXIMUM_ALLOWED_ACCESS
,
632 servername
, user
, &pol
);
634 if (!W_ERROR_IS_OK(result
))
639 /* Get printer info */
641 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
643 if (!W_ERROR_IS_OK(result
))
646 /* Display printer info */
648 switch (info_level
) {
650 display_print_info_0(ctr
.printers_0
);
653 display_print_info_1(ctr
.printers_1
);
656 display_print_info_2(ctr
.printers_2
);
659 display_print_info_3(ctr
.printers_3
);
662 display_print_info_7(ctr
.printers_7
);
665 printf("unknown info level %d\n", info_level
);
671 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
676 /****************************************************************************
677 ****************************************************************************/
679 static void display_reg_value(REGISTRY_VALUE value
)
685 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
686 *((uint32
*) value
.data_p
));
689 rpcstr_pull(text
, value
.data_p
, sizeof(text
), value
.size
,
691 printf("%s: REG_SZ: %s\n", value
.valuename
, 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 uint16
*curstr
= (uint16
*) value
.data_p
;
713 uint8
*start
= value
.data_p
;
714 printf("%s: REG_MULTI_SZ:\n", value
.valuename
);
715 while (((uint8
*) curstr
< start
+ value
.size
)) {
716 rpcstr_pull(text
, curstr
, sizeof(text
), -1,
718 printf(" %s\n", *text
!= 0 ? text
: "NULL");
719 curstr
+= strlen(text
) + 1;
724 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
729 /****************************************************************************
730 ****************************************************************************/
732 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
734 int argc
, const char **argv
)
738 BOOL opened_hnd
= False
;
742 const char *valuename
;
743 REGISTRY_VALUE value
;
746 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
747 printf("<printername> of . queries print server\n");
752 /* Open a printer handle */
754 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
755 strupper_m(servername
);
756 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
757 fstrcpy(printername
, servername
);
759 slprintf(printername
, sizeof(servername
)-1, "%s\\%s",
760 servername
, argv
[1]);
761 fstrcpy(user
, cli
->user_name
);
763 /* get a printer handle */
765 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
766 "", MAXIMUM_ALLOWED_ACCESS
,
767 servername
, user
, &pol
);
769 if (!W_ERROR_IS_OK(result
))
774 /* Get printer info */
776 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
778 if (!W_ERROR_IS_OK(result
))
781 /* Display printer data */
783 fstrcpy(value
.valuename
, valuename
);
784 display_reg_value(value
);
789 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
794 /****************************************************************************
795 ****************************************************************************/
797 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
799 int argc
, const char **argv
)
803 BOOL opened_hnd
= False
;
807 const char *valuename
, *keyname
;
808 REGISTRY_VALUE value
;
811 printf("Usage: %s <printername> <keyname> <valuename>\n",
813 printf("<printername> of . queries print server\n");
819 /* Open a printer handle */
821 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
822 strupper_m(servername
);
823 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
824 fstrcpy(printername
, servername
);
826 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
827 servername
, argv
[1]);
828 fstrcpy(user
, cli
->user_name
);
830 /* get a printer handle */
832 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
833 "", MAXIMUM_ALLOWED_ACCESS
,
834 servername
, user
, &pol
);
836 if (!W_ERROR_IS_OK(result
))
841 /* Get printer info */
843 result
= rpccli_spoolss_getprinterdataex(cli
, mem_ctx
, &pol
, keyname
,
846 if (!W_ERROR_IS_OK(result
))
849 /* Display printer data */
851 fstrcpy(value
.valuename
, valuename
);
852 display_reg_value(value
);
857 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
862 /****************************************************************************
863 ****************************************************************************/
865 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
871 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
873 printf ("Printer Driver Info 1:\n");
874 printf ("\tDriver Name: [%s]\n\n", name
);
879 /****************************************************************************
880 ****************************************************************************/
882 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
885 fstring architecture
;
892 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
893 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
894 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
895 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
896 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
898 printf ("Printer Driver Info 2:\n");
899 printf ("\tVersion: [%x]\n", i1
->version
);
900 printf ("\tDriver Name: [%s]\n", name
);
901 printf ("\tArchitecture: [%s]\n", architecture
);
902 printf ("\tDriver Path: [%s]\n", driverpath
);
903 printf ("\tDatafile: [%s]\n", datafile
);
904 printf ("\tConfigfile: [%s]\n\n", configfile
);
909 /****************************************************************************
910 ****************************************************************************/
912 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
915 fstring architecture
= "";
916 fstring driverpath
= "";
917 fstring datafile
= "";
918 fstring configfile
= "";
919 fstring helpfile
= "";
920 fstring dependentfiles
= "";
921 fstring monitorname
= "";
922 fstring defaultdatatype
= "";
930 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
931 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
932 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
933 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
934 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
935 rpcstr_pull(helpfile
, i1
->helpfile
.buffer
, sizeof(helpfile
), -1, STR_TERMINATE
);
936 rpcstr_pull(monitorname
, i1
->monitorname
.buffer
, sizeof(monitorname
), -1, STR_TERMINATE
);
937 rpcstr_pull(defaultdatatype
, i1
->defaultdatatype
.buffer
, sizeof(defaultdatatype
), -1, STR_TERMINATE
);
939 printf ("Printer Driver Info 3:\n");
940 printf ("\tVersion: [%x]\n", i1
->version
);
941 printf ("\tDriver Name: [%s]\n",name
);
942 printf ("\tArchitecture: [%s]\n", architecture
);
943 printf ("\tDriver Path: [%s]\n", driverpath
);
944 printf ("\tDatafile: [%s]\n", datafile
);
945 printf ("\tConfigfile: [%s]\n", configfile
);
946 printf ("\tHelpfile: [%s]\n\n", helpfile
);
950 rpcstr_pull(dependentfiles
, i1
->dependentfiles
+length
, sizeof(dependentfiles
), -1, STR_TERMINATE
);
952 length
+=strlen(dependentfiles
)+1;
954 if (strlen(dependentfiles
) > 0)
956 printf ("\tDependentfiles: [%s]\n", dependentfiles
);
966 printf ("\tMonitorname: [%s]\n", monitorname
);
967 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
972 /****************************************************************************
973 ****************************************************************************/
975 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
977 int argc
, const char **argv
)
981 uint32 info_level
= 3;
982 BOOL opened_hnd
= False
;
983 PRINTER_DRIVER_CTR ctr
;
988 BOOL success
= False
;
990 if ((argc
== 1) || (argc
> 3))
992 printf("Usage: %s <printername> [level]\n", argv
[0]);
996 /* get the arguments need to open the printer handle */
997 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
998 strupper_m(servername
);
999 fstrcpy(user
, cli
->user_name
);
1000 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1002 info_level
= atoi(argv
[2]);
1004 /* Open a printer handle */
1006 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1008 servername
, user
, &pol
);
1010 if (!W_ERROR_IS_OK(werror
)) {
1011 printf("Error opening printer handle for %s!\n", printername
);
1017 /* loop through and print driver info level for each architecture */
1019 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1021 werror
= rpccli_spoolss_getprinterdriver( cli
, mem_ctx
, &pol
, info_level
,
1022 archi_table
[i
].long_archi
, archi_table
[i
].version
,
1025 if (!W_ERROR_IS_OK(werror
))
1028 /* need at least one success */
1032 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1034 switch (info_level
) {
1036 display_print_driver_1 (ctr
.info1
);
1039 display_print_driver_2 (ctr
.info2
);
1042 display_print_driver_3 (ctr
.info3
);
1045 printf("unknown info level %d\n", info_level
);
1053 rpccli_spoolss_close_printer (cli
, mem_ctx
, &pol
);
1061 /****************************************************************************
1062 ****************************************************************************/
1064 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1065 TALLOC_CTX
*mem_ctx
,
1066 int argc
, const char **argv
)
1068 WERROR werror
= WERR_OK
;
1069 uint32 info_level
= 1;
1070 PRINTER_DRIVER_CTR ctr
;
1075 printf("Usage: enumdrivers [level]\n");
1080 info_level
= atoi(argv
[1]);
1083 /* loop through and print driver info level for each architecture */
1084 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1085 /* check to see if we already asked for this architecture string */
1087 if ( i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
) )
1090 werror
= rpccli_spoolss_enumprinterdrivers(
1091 cli
, mem_ctx
, info_level
,
1092 archi_table
[i
].long_archi
, &returned
, &ctr
);
1094 if (W_ERROR_V(werror
) == W_ERROR_V(WERR_INVALID_ENVIRONMENT
)) {
1095 printf ("Server does not support environment [%s]\n",
1096 archi_table
[i
].long_archi
);
1104 if (!W_ERROR_IS_OK(werror
)) {
1105 printf ("Error getting driver for environment [%s] - %d\n",
1106 archi_table
[i
].long_archi
, W_ERROR_V(werror
));
1110 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1115 for (j
=0; j
< returned
; j
++) {
1116 display_print_driver_1 (&ctr
.info1
[j
]);
1120 for (j
=0; j
< returned
; j
++) {
1121 display_print_driver_2 (&ctr
.info2
[j
]);
1125 for (j
=0; j
< returned
; j
++) {
1126 display_print_driver_3 (&ctr
.info3
[j
]);
1130 printf("unknown info level %d\n", info_level
);
1131 return WERR_UNKNOWN_LEVEL
;
1138 /****************************************************************************
1139 ****************************************************************************/
1141 static void display_printdriverdir_1(DRIVER_DIRECTORY_1
*i1
)
1147 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
1149 printf ("\tDirectory Name:[%s]\n", name
);
1152 /****************************************************************************
1153 ****************************************************************************/
1155 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1156 TALLOC_CTX
*mem_ctx
,
1157 int argc
, const char **argv
)
1161 DRIVER_DIRECTORY_CTR ctr
;
1164 printf("Usage: %s [environment]\n", argv
[0]);
1168 /* Get the arguments need to open the printer handle */
1171 fstrcpy (env
, argv
[1]);
1173 fstrcpy (env
, "Windows NT x86");
1175 /* Get the directory. Only use Info level 1 */
1177 result
= rpccli_spoolss_getprinterdriverdir(cli
, mem_ctx
, 1, env
, &ctr
);
1179 if (W_ERROR_IS_OK(result
))
1180 display_printdriverdir_1(ctr
.info1
);
1185 /****************************************************************************
1186 ****************************************************************************/
1188 void set_drv_info_3_env (DRIVER_INFO_3
*info
, const char *arch
)
1193 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1195 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1197 info
->version
= archi_table
[i
].version
;
1198 init_unistr (&info
->architecture
, archi_table
[i
].long_archi
);
1203 if (archi_table
[i
].long_archi
== NULL
)
1205 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1212 /**************************************************************************
1213 wrapper for strtok to get the next parameter from a delimited list.
1214 Needed to handle the empty parameter string denoted by "NULL"
1215 *************************************************************************/
1217 static char* get_driver_3_param (char* str
, const char* delim
, UNISTR
* dest
)
1221 /* get the next token */
1222 ptr
= strtok(str
, delim
);
1224 /* a string of 'NULL' is used to represent an empty
1225 parameter because two consecutive delimiters
1226 will not return an empty string. See man strtok(3)
1228 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0))
1232 init_unistr(dest
, ptr
);
1237 /********************************************************************************
1238 fill in the members of a DRIVER_INFO_3 struct using a character
1239 string in the form of
1240 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1241 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1242 <Default Data Type>:<Comma Separated list of Files>
1243 *******************************************************************************/
1244 static BOOL
init_drv_info_3_members ( TALLOC_CTX
*mem_ctx
, DRIVER_INFO_3
*info
,
1250 /* fill in the UNISTR fields */
1251 str
= get_driver_3_param (args
, ":", &info
->name
);
1252 str
= get_driver_3_param (NULL
, ":", &info
->driverpath
);
1253 str
= get_driver_3_param (NULL
, ":", &info
->datafile
);
1254 str
= get_driver_3_param (NULL
, ":", &info
->configfile
);
1255 str
= get_driver_3_param (NULL
, ":", &info
->helpfile
);
1256 str
= get_driver_3_param (NULL
, ":", &info
->monitorname
);
1257 str
= get_driver_3_param (NULL
, ":", &info
->defaultdatatype
);
1259 /* <Comma Separated List of Dependent Files> */
1260 str2
= get_driver_3_param (NULL
, ":", NULL
); /* save the beginning of the string */
1263 /* begin to strip out each filename */
1264 str
= strtok(str
, ",");
1268 /* keep a cumlative count of the str lengths */
1269 len
+= strlen(str
)+1;
1270 str
= strtok(NULL
, ",");
1273 /* allocate the space; add one extra slot for a terminating NULL.
1274 Each filename is NULL terminated and the end contains a double
1276 if ((info
->dependentfiles
=TALLOC_ARRAY(mem_ctx
, uint16
, len
+1)) == NULL
)
1278 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1281 for (i
=0; i
<len
; i
++)
1283 SSVAL(&info
->dependentfiles
[i
], 0, str2
[i
]);
1285 info
->dependentfiles
[len
] = '\0';
1291 /****************************************************************************
1292 ****************************************************************************/
1294 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1295 TALLOC_CTX
*mem_ctx
,
1296 int argc
, const char **argv
)
1300 PRINTER_DRIVER_CTR ctr
;
1301 DRIVER_INFO_3 info3
;
1303 fstring driver_name
;
1306 /* parse the command arguements */
1307 if (argc
!= 3 && argc
!= 4)
1309 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1310 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1311 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1312 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1313 printf ("\t[version]\n");
1318 /* Fill in the DRIVER_INFO_3 struct */
1320 if (!(arch
= cmd_spoolss_get_short_archi(argv
[1])))
1322 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1323 return WERR_INVALID_PARAM
;
1326 set_drv_info_3_env(&info3
, arch
);
1328 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1329 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1331 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1332 return WERR_INVALID_PARAM
;
1335 /* if printer driver version specified, override the default version
1336 * used by the architecture. This allows installation of Windows
1337 * 2000 (version 3) printer drivers. */
1340 info3
.version
= atoi(argv
[3]);
1345 result
= rpccli_spoolss_addprinterdriver (cli
, mem_ctx
, level
, &ctr
);
1347 if (W_ERROR_IS_OK(result
)) {
1348 rpcstr_pull(driver_name
, info3
.name
.buffer
,
1349 sizeof(driver_name
), -1, STR_TERMINATE
);
1350 printf ("Printer Driver %s successfully installed.\n",
1358 /****************************************************************************
1359 ****************************************************************************/
1361 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1362 TALLOC_CTX
*mem_ctx
,
1363 int argc
, const char **argv
)
1367 PRINTER_INFO_CTR ctr
;
1368 PRINTER_INFO_2 info2
;
1371 /* parse the command arguements */
1374 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1378 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1379 strupper_m(servername
);
1381 /* Fill in the DRIVER_INFO_2 struct */
1384 init_unistr( &info2
.printername
, argv
[1]);
1385 init_unistr( &info2
.sharename
, argv
[2]);
1386 init_unistr( &info2
.drivername
, argv
[3]);
1387 init_unistr( &info2
.portname
, argv
[4]);
1388 init_unistr( &info2
.comment
, "Created by rpcclient");
1389 init_unistr( &info2
.printprocessor
, "winprint");
1390 init_unistr( &info2
.datatype
, "RAW");
1391 info2
.devmode
= NULL
;
1392 info2
.secdesc
= NULL
;
1393 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1395 info2
.defaultpriority
= 0;
1396 info2
.starttime
= 0;
1397 info2
.untiltime
= 0;
1399 /* These three fields must not be used by AddPrinter()
1400 as defined in the MS Platform SDK documentation..
1404 info2.averageppm = 0;
1407 ctr
.printers_2
= &info2
;
1408 result
= rpccli_spoolss_addprinterex (cli
, mem_ctx
, level
, &ctr
);
1410 if (W_ERROR_IS_OK(result
))
1411 printf ("Printer %s successfully installed.\n", argv
[1]);
1416 /****************************************************************************
1417 ****************************************************************************/
1419 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1420 TALLOC_CTX
*mem_ctx
,
1421 int argc
, const char **argv
)
1426 BOOL opened_hnd
= False
;
1427 PRINTER_INFO_CTR ctr
;
1428 PRINTER_INFO_2 info2
;
1433 /* parse the command arguements */
1436 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1440 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1441 strupper_m(servername
);
1442 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
1443 fstrcpy(user
, cli
->user_name
);
1445 /* Get a printer handle */
1447 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1449 servername
, user
, &pol
);
1451 if (!W_ERROR_IS_OK(result
))
1456 /* Get printer info */
1458 ZERO_STRUCT (info2
);
1459 ctr
.printers_2
= &info2
;
1461 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, level
, &ctr
);
1463 if (!W_ERROR_IS_OK(result
)) {
1464 printf ("Unable to retrieve printer information!\n");
1468 /* Set the printer driver */
1470 init_unistr(&ctr
.printers_2
->drivername
, argv
[2]);
1472 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, level
, &ctr
, 0);
1474 if (!W_ERROR_IS_OK(result
)) {
1475 printf("SetPrinter call failed!\n");
1479 printf("Succesfully set %s to driver %s.\n", argv
[1], argv
[2]);
1485 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
1491 /****************************************************************************
1492 ****************************************************************************/
1494 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1495 TALLOC_CTX
*mem_ctx
,
1496 int argc
, const char **argv
)
1498 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1503 const char *arch
= NULL
;
1505 /* parse the command arguements */
1506 if (argc
< 2 || argc
> 4) {
1507 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1514 vers
= atoi (argv
[3]);
1517 /* delete the driver for all architectures */
1518 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1520 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1523 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1526 /* make the call to remove the driver */
1527 result
= rpccli_spoolss_deleteprinterdriverex(
1528 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1], archi_table
[i
].version
);
1530 if ( !W_ERROR_IS_OK(result
) )
1532 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1533 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1534 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, dos_errstr(result
));
1539 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1540 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1549 /****************************************************************************
1550 ****************************************************************************/
1552 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1553 TALLOC_CTX
*mem_ctx
,
1554 int argc
, const char **argv
)
1556 WERROR result
= WERR_OK
;
1560 /* parse the command arguements */
1562 printf ("Usage: %s <driver>\n", argv
[0]);
1566 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1567 strupper_m(servername
);
1569 /* delete the driver for all architectures */
1570 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1571 /* make the call to remove the driver */
1572 result
= rpccli_spoolss_deleteprinterdriver(
1573 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1]);
1575 if ( !W_ERROR_IS_OK(result
) ) {
1576 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1577 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1578 argv
[1], archi_table
[i
].long_archi
,
1582 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1583 archi_table
[i
].long_archi
);
1590 /****************************************************************************
1591 ****************************************************************************/
1593 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1594 TALLOC_CTX
*mem_ctx
,
1595 int argc
, const char **argv
)
1598 char *servername
= NULL
, *environment
= NULL
;
1601 /* parse the command arguements */
1603 printf ("Usage: %s [environment]\n", argv
[0]);
1607 if (asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
) < 0)
1609 strupper_m(servername
);
1611 if (asprintf(&environment
, "%s", (argc
== 2) ? argv
[1] :
1612 PRINTER_DRIVER_ARCHITECTURE
) < 0) {
1613 SAFE_FREE(servername
);
1617 result
= rpccli_spoolss_getprintprocessordirectory(
1618 cli
, mem_ctx
, servername
, environment
, procdir
);
1620 if (W_ERROR_IS_OK(result
))
1621 printf("%s\n", procdir
);
1623 SAFE_FREE(servername
);
1624 SAFE_FREE(environment
);
1629 /****************************************************************************
1630 ****************************************************************************/
1632 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1633 int argc
, const char **argv
)
1637 char *servername
= NULL
, *printername
= NULL
;
1639 BOOL got_handle
= False
;
1641 /* Parse the command arguements */
1644 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1648 /* Get a printer handle */
1650 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1651 strupper_m(servername
);
1652 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1654 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1656 servername
, cli
->user_name
, &handle
);
1658 if (!W_ERROR_IS_OK(werror
))
1663 /* Dummy up some values for the form data */
1665 form
.flags
= FORM_USER
;
1666 form
.size_x
= form
.size_y
= 100;
1672 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1677 werror
= rpccli_spoolss_addform(cli
, mem_ctx
, &handle
, 1, &form
);
1681 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1683 SAFE_FREE(servername
);
1684 SAFE_FREE(printername
);
1689 /****************************************************************************
1690 ****************************************************************************/
1692 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1693 int argc
, const char **argv
)
1697 char *servername
= NULL
, *printername
= NULL
;
1699 BOOL got_handle
= False
;
1701 /* Parse the command arguements */
1704 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1708 /* Get a printer handle */
1710 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1711 strupper_m(servername
);
1712 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1714 werror
= rpccli_spoolss_open_printer_ex(
1715 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1716 servername
, cli
->user_name
, &handle
);
1718 if (!W_ERROR_IS_OK(werror
))
1723 /* Dummy up some values for the form data */
1725 form
.flags
= FORM_PRINTER
;
1726 form
.size_x
= form
.size_y
= 100;
1732 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1736 werror
= rpccli_spoolss_setform(cli
, mem_ctx
, &handle
, 1, argv
[2], &form
);
1740 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1742 SAFE_FREE(servername
);
1743 SAFE_FREE(printername
);
1748 /****************************************************************************
1749 ****************************************************************************/
1751 static const char *get_form_flag(int form_flag
)
1753 switch (form_flag
) {
1757 return "FORM_BUILTIN";
1759 return "FORM_PRINTER";
1765 /****************************************************************************
1766 ****************************************************************************/
1768 static void display_form(FORM_1
*form
)
1770 fstring form_name
= "";
1772 if (form
->name
.buffer
)
1773 rpcstr_pull(form_name
, form
->name
.buffer
,
1774 sizeof(form_name
), -1, STR_TERMINATE
);
1777 "\tflag: %s (%d)\n" \
1778 "\twidth: %d, length: %d\n" \
1779 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1780 form_name
, get_form_flag(form
->flag
), form
->flag
,
1781 form
->width
, form
->length
,
1782 form
->left
, form
->right
,
1783 form
->top
, form
->bottom
);
1786 /****************************************************************************
1787 ****************************************************************************/
1789 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1790 int argc
, const char **argv
)
1794 char *servername
= NULL
, *printername
= NULL
;
1796 BOOL got_handle
= False
;
1798 /* Parse the command arguements */
1801 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1805 /* Get a printer handle */
1807 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1808 strupper_m(servername
);
1809 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1811 werror
= rpccli_spoolss_open_printer_ex(
1812 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1813 servername
, cli
->user_name
, &handle
);
1815 if (!W_ERROR_IS_OK(werror
))
1822 werror
= rpccli_spoolss_getform(cli
, mem_ctx
, &handle
, argv
[2], 1, &form
);
1824 if (!W_ERROR_IS_OK(werror
))
1827 display_form(&form
);
1831 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1833 SAFE_FREE(servername
);
1834 SAFE_FREE(printername
);
1839 /****************************************************************************
1840 ****************************************************************************/
1842 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
1843 TALLOC_CTX
*mem_ctx
, int argc
,
1848 char *servername
= NULL
, *printername
= NULL
;
1849 BOOL got_handle
= False
;
1851 /* Parse the command arguements */
1854 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1858 /* Get a printer handle */
1860 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1861 strupper_m(servername
);
1862 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1864 werror
= rpccli_spoolss_open_printer_ex(
1865 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1866 servername
, cli
->user_name
, &handle
);
1868 if (!W_ERROR_IS_OK(werror
))
1873 /* Delete the form */
1875 werror
= rpccli_spoolss_deleteform(cli
, mem_ctx
, &handle
, argv
[2]);
1879 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1881 SAFE_FREE(servername
);
1882 SAFE_FREE(printername
);
1887 /****************************************************************************
1888 ****************************************************************************/
1890 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
1891 TALLOC_CTX
*mem_ctx
, int argc
,
1896 char *servername
= NULL
, *printername
= NULL
;
1897 BOOL got_handle
= False
;
1898 uint32 needed
, offered
, num_forms
, level
= 1, i
;
1901 /* Parse the command arguements */
1904 printf ("Usage: %s <printer>\n", argv
[0]);
1908 /* Get a printer handle */
1910 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1911 strupper_m(servername
);
1912 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1914 werror
= rpccli_spoolss_open_printer_ex(
1915 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1916 servername
, cli
->user_name
, &handle
);
1918 if (!W_ERROR_IS_OK(werror
))
1923 /* Enumerate forms */
1925 offered
= needed
= 0;
1926 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
, &handle
, level
, &num_forms
, &forms
);
1928 if (!W_ERROR_IS_OK(werror
))
1931 /* Display output */
1933 for (i
= 0; i
< num_forms
; i
++) {
1935 display_form(&forms
[i
]);
1941 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1943 SAFE_FREE(servername
);
1944 SAFE_FREE(printername
);
1949 /****************************************************************************
1950 ****************************************************************************/
1952 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
1953 TALLOC_CTX
*mem_ctx
,
1954 int argc
, const char **argv
)
1957 fstring servername
, printername
, user
;
1959 BOOL opened_hnd
= False
;
1960 PRINTER_INFO_CTR ctr
;
1961 PRINTER_INFO_0 info
;
1962 REGISTRY_VALUE value
;
1964 /* parse the command arguements */
1966 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
1967 " <value> <data>\n",
1969 return WERR_INVALID_PARAM
;
1972 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1973 strupper_m(servername
);
1974 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1975 fstrcpy(user
, cli
->user_name
);
1977 value
.type
= REG_NONE
;
1979 if (strequal(argv
[2], "string")) {
1980 value
.type
= REG_SZ
;
1983 if (strequal(argv
[2], "binary")) {
1984 value
.type
= REG_BINARY
;
1987 if (strequal(argv
[2], "dword")) {
1988 value
.type
= REG_DWORD
;
1991 if (strequal(argv
[2], "multistring")) {
1992 value
.type
= REG_MULTI_SZ
;
1995 if (value
.type
== REG_NONE
) {
1996 printf("Unknown data type: %s\n", argv
[2]);
1997 return WERR_INVALID_PARAM
;
2000 /* get a printer handle */
2001 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
2002 MAXIMUM_ALLOWED_ACCESS
, servername
,
2004 if (!W_ERROR_IS_OK(result
))
2009 ctr
.printers_0
= &info
;
2011 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2013 if (!W_ERROR_IS_OK(result
))
2016 printf("%s\n", timestring(True
));
2017 printf("\tchange_id (before set)\t:[0x%x]\n", info
.change_id
);
2019 /* Set the printer data */
2021 fstrcpy(value
.valuename
, argv
[3]);
2023 switch (value
.type
) {
2026 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2027 value
.size
= data
.uni_str_len
* 2;
2028 value
.data_p
= TALLOC_MEMDUP(mem_ctx
, data
.buffer
, value
.size
);
2032 uint32 data
= strtoul(argv
[4], NULL
, 10);
2033 value
.size
= sizeof(data
);
2034 value
.data_p
= TALLOC_MEMDUP(mem_ctx
, &data
, sizeof(data
));
2038 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2039 value
.data_p
= data
.data
;
2040 value
.size
= data
.length
;
2043 case REG_MULTI_SZ
: {
2048 for (i
=4; i
<argc
; i
++) {
2049 if (strcmp(argv
[i
], "NULL") == 0) {
2052 len
+= strlen(argv
[i
])+1;
2056 value
.data_p
= TALLOC_ARRAY(mem_ctx
, unsigned char, value
.size
);
2057 if (value
.data_p
== NULL
) {
2058 result
= WERR_NOMEM
;
2062 p
= (char *)value
.data_p
;
2064 for (i
=4; i
<argc
; i
++) {
2065 size_t l
= (strlen(argv
[i
])+1)*2;
2066 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2070 SMB_ASSERT(len
== 0);
2074 printf("Unknown data type: %s\n", argv
[2]);
2075 result
= WERR_INVALID_PARAM
;
2079 result
= rpccli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2081 if (!W_ERROR_IS_OK(result
)) {
2082 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2085 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2087 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2089 if (!W_ERROR_IS_OK(result
))
2092 printf("%s\n", timestring(True
));
2093 printf("\tchange_id (after set)\t:[0x%x]\n", info
.change_id
);
2098 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
2103 /****************************************************************************
2104 ****************************************************************************/
2106 static void display_job_info_1(JOB_INFO_1
*job
)
2108 fstring username
= "", document
= "", text_status
= "";
2110 rpcstr_pull(username
, job
->username
.buffer
,
2111 sizeof(username
), -1, STR_TERMINATE
);
2113 rpcstr_pull(document
, job
->document
.buffer
,
2114 sizeof(document
), -1, STR_TERMINATE
);
2116 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2117 sizeof(text_status
), -1, STR_TERMINATE
);
2119 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job
->position
, job
->jobid
,
2120 username
, document
, text_status
, job
->pagesprinted
,
2124 /****************************************************************************
2125 ****************************************************************************/
2127 static void display_job_info_2(JOB_INFO_2
*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, %d bytes\n", job
->position
, job
->jobid
,
2141 username
, document
, text_status
, job
->pagesprinted
,
2142 job
->totalpages
, job
->size
);
2145 /****************************************************************************
2146 ****************************************************************************/
2148 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2149 TALLOC_CTX
*mem_ctx
, int argc
,
2153 uint32 needed
, offered
, level
= 1, num_jobs
, i
;
2154 BOOL got_hnd
= False
;
2155 pstring printername
;
2156 fstring servername
, user
;
2160 if (argc
< 2 || argc
> 3) {
2161 printf("Usage: %s printername [level]\n", argv
[0]);
2166 level
= atoi(argv
[2]);
2168 /* Open printer handle */
2170 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2171 strupper_m(servername
);
2172 fstrcpy(user
, cli
->user_name
);
2173 slprintf(printername
, sizeof(servername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2174 strupper_m(printername
);
2175 pstrcat(printername
, argv
[1]);
2177 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2178 "", MAXIMUM_ALLOWED_ACCESS
,
2179 servername
, user
, &hnd
);
2181 if (!W_ERROR_IS_OK(result
))
2186 /* Enumerate ports */
2188 offered
= needed
= 0;
2189 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2192 if (!W_ERROR_IS_OK(result
))
2195 for (i
= 0; i
< num_jobs
; i
++) {
2198 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2201 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2204 d_printf("unknown info level %d\n", level
);
2211 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2216 /****************************************************************************
2217 ****************************************************************************/
2219 static WERROR
cmd_spoolss_enum_data( struct rpc_pipe_client
*cli
,
2220 TALLOC_CTX
*mem_ctx
, int argc
,
2224 uint32 i
=0, val_needed
, data_needed
;
2225 BOOL got_hnd
= False
;
2226 pstring printername
;
2227 fstring servername
, user
;
2231 printf("Usage: %s printername\n", argv
[0]);
2235 /* Open printer handle */
2237 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2238 strupper_m(servername
);
2239 fstrcpy(user
, cli
->user_name
);
2240 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2241 strupper_m(printername
);
2242 pstrcat(printername
, argv
[1]);
2244 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2245 "", MAXIMUM_ALLOWED_ACCESS
,
2246 servername
, user
, &hnd
);
2248 if (!W_ERROR_IS_OK(result
))
2253 /* Enumerate data */
2255 result
= rpccli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2256 &val_needed
, &data_needed
,
2258 while (W_ERROR_IS_OK(result
)) {
2259 REGISTRY_VALUE value
;
2260 result
= rpccli_spoolss_enumprinterdata(
2261 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2262 data_needed
, 0, 0, &value
);
2263 if (W_ERROR_IS_OK(result
))
2264 display_reg_value(value
);
2266 if (W_ERROR_V(result
) == ERRnomoreitems
)
2267 result
= W_ERROR(ERRsuccess
);
2271 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2276 /****************************************************************************
2277 ****************************************************************************/
2279 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2280 TALLOC_CTX
*mem_ctx
, int argc
,
2285 BOOL got_hnd
= False
;
2286 pstring printername
;
2287 fstring servername
, user
;
2288 const char *keyname
= NULL
;
2290 REGVAL_CTR
*ctr
= NULL
;
2293 printf("Usage: %s printername <keyname>\n", argv
[0]);
2299 /* Open printer handle */
2301 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2302 strupper_m(servername
);
2303 fstrcpy(user
, cli
->user_name
);
2304 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2305 strupper_m(printername
);
2306 pstrcat(printername
, argv
[1]);
2308 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2309 "", MAXIMUM_ALLOWED_ACCESS
,
2310 servername
, user
, &hnd
);
2312 if (!W_ERROR_IS_OK(result
))
2317 /* Enumerate subkeys */
2319 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2322 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2324 if (!W_ERROR_IS_OK(result
))
2327 for (i
=0; i
< ctr
->num_values
; i
++) {
2328 display_reg_value(*(ctr
->values
[i
]));
2335 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2340 /****************************************************************************
2341 ****************************************************************************/
2343 static WERROR
cmd_spoolss_enum_printerkey( struct rpc_pipe_client
*cli
,
2344 TALLOC_CTX
*mem_ctx
, int argc
,
2348 BOOL got_hnd
= False
;
2349 pstring printername
;
2350 fstring servername
, user
;
2351 const char *keyname
= NULL
;
2353 uint16
*keylist
= NULL
, *curkey
;
2355 if (argc
< 2 || argc
> 3) {
2356 printf("Usage: %s printername [keyname]\n", argv
[0]);
2365 /* Open printer handle */
2367 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2368 strupper_m(servername
);
2369 fstrcpy(user
, cli
->user_name
);
2370 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2371 strupper_m(printername
);
2372 pstrcat(printername
, argv
[1]);
2374 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2375 "", MAXIMUM_ALLOWED_ACCESS
,
2376 servername
, user
, &hnd
);
2378 if (!W_ERROR_IS_OK(result
))
2383 /* Enumerate subkeys */
2385 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2387 if (!W_ERROR_IS_OK(result
))
2391 while (*curkey
!= 0) {
2393 rpcstr_pull(subkey
, curkey
, sizeof(subkey
), -1,
2395 printf("%s\n", subkey
);
2396 curkey
+= strlen(subkey
) + 1;
2403 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2408 /****************************************************************************
2409 ****************************************************************************/
2411 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2412 TALLOC_CTX
*mem_ctx
, int argc
,
2415 fstring servername
, printername
;
2417 BOOL got_hnd
= False
;
2419 SPOOL_NOTIFY_OPTION option
;
2422 printf("Usage: %s printername\n", argv
[0]);
2429 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", cli
->cli
->desthost
);
2430 strupper_m(servername
);
2432 slprintf(printername
, sizeof(printername
) - 1, "\\\\%s\\%s", cli
->cli
->desthost
,
2434 strupper_m(printername
);
2436 result
= rpccli_spoolss_open_printer_ex(
2437 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
2438 servername
, cli
->user_name
, &hnd
);
2440 if (!W_ERROR_IS_OK(result
)) {
2441 printf("Error opening %s\n", argv
[1]);
2447 /* Create spool options */
2449 ZERO_STRUCT(option
);
2452 option
.option_type_ptr
= 1;
2453 option
.count
= option
.ctr
.count
= 2;
2455 option
.ctr
.type
= TALLOC_ARRAY(mem_ctx
, SPOOL_NOTIFY_OPTION_TYPE
, 2);
2457 ZERO_STRUCT(option
.ctr
.type
[0]);
2458 option
.ctr
.type
[0].type
= PRINTER_NOTIFY_TYPE
;
2459 option
.ctr
.type
[0].count
= option
.ctr
.type
[0].count2
= 1;
2460 option
.ctr
.type
[0].fields_ptr
= 1;
2461 option
.ctr
.type
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2463 ZERO_STRUCT(option
.ctr
.type
[1]);
2464 option
.ctr
.type
[1].type
= JOB_NOTIFY_TYPE
;
2465 option
.ctr
.type
[1].count
= option
.ctr
.type
[1].count2
= 1;
2466 option
.ctr
.type
[1].fields_ptr
= 1;
2467 option
.ctr
.type
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2471 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", myhostname());
2472 strupper_m(servername
);
2474 result
= rpccli_spoolss_rffpcnex(
2475 cli
, mem_ctx
, &hnd
, 0, 0, servername
, 123, &option
);
2477 if (!W_ERROR_IS_OK(result
)) {
2478 printf("Error rffpcnex %s\n", argv
[1]);
2484 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2489 /****************************************************************************
2490 ****************************************************************************/
2492 static BOOL
compare_printer( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2493 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2495 PRINTER_INFO_CTR ctr1
, ctr2
;
2497 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2499 printf("Retrieving printer propertiesfor %s...", cli1
->cli
->desthost
);
2500 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 2, &ctr1
);
2501 if ( !W_ERROR_IS_OK(werror
) ) {
2502 printf("failed (%s)\n", dos_errstr(werror
));
2503 talloc_destroy(mem_ctx
);
2508 printf("Retrieving printer properties for %s...", cli2
->cli
->desthost
);
2509 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 2, &ctr2
);
2510 if ( !W_ERROR_IS_OK(werror
) ) {
2511 printf("failed (%s)\n", dos_errstr(werror
));
2512 talloc_destroy(mem_ctx
);
2517 talloc_destroy(mem_ctx
);
2522 /****************************************************************************
2523 ****************************************************************************/
2525 static BOOL
compare_printer_secdesc( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2526 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2528 PRINTER_INFO_CTR ctr1
, ctr2
;
2530 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2531 SEC_DESC
*sd1
, *sd2
;
2535 printf("Retreiving printer security for %s...", cli1
->cli
->desthost
);
2536 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 3, &ctr1
);
2537 if ( !W_ERROR_IS_OK(werror
) ) {
2538 printf("failed (%s)\n", dos_errstr(werror
));
2544 printf("Retrieving printer security for %s...", cli2
->cli
->desthost
);
2545 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 3, &ctr2
);
2546 if ( !W_ERROR_IS_OK(werror
) ) {
2547 printf("failed (%s)\n", dos_errstr(werror
));
2556 if ( (ctr1
.printers_3
!= ctr2
.printers_3
) && (!ctr1
.printers_3
|| !ctr2
.printers_3
) ) {
2557 printf("NULL PRINTER_INFO_3!\n");
2562 sd1
= ctr1
.printers_3
->secdesc
;
2563 sd2
= ctr2
.printers_3
->secdesc
;
2565 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2566 printf("NULL secdesc!\n");
2571 if ( (ctr1
.printers_3
->flags
!= ctr1
.printers_3
->flags
) || !sec_desc_equal( sd1
, sd2
) ) {
2572 printf("Security Descriptors *not* equal!\n");
2577 printf("Security descriptors match\n");
2580 talloc_destroy(mem_ctx
);
2585 /****************************************************************************
2586 ****************************************************************************/
2588 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
2589 TALLOC_CTX
*mem_ctx
, int argc
,
2592 fstring printername
, servername1
, servername2
;
2593 pstring printername_path
;
2594 struct cli_state
*cli_server1
= cli
->cli
;
2595 struct cli_state
*cli_server2
= NULL
;
2596 struct rpc_pipe_client
*cli2
= NULL
;
2597 POLICY_HND hPrinter1
, hPrinter2
;
2602 printf("Usage: %s <printer> <server>\n", argv
[0]);
2606 fstrcpy( printername
, argv
[1] );
2608 fstr_sprintf( servername1
, cli
->cli
->desthost
);
2609 fstrcpy( servername2
, argv
[2] );
2610 strupper_m( servername1
);
2611 strupper_m( servername2
);
2614 /* first get the connection to the remote server */
2616 nt_status
= cli_full_connection(&cli_server2
, global_myname(), servername2
,
2619 cmdline_auth_info
.username
,
2621 cmdline_auth_info
.password
,
2622 cmdline_auth_info
.use_kerberos
? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2623 cmdline_auth_info
.signing_state
, NULL
);
2625 if ( !NT_STATUS_IS_OK(nt_status
) )
2626 return WERR_GENERAL_FAILURE
;
2628 cli2
= cli_rpc_pipe_open_noauth(cli_server2
, PI_SPOOLSS
, &nt_status
);
2630 printf("failed to open spoolss pipe on server %s (%s)\n",
2631 servername2
, nt_errstr(nt_status
));
2632 return WERR_GENERAL_FAILURE
;
2635 /* now open up both printers */
2637 pstr_sprintf( printername_path
, "\\\\%s\\%s", servername1
, printername
);
2638 printf("Opening %s...", printername_path
);
2639 werror
= rpccli_spoolss_open_printer_ex( cli
, mem_ctx
, printername_path
,
2640 "", PRINTER_ALL_ACCESS
, servername1
, cli_server1
->user_name
, &hPrinter1
);
2641 if ( !W_ERROR_IS_OK(werror
) ) {
2642 printf("failed (%s)\n", dos_errstr(werror
));
2647 pstr_sprintf( printername_path
, "\\\\%s\\%s", servername2
, printername
);
2648 printf("Opening %s...", printername_path
);
2649 werror
= rpccli_spoolss_open_printer_ex( cli2
, mem_ctx
, printername_path
,
2650 "", PRINTER_ALL_ACCESS
, servername2
, cli_server2
->user_name
, &hPrinter2
);
2651 if ( !W_ERROR_IS_OK(werror
) ) {
2652 printf("failed (%s)\n", dos_errstr(werror
));
2658 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2659 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2661 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2668 printf("Closing printers...");
2669 rpccli_spoolss_close_printer( cli
, mem_ctx
, &hPrinter1
);
2670 rpccli_spoolss_close_printer( cli2
, mem_ctx
, &hPrinter2
);
2673 /* close the second remote connection */
2675 cli_shutdown( cli_server2
);
2680 /* List of commands exported by this module */
2681 struct cmd_set spoolss_commands
[] = {
2685 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, PI_SPOOLSS
, NULL
, "Add a print driver", "" },
2686 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, PI_SPOOLSS
, NULL
, "Add a printer", "" },
2687 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, PI_SPOOLSS
, NULL
, "Delete a printer driver", "" },
2688 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, PI_SPOOLSS
, NULL
, "Delete a printer driver with files", "" },
2689 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, PI_SPOOLSS
, NULL
, "Enumerate printer data", "" },
2690 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, PI_SPOOLSS
, NULL
, "Enumerate printer data for a key", "" },
2691 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, PI_SPOOLSS
, NULL
, "Enumerate printer keys", "" },
2692 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, PI_SPOOLSS
, NULL
, "Enumerate print jobs", "" },
2693 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, PI_SPOOLSS
, NULL
, "Enumerate printer ports", "" },
2694 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, PI_SPOOLSS
, NULL
, "Enumerate installed printer drivers", "" },
2695 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, PI_SPOOLSS
, NULL
, "Enumerate printers", "" },
2696 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, PI_SPOOLSS
, NULL
, "Get print driver data", "" },
2697 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, PI_SPOOLSS
, NULL
, "Get printer driver data with keyname", ""},
2698 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, PI_SPOOLSS
, NULL
, "Get print driver information", "" },
2699 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, PI_SPOOLSS
, NULL
, "Get print driver upload directory", "" },
2700 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, PI_SPOOLSS
, NULL
, "Get printer info", "" },
2701 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, PI_SPOOLSS
, NULL
, "Open printer handle", "" },
2702 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, PI_SPOOLSS
, NULL
, "Set printer driver", "" },
2703 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, PI_SPOOLSS
, NULL
, "Get print processor directory", "" },
2704 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, PI_SPOOLSS
, NULL
, "Add form", "" },
2705 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, PI_SPOOLSS
, NULL
, "Set form", "" },
2706 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, PI_SPOOLSS
, NULL
, "Get form", "" },
2707 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, PI_SPOOLSS
, NULL
, "Delete form", "" },
2708 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, PI_SPOOLSS
, NULL
, "Enumerate forms", "" },
2709 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, PI_SPOOLSS
, NULL
, "Set printer comment", "" },
2710 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, PI_SPOOLSS
, NULL
, "Set printername", "" },
2711 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, PI_SPOOLSS
, NULL
, "Set REG_SZ printer data", "" },
2712 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, PI_SPOOLSS
, NULL
, "Rffpcnex test", "" },
2713 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, PI_SPOOLSS
, NULL
, "Printer comparison test", "" },