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 display_sec_desc(i3
->secdesc
);
284 /****************************************************************************
285 ****************************************************************************/
287 static void display_print_info_7(PRINTER_INFO_7
*i7
)
290 rpcstr_pull(guid
, i7
->guid
.buffer
,sizeof(guid
), -1, STR_TERMINATE
);
291 printf("\tguid:[%s]\n", guid
);
292 printf("\taction:[0x%x]\n", i7
->action
);
296 /****************************************************************************
297 ****************************************************************************/
299 static WERROR
cmd_spoolss_enum_printers(struct rpc_pipe_client
*cli
,
301 int argc
, const char **argv
)
304 uint32 info_level
= 1;
305 PRINTER_INFO_CTR ctr
;
306 uint32 i
= 0, num_printers
;
311 printf("Usage: %s [level] [name]\n", argv
[0]);
316 info_level
= atoi(argv
[1]);
319 fstrcpy(name
, argv
[2]);
321 slprintf(name
, sizeof(name
)-1, "\\\\%s", cli
->cli
->desthost
);
327 result
= rpccli_spoolss_enum_printers(cli
, mem_ctx
, name
, PRINTER_ENUM_LOCAL
,
328 info_level
, &num_printers
, &ctr
);
330 if (W_ERROR_IS_OK(result
)) {
333 printf ("No printers returned.\n");
337 for (i
= 0; i
< num_printers
; i
++) {
340 display_print_info_0(&ctr
.printers_0
[i
]);
343 display_print_info_1(&ctr
.printers_1
[i
]);
346 display_print_info_2(&ctr
.printers_2
[i
]);
349 display_print_info_3(&ctr
.printers_3
[i
]);
352 printf("unknown info level %d\n", info_level
);
362 /****************************************************************************
363 ****************************************************************************/
365 static void display_port_info_1(PORT_INFO_1
*i1
)
369 rpcstr_pull(buffer
, i1
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
370 printf("\tPort Name:\t[%s]\n", buffer
);
373 /****************************************************************************
374 ****************************************************************************/
376 static void display_port_info_2(PORT_INFO_2
*i2
)
380 rpcstr_pull(buffer
, i2
->port_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
381 printf("\tPort Name:\t[%s]\n", buffer
);
382 rpcstr_pull(buffer
, i2
->monitor_name
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
384 printf("\tMonitor Name:\t[%s]\n", buffer
);
385 rpcstr_pull(buffer
, i2
->description
.buffer
, sizeof(buffer
), -1, STR_TERMINATE
);
387 printf("\tDescription:\t[%s]\n", buffer
);
388 printf("\tPort Type:\t" );
389 if ( i2
->port_type
) {
390 int comma
= 0; /* hack */
392 if ( i2
->port_type
& PORT_TYPE_READ
) {
396 if ( i2
->port_type
& PORT_TYPE_WRITE
) {
397 printf( "%sWrite", comma
? ", " : "" );
400 /* These two have slightly different interpretations
401 on 95/98/ME but I'm disregarding that for now */
402 if ( i2
->port_type
& PORT_TYPE_REDIRECTED
) {
403 printf( "%sRedirected", comma
? ", " : "" );
406 if ( i2
->port_type
& PORT_TYPE_NET_ATTACHED
) {
407 printf( "%sNet-Attached", comma
? ", " : "" );
411 printf( "[Unset]\n" );
413 printf("\tReserved:\t[%d]\n", i2
->reserved
);
417 /****************************************************************************
418 ****************************************************************************/
420 static WERROR
cmd_spoolss_enum_ports(struct rpc_pipe_client
*cli
,
421 TALLOC_CTX
*mem_ctx
, int argc
,
425 uint32 info_level
= 1;
430 printf("Usage: %s [level]\n", argv
[0]);
435 info_level
= atoi(argv
[1]);
437 /* Enumerate ports */
441 result
= rpccli_spoolss_enum_ports(cli
, mem_ctx
, info_level
, &returned
, &ctr
);
443 if (W_ERROR_IS_OK(result
)) {
446 for (i
= 0; i
< returned
; i
++) {
447 switch (info_level
) {
449 display_port_info_1(&ctr
.port
.info_1
[i
]);
452 display_port_info_2(&ctr
.port
.info_2
[i
]);
455 printf("unknown info level %d\n", info_level
);
464 /****************************************************************************
465 ****************************************************************************/
467 static WERROR
cmd_spoolss_setprinter(struct rpc_pipe_client
*cli
,
469 int argc
, const char **argv
)
473 uint32 info_level
= 2;
474 BOOL opened_hnd
= False
;
475 PRINTER_INFO_CTR ctr
;
481 if (argc
== 1 || argc
> 3) {
482 printf("Usage: %s printername comment\n", argv
[0]);
487 /* Open a printer handle */
489 fstrcpy(comment
, argv
[2]);
492 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
493 strupper_m(servername
);
494 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
495 fstrcpy(user
, cli
->user_name
);
497 /* get a printer handle */
498 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
499 PRINTER_ALL_ACCESS
, servername
,
502 if (!W_ERROR_IS_OK(result
))
507 /* Get printer info */
508 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
510 if (!W_ERROR_IS_OK(result
))
514 /* Modify the comment. */
515 init_unistr(&ctr
.printers_2
->comment
, comment
);
516 ctr
.printers_2
->devmode
= NULL
;
517 ctr
.printers_2
->secdesc
= NULL
;
519 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
, 0);
520 if (W_ERROR_IS_OK(result
))
521 printf("Success in setting comment.\n");
525 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
530 /****************************************************************************
531 ****************************************************************************/
533 static WERROR
cmd_spoolss_setprintername(struct rpc_pipe_client
*cli
,
535 int argc
, const char **argv
)
539 uint32 info_level
= 2;
540 BOOL opened_hnd
= False
;
541 PRINTER_INFO_CTR ctr
;
547 if (argc
== 1 || argc
> 3) {
548 printf("Usage: %s printername new_printername\n", argv
[0]);
553 /* Open a printer handle */
555 fstrcpy(new_printername
, argv
[2]);
558 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
559 strupper_m(servername
);
560 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
561 fstrcpy(user
, cli
->user_name
);
563 /* get a printer handle */
564 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
565 PRINTER_ALL_ACCESS
, servername
,
568 if (!W_ERROR_IS_OK(result
))
573 /* Get printer info */
574 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
576 if (!W_ERROR_IS_OK(result
))
579 /* Modify the printername. */
580 init_unistr(&ctr
.printers_2
->printername
, new_printername
);
581 ctr
.printers_2
->devmode
= NULL
;
582 ctr
.printers_2
->secdesc
= NULL
;
584 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
, 0);
585 if (W_ERROR_IS_OK(result
))
586 printf("Success in setting printername.\n");
590 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
595 /****************************************************************************
596 ****************************************************************************/
598 static WERROR
cmd_spoolss_getprinter(struct rpc_pipe_client
*cli
,
600 int argc
, const char **argv
)
604 uint32 info_level
= 1;
605 BOOL opened_hnd
= False
;
606 PRINTER_INFO_CTR ctr
;
611 if (argc
== 1 || argc
> 3) {
612 printf("Usage: %s <printername> [level]\n", argv
[0]);
616 /* Open a printer handle */
618 info_level
= atoi(argv
[2]);
621 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
622 strupper_m(servername
);
623 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
624 fstrcpy(user
, cli
->user_name
);
626 /* get a printer handle */
628 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
629 "", MAXIMUM_ALLOWED_ACCESS
,
630 servername
, user
, &pol
);
632 if (!W_ERROR_IS_OK(result
))
637 /* Get printer info */
639 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
);
641 if (!W_ERROR_IS_OK(result
))
644 /* Display printer info */
646 switch (info_level
) {
648 display_print_info_0(ctr
.printers_0
);
651 display_print_info_1(ctr
.printers_1
);
654 display_print_info_2(ctr
.printers_2
);
657 display_print_info_3(ctr
.printers_3
);
660 display_print_info_7(ctr
.printers_7
);
663 printf("unknown info level %d\n", info_level
);
669 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
674 /****************************************************************************
675 ****************************************************************************/
677 static void display_reg_value(REGISTRY_VALUE value
)
683 printf("%s: REG_DWORD: 0x%08x\n", value
.valuename
,
684 *((uint32
*) value
.data_p
));
687 rpcstr_pull(text
, value
.data_p
, sizeof(text
), value
.size
,
689 printf("%s: REG_SZ: %s\n", value
.valuename
, text
);
692 char *hex
= hex_encode(NULL
, value
.data_p
, value
.size
);
694 printf("%s: REG_BINARY:", value
.valuename
);
696 for (i
=0; i
<len
; i
++) {
697 if (hex
[i
] == '\0') {
710 uint16
*curstr
= (uint16
*) value
.data_p
;
711 uint8
*start
= value
.data_p
;
712 printf("%s: REG_MULTI_SZ:\n", value
.valuename
);
713 while (((uint8
*) curstr
< start
+ value
.size
)) {
714 rpcstr_pull(text
, curstr
, sizeof(text
), -1,
716 printf(" %s\n", *text
!= 0 ? text
: "NULL");
717 curstr
+= strlen(text
) + 1;
722 printf("%s: unknown type %d\n", value
.valuename
, value
.type
);
727 /****************************************************************************
728 ****************************************************************************/
730 static WERROR
cmd_spoolss_getprinterdata(struct rpc_pipe_client
*cli
,
732 int argc
, const char **argv
)
736 BOOL opened_hnd
= False
;
740 const char *valuename
;
741 REGISTRY_VALUE value
;
744 printf("Usage: %s <printername> <valuename>\n", argv
[0]);
745 printf("<printername> of . queries print server\n");
750 /* Open a printer handle */
752 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
753 strupper_m(servername
);
754 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
755 fstrcpy(printername
, servername
);
757 slprintf(printername
, sizeof(servername
)-1, "%s\\%s",
758 servername
, argv
[1]);
759 fstrcpy(user
, cli
->user_name
);
761 /* get a printer handle */
763 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
764 "", MAXIMUM_ALLOWED_ACCESS
,
765 servername
, user
, &pol
);
767 if (!W_ERROR_IS_OK(result
))
772 /* Get printer info */
774 result
= rpccli_spoolss_getprinterdata(cli
, mem_ctx
, &pol
, valuename
, &value
);
776 if (!W_ERROR_IS_OK(result
))
779 /* Display printer data */
781 fstrcpy(value
.valuename
, valuename
);
782 display_reg_value(value
);
787 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
792 /****************************************************************************
793 ****************************************************************************/
795 static WERROR
cmd_spoolss_getprinterdataex(struct rpc_pipe_client
*cli
,
797 int argc
, const char **argv
)
801 BOOL opened_hnd
= False
;
805 const char *valuename
, *keyname
;
806 REGISTRY_VALUE value
;
809 printf("Usage: %s <printername> <keyname> <valuename>\n",
811 printf("<printername> of . queries print server\n");
817 /* Open a printer handle */
819 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
820 strupper_m(servername
);
821 if (strncmp(argv
[1], ".", sizeof(".")) == 0)
822 fstrcpy(printername
, servername
);
824 slprintf(printername
, sizeof(printername
)-1, "%s\\%s",
825 servername
, argv
[1]);
826 fstrcpy(user
, cli
->user_name
);
828 /* get a printer handle */
830 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
831 "", MAXIMUM_ALLOWED_ACCESS
,
832 servername
, user
, &pol
);
834 if (!W_ERROR_IS_OK(result
))
839 /* Get printer info */
841 result
= rpccli_spoolss_getprinterdataex(cli
, mem_ctx
, &pol
, keyname
,
844 if (!W_ERROR_IS_OK(result
))
847 /* Display printer data */
849 fstrcpy(value
.valuename
, valuename
);
850 display_reg_value(value
);
855 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
860 /****************************************************************************
861 ****************************************************************************/
863 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
869 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
871 printf ("Printer Driver Info 1:\n");
872 printf ("\tDriver Name: [%s]\n\n", name
);
877 /****************************************************************************
878 ****************************************************************************/
880 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
883 fstring architecture
;
890 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
891 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
892 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
893 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
894 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
896 printf ("Printer Driver Info 2:\n");
897 printf ("\tVersion: [%x]\n", i1
->version
);
898 printf ("\tDriver Name: [%s]\n", name
);
899 printf ("\tArchitecture: [%s]\n", architecture
);
900 printf ("\tDriver Path: [%s]\n", driverpath
);
901 printf ("\tDatafile: [%s]\n", datafile
);
902 printf ("\tConfigfile: [%s]\n\n", configfile
);
907 /****************************************************************************
908 ****************************************************************************/
910 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
913 fstring architecture
= "";
914 fstring driverpath
= "";
915 fstring datafile
= "";
916 fstring configfile
= "";
917 fstring helpfile
= "";
918 fstring dependentfiles
= "";
919 fstring monitorname
= "";
920 fstring defaultdatatype
= "";
928 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
929 rpcstr_pull(architecture
, i1
->architecture
.buffer
, sizeof(architecture
), -1, STR_TERMINATE
);
930 rpcstr_pull(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
), -1, STR_TERMINATE
);
931 rpcstr_pull(datafile
, i1
->datafile
.buffer
, sizeof(datafile
), -1, STR_TERMINATE
);
932 rpcstr_pull(configfile
, i1
->configfile
.buffer
, sizeof(configfile
), -1, STR_TERMINATE
);
933 rpcstr_pull(helpfile
, i1
->helpfile
.buffer
, sizeof(helpfile
), -1, STR_TERMINATE
);
934 rpcstr_pull(monitorname
, i1
->monitorname
.buffer
, sizeof(monitorname
), -1, STR_TERMINATE
);
935 rpcstr_pull(defaultdatatype
, i1
->defaultdatatype
.buffer
, sizeof(defaultdatatype
), -1, STR_TERMINATE
);
937 printf ("Printer Driver Info 3:\n");
938 printf ("\tVersion: [%x]\n", i1
->version
);
939 printf ("\tDriver Name: [%s]\n",name
);
940 printf ("\tArchitecture: [%s]\n", architecture
);
941 printf ("\tDriver Path: [%s]\n", driverpath
);
942 printf ("\tDatafile: [%s]\n", datafile
);
943 printf ("\tConfigfile: [%s]\n", configfile
);
944 printf ("\tHelpfile: [%s]\n\n", helpfile
);
948 rpcstr_pull(dependentfiles
, i1
->dependentfiles
+length
, sizeof(dependentfiles
), -1, STR_TERMINATE
);
950 length
+=strlen(dependentfiles
)+1;
952 if (strlen(dependentfiles
) > 0)
954 printf ("\tDependentfiles: [%s]\n", dependentfiles
);
964 printf ("\tMonitorname: [%s]\n", monitorname
);
965 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
970 /****************************************************************************
971 ****************************************************************************/
973 static WERROR
cmd_spoolss_getdriver(struct rpc_pipe_client
*cli
,
975 int argc
, const char **argv
)
979 uint32 info_level
= 3;
980 BOOL opened_hnd
= False
;
981 PRINTER_DRIVER_CTR ctr
;
986 BOOL success
= False
;
988 if ((argc
== 1) || (argc
> 3))
990 printf("Usage: %s <printername> [level]\n", argv
[0]);
994 /* get the arguments need to open the printer handle */
995 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
996 strupper_m(servername
);
997 fstrcpy(user
, cli
->user_name
);
998 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1000 info_level
= atoi(argv
[2]);
1002 /* Open a printer handle */
1004 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1006 servername
, user
, &pol
);
1008 if (!W_ERROR_IS_OK(werror
)) {
1009 printf("Error opening printer handle for %s!\n", printername
);
1015 /* loop through and print driver info level for each architecture */
1017 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1019 werror
= rpccli_spoolss_getprinterdriver( cli
, mem_ctx
, &pol
, info_level
,
1020 archi_table
[i
].long_archi
, archi_table
[i
].version
,
1023 if (!W_ERROR_IS_OK(werror
))
1026 /* need at least one success */
1030 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1032 switch (info_level
) {
1034 display_print_driver_1 (ctr
.info1
);
1037 display_print_driver_2 (ctr
.info2
);
1040 display_print_driver_3 (ctr
.info3
);
1043 printf("unknown info level %d\n", info_level
);
1051 rpccli_spoolss_close_printer (cli
, mem_ctx
, &pol
);
1059 /****************************************************************************
1060 ****************************************************************************/
1062 static WERROR
cmd_spoolss_enum_drivers(struct rpc_pipe_client
*cli
,
1063 TALLOC_CTX
*mem_ctx
,
1064 int argc
, const char **argv
)
1066 WERROR werror
= WERR_OK
;
1067 uint32 info_level
= 1;
1068 PRINTER_DRIVER_CTR ctr
;
1073 printf("Usage: enumdrivers [level]\n");
1078 info_level
= atoi(argv
[1]);
1081 /* loop through and print driver info level for each architecture */
1082 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++) {
1083 /* check to see if we already asked for this architecture string */
1085 if ( i
>0 && strequal(archi_table
[i
].long_archi
, archi_table
[i
-1].long_archi
) )
1088 werror
= rpccli_spoolss_enumprinterdrivers(
1089 cli
, mem_ctx
, info_level
,
1090 archi_table
[i
].long_archi
, &returned
, &ctr
);
1092 if (W_ERROR_V(werror
) == W_ERROR_V(WERR_INVALID_ENVIRONMENT
)) {
1093 printf ("Server does not support environment [%s]\n",
1094 archi_table
[i
].long_archi
);
1102 if (!W_ERROR_IS_OK(werror
)) {
1103 printf ("Error getting driver for environment [%s] - %d\n",
1104 archi_table
[i
].long_archi
, W_ERROR_V(werror
));
1108 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
1113 for (j
=0; j
< returned
; j
++) {
1114 display_print_driver_1 (&ctr
.info1
[j
]);
1118 for (j
=0; j
< returned
; j
++) {
1119 display_print_driver_2 (&ctr
.info2
[j
]);
1123 for (j
=0; j
< returned
; j
++) {
1124 display_print_driver_3 (&ctr
.info3
[j
]);
1128 printf("unknown info level %d\n", info_level
);
1129 return WERR_UNKNOWN_LEVEL
;
1136 /****************************************************************************
1137 ****************************************************************************/
1139 static void display_printdriverdir_1(DRIVER_DIRECTORY_1
*i1
)
1145 rpcstr_pull(name
, i1
->name
.buffer
, sizeof(name
), -1, STR_TERMINATE
);
1147 printf ("\tDirectory Name:[%s]\n", name
);
1150 /****************************************************************************
1151 ****************************************************************************/
1153 static WERROR
cmd_spoolss_getdriverdir(struct rpc_pipe_client
*cli
,
1154 TALLOC_CTX
*mem_ctx
,
1155 int argc
, const char **argv
)
1159 DRIVER_DIRECTORY_CTR ctr
;
1162 printf("Usage: %s [environment]\n", argv
[0]);
1166 /* Get the arguments need to open the printer handle */
1169 fstrcpy (env
, argv
[1]);
1171 fstrcpy (env
, "Windows NT x86");
1173 /* Get the directory. Only use Info level 1 */
1175 result
= rpccli_spoolss_getprinterdriverdir(cli
, mem_ctx
, 1, env
, &ctr
);
1177 if (W_ERROR_IS_OK(result
))
1178 display_printdriverdir_1(ctr
.info1
);
1183 /****************************************************************************
1184 ****************************************************************************/
1186 void set_drv_info_3_env (DRIVER_INFO_3
*info
, const char *arch
)
1191 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1193 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
1195 info
->version
= archi_table
[i
].version
;
1196 init_unistr (&info
->architecture
, archi_table
[i
].long_archi
);
1201 if (archi_table
[i
].long_archi
== NULL
)
1203 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1210 /**************************************************************************
1211 wrapper for strtok to get the next parameter from a delimited list.
1212 Needed to handle the empty parameter string denoted by "NULL"
1213 *************************************************************************/
1215 static char* get_driver_3_param (char* str
, const char* delim
, UNISTR
* dest
)
1219 /* get the next token */
1220 ptr
= strtok(str
, delim
);
1222 /* a string of 'NULL' is used to represent an empty
1223 parameter because two consecutive delimiters
1224 will not return an empty string. See man strtok(3)
1226 if (ptr
&& (StrCaseCmp(ptr
, "NULL") == 0))
1230 init_unistr(dest
, ptr
);
1235 /********************************************************************************
1236 fill in the members of a DRIVER_INFO_3 struct using a character
1237 string in the form of
1238 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1239 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1240 <Default Data Type>:<Comma Separated list of Files>
1241 *******************************************************************************/
1242 static BOOL
init_drv_info_3_members ( TALLOC_CTX
*mem_ctx
, DRIVER_INFO_3
*info
,
1248 /* fill in the UNISTR fields */
1249 str
= get_driver_3_param (args
, ":", &info
->name
);
1250 str
= get_driver_3_param (NULL
, ":", &info
->driverpath
);
1251 str
= get_driver_3_param (NULL
, ":", &info
->datafile
);
1252 str
= get_driver_3_param (NULL
, ":", &info
->configfile
);
1253 str
= get_driver_3_param (NULL
, ":", &info
->helpfile
);
1254 str
= get_driver_3_param (NULL
, ":", &info
->monitorname
);
1255 str
= get_driver_3_param (NULL
, ":", &info
->defaultdatatype
);
1257 /* <Comma Separated List of Dependent Files> */
1258 str2
= get_driver_3_param (NULL
, ":", NULL
); /* save the beginning of the string */
1261 /* begin to strip out each filename */
1262 str
= strtok(str
, ",");
1266 /* keep a cumlative count of the str lengths */
1267 len
+= strlen(str
)+1;
1268 str
= strtok(NULL
, ",");
1271 /* allocate the space; add one extra slot for a terminating NULL.
1272 Each filename is NULL terminated and the end contains a double
1274 if ((info
->dependentfiles
=TALLOC_ARRAY(mem_ctx
, uint16
, len
+1)) == NULL
)
1276 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1279 for (i
=0; i
<len
; i
++)
1281 SSVAL(&info
->dependentfiles
[i
], 0, str2
[i
]);
1283 info
->dependentfiles
[len
] = '\0';
1289 /****************************************************************************
1290 ****************************************************************************/
1292 static WERROR
cmd_spoolss_addprinterdriver(struct rpc_pipe_client
*cli
,
1293 TALLOC_CTX
*mem_ctx
,
1294 int argc
, const char **argv
)
1298 PRINTER_DRIVER_CTR ctr
;
1299 DRIVER_INFO_3 info3
;
1301 fstring driver_name
;
1304 /* parse the command arguements */
1305 if (argc
!= 3 && argc
!= 4)
1307 printf ("Usage: %s <Environment> \\\n", argv
[0]);
1308 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1309 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1310 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1311 printf ("\t[version]\n");
1316 /* Fill in the DRIVER_INFO_3 struct */
1318 if (!(arch
= cmd_spoolss_get_short_archi(argv
[1])))
1320 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1321 return WERR_INVALID_PARAM
;
1324 set_drv_info_3_env(&info3
, arch
);
1326 driver_args
= talloc_strdup( mem_ctx
, argv
[2] );
1327 if (!init_drv_info_3_members(mem_ctx
, &info3
, driver_args
))
1329 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1330 return WERR_INVALID_PARAM
;
1333 /* if printer driver version specified, override the default version
1334 * used by the architecture. This allows installation of Windows
1335 * 2000 (version 3) printer drivers. */
1338 info3
.version
= atoi(argv
[3]);
1343 result
= rpccli_spoolss_addprinterdriver (cli
, mem_ctx
, level
, &ctr
);
1345 if (W_ERROR_IS_OK(result
)) {
1346 rpcstr_pull(driver_name
, info3
.name
.buffer
,
1347 sizeof(driver_name
), -1, STR_TERMINATE
);
1348 printf ("Printer Driver %s successfully installed.\n",
1356 /****************************************************************************
1357 ****************************************************************************/
1359 static WERROR
cmd_spoolss_addprinterex(struct rpc_pipe_client
*cli
,
1360 TALLOC_CTX
*mem_ctx
,
1361 int argc
, const char **argv
)
1365 PRINTER_INFO_CTR ctr
;
1366 PRINTER_INFO_2 info2
;
1369 /* parse the command arguements */
1372 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1376 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1377 strupper_m(servername
);
1379 /* Fill in the DRIVER_INFO_2 struct */
1382 init_unistr( &info2
.printername
, argv
[1]);
1383 init_unistr( &info2
.sharename
, argv
[2]);
1384 init_unistr( &info2
.drivername
, argv
[3]);
1385 init_unistr( &info2
.portname
, argv
[4]);
1386 init_unistr( &info2
.comment
, "Created by rpcclient");
1387 init_unistr( &info2
.printprocessor
, "winprint");
1388 init_unistr( &info2
.datatype
, "RAW");
1389 info2
.devmode
= NULL
;
1390 info2
.secdesc
= NULL
;
1391 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1393 info2
.defaultpriority
= 0;
1394 info2
.starttime
= 0;
1395 info2
.untiltime
= 0;
1397 /* These three fields must not be used by AddPrinter()
1398 as defined in the MS Platform SDK documentation..
1402 info2.averageppm = 0;
1405 ctr
.printers_2
= &info2
;
1406 result
= rpccli_spoolss_addprinterex (cli
, mem_ctx
, level
, &ctr
);
1408 if (W_ERROR_IS_OK(result
))
1409 printf ("Printer %s successfully installed.\n", argv
[1]);
1414 /****************************************************************************
1415 ****************************************************************************/
1417 static WERROR
cmd_spoolss_setdriver(struct rpc_pipe_client
*cli
,
1418 TALLOC_CTX
*mem_ctx
,
1419 int argc
, const char **argv
)
1424 BOOL opened_hnd
= False
;
1425 PRINTER_INFO_CTR ctr
;
1426 PRINTER_INFO_2 info2
;
1431 /* parse the command arguements */
1434 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1438 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1439 strupper_m(servername
);
1440 slprintf(printername
, sizeof(printername
)-1, "%s\\%s", servername
, argv
[1]);
1441 fstrcpy(user
, cli
->user_name
);
1443 /* Get a printer handle */
1445 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1447 servername
, user
, &pol
);
1449 if (!W_ERROR_IS_OK(result
))
1454 /* Get printer info */
1456 ZERO_STRUCT (info2
);
1457 ctr
.printers_2
= &info2
;
1459 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, level
, &ctr
);
1461 if (!W_ERROR_IS_OK(result
)) {
1462 printf ("Unable to retrieve printer information!\n");
1466 /* Set the printer driver */
1468 init_unistr(&ctr
.printers_2
->drivername
, argv
[2]);
1470 result
= rpccli_spoolss_setprinter(cli
, mem_ctx
, &pol
, level
, &ctr
, 0);
1472 if (!W_ERROR_IS_OK(result
)) {
1473 printf("SetPrinter call failed!\n");
1477 printf("Succesfully set %s to driver %s.\n", argv
[1], argv
[2]);
1483 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
1489 /****************************************************************************
1490 ****************************************************************************/
1492 static WERROR
cmd_spoolss_deletedriverex(struct rpc_pipe_client
*cli
,
1493 TALLOC_CTX
*mem_ctx
,
1494 int argc
, const char **argv
)
1496 WERROR result
, ret
= WERR_UNKNOWN_PRINTER_DRIVER
;
1501 const char *arch
= NULL
;
1503 /* parse the command arguements */
1504 if (argc
< 2 || argc
> 4) {
1505 printf ("Usage: %s <driver> [arch] [version]\n", argv
[0]);
1512 vers
= atoi (argv
[3]);
1515 /* delete the driver for all architectures */
1516 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1518 if (arch
&& !strequal( archi_table
[i
].long_archi
, arch
))
1521 if (vers
>= 0 && archi_table
[i
].version
!= vers
)
1524 /* make the call to remove the driver */
1525 result
= rpccli_spoolss_deleteprinterdriverex(
1526 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1], archi_table
[i
].version
);
1528 if ( !W_ERROR_IS_OK(result
) )
1530 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1531 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1532 argv
[1], archi_table
[i
].long_archi
, archi_table
[i
].version
, dos_errstr(result
));
1537 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv
[1],
1538 archi_table
[i
].long_archi
, archi_table
[i
].version
);
1547 /****************************************************************************
1548 ****************************************************************************/
1550 static WERROR
cmd_spoolss_deletedriver(struct rpc_pipe_client
*cli
,
1551 TALLOC_CTX
*mem_ctx
,
1552 int argc
, const char **argv
)
1554 WERROR result
= WERR_OK
;
1558 /* parse the command arguements */
1560 printf ("Usage: %s <driver>\n", argv
[0]);
1564 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1565 strupper_m(servername
);
1567 /* delete the driver for all architectures */
1568 for (i
=0; archi_table
[i
].long_archi
; i
++) {
1569 /* make the call to remove the driver */
1570 result
= rpccli_spoolss_deleteprinterdriver(
1571 cli
, mem_ctx
, archi_table
[i
].long_archi
, argv
[1]);
1573 if ( !W_ERROR_IS_OK(result
) ) {
1574 if ( !W_ERROR_EQUAL(result
, WERR_UNKNOWN_PRINTER_DRIVER
) ) {
1575 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1576 argv
[1], archi_table
[i
].long_archi
,
1580 printf ("Driver %s removed for arch [%s].\n", argv
[1],
1581 archi_table
[i
].long_archi
);
1588 /****************************************************************************
1589 ****************************************************************************/
1591 static WERROR
cmd_spoolss_getprintprocdir(struct rpc_pipe_client
*cli
,
1592 TALLOC_CTX
*mem_ctx
,
1593 int argc
, const char **argv
)
1596 char *servername
= NULL
, *environment
= NULL
;
1599 /* parse the command arguements */
1601 printf ("Usage: %s [environment]\n", argv
[0]);
1605 if (asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
) < 0)
1607 strupper_m(servername
);
1609 if (asprintf(&environment
, "%s", (argc
== 2) ? argv
[1] :
1610 PRINTER_DRIVER_ARCHITECTURE
) < 0) {
1611 SAFE_FREE(servername
);
1615 result
= rpccli_spoolss_getprintprocessordirectory(
1616 cli
, mem_ctx
, servername
, environment
, procdir
);
1618 if (W_ERROR_IS_OK(result
))
1619 printf("%s\n", procdir
);
1621 SAFE_FREE(servername
);
1622 SAFE_FREE(environment
);
1627 /****************************************************************************
1628 ****************************************************************************/
1630 static WERROR
cmd_spoolss_addform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1631 int argc
, const char **argv
)
1635 char *servername
= NULL
, *printername
= NULL
;
1637 BOOL got_handle
= False
;
1639 /* Parse the command arguements */
1642 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1646 /* Get a printer handle */
1648 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1649 strupper_m(servername
);
1650 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1652 werror
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1654 servername
, cli
->user_name
, &handle
);
1656 if (!W_ERROR_IS_OK(werror
))
1661 /* Dummy up some values for the form data */
1663 form
.flags
= FORM_USER
;
1664 form
.size_x
= form
.size_y
= 100;
1670 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1675 werror
= rpccli_spoolss_addform(cli
, mem_ctx
, &handle
, 1, &form
);
1679 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1681 SAFE_FREE(servername
);
1682 SAFE_FREE(printername
);
1687 /****************************************************************************
1688 ****************************************************************************/
1690 static WERROR
cmd_spoolss_setform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1691 int argc
, const char **argv
)
1695 char *servername
= NULL
, *printername
= NULL
;
1697 BOOL got_handle
= False
;
1699 /* Parse the command arguements */
1702 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1706 /* Get a printer handle */
1708 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1709 strupper_m(servername
);
1710 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1712 werror
= rpccli_spoolss_open_printer_ex(
1713 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1714 servername
, cli
->user_name
, &handle
);
1716 if (!W_ERROR_IS_OK(werror
))
1721 /* Dummy up some values for the form data */
1723 form
.flags
= FORM_PRINTER
;
1724 form
.size_x
= form
.size_y
= 100;
1730 init_unistr2(&form
.name
, argv
[2], UNI_STR_TERMINATE
);
1734 werror
= rpccli_spoolss_setform(cli
, mem_ctx
, &handle
, 1, argv
[2], &form
);
1738 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1740 SAFE_FREE(servername
);
1741 SAFE_FREE(printername
);
1746 /****************************************************************************
1747 ****************************************************************************/
1749 static const char *get_form_flag(int form_flag
)
1751 switch (form_flag
) {
1755 return "FORM_BUILTIN";
1757 return "FORM_PRINTER";
1763 /****************************************************************************
1764 ****************************************************************************/
1766 static void display_form(FORM_1
*form
)
1768 fstring form_name
= "";
1770 if (form
->name
.buffer
)
1771 rpcstr_pull(form_name
, form
->name
.buffer
,
1772 sizeof(form_name
), -1, STR_TERMINATE
);
1775 "\tflag: %s (%d)\n" \
1776 "\twidth: %d, length: %d\n" \
1777 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1778 form_name
, get_form_flag(form
->flag
), form
->flag
,
1779 form
->width
, form
->length
,
1780 form
->left
, form
->right
,
1781 form
->top
, form
->bottom
);
1784 /****************************************************************************
1785 ****************************************************************************/
1787 static WERROR
cmd_spoolss_getform(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1788 int argc
, const char **argv
)
1792 char *servername
= NULL
, *printername
= NULL
;
1794 BOOL got_handle
= False
;
1796 /* Parse the command arguements */
1799 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1803 /* Get a printer handle */
1805 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1806 strupper_m(servername
);
1807 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1809 werror
= rpccli_spoolss_open_printer_ex(
1810 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1811 servername
, cli
->user_name
, &handle
);
1813 if (!W_ERROR_IS_OK(werror
))
1820 werror
= rpccli_spoolss_getform(cli
, mem_ctx
, &handle
, argv
[2], 1, &form
);
1822 if (!W_ERROR_IS_OK(werror
))
1825 display_form(&form
);
1829 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1831 SAFE_FREE(servername
);
1832 SAFE_FREE(printername
);
1837 /****************************************************************************
1838 ****************************************************************************/
1840 static WERROR
cmd_spoolss_deleteform(struct rpc_pipe_client
*cli
,
1841 TALLOC_CTX
*mem_ctx
, int argc
,
1846 char *servername
= NULL
, *printername
= NULL
;
1847 BOOL got_handle
= False
;
1849 /* Parse the command arguements */
1852 printf ("Usage: %s <printer> <formname>\n", argv
[0]);
1856 /* Get a printer handle */
1858 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1859 strupper_m(servername
);
1860 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1862 werror
= rpccli_spoolss_open_printer_ex(
1863 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1864 servername
, cli
->user_name
, &handle
);
1866 if (!W_ERROR_IS_OK(werror
))
1871 /* Delete the form */
1873 werror
= rpccli_spoolss_deleteform(cli
, mem_ctx
, &handle
, argv
[2]);
1877 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1879 SAFE_FREE(servername
);
1880 SAFE_FREE(printername
);
1885 /****************************************************************************
1886 ****************************************************************************/
1888 static WERROR
cmd_spoolss_enum_forms(struct rpc_pipe_client
*cli
,
1889 TALLOC_CTX
*mem_ctx
, int argc
,
1894 char *servername
= NULL
, *printername
= NULL
;
1895 BOOL got_handle
= False
;
1896 uint32 num_forms
, level
= 1, i
;
1899 /* Parse the command arguements */
1902 printf ("Usage: %s <printer>\n", argv
[0]);
1906 /* Get a printer handle */
1908 asprintf(&servername
, "\\\\%s", cli
->cli
->desthost
);
1909 strupper_m(servername
);
1910 asprintf(&printername
, "%s\\%s", servername
, argv
[1]);
1912 werror
= rpccli_spoolss_open_printer_ex(
1913 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
1914 servername
, cli
->user_name
, &handle
);
1916 if (!W_ERROR_IS_OK(werror
))
1921 /* Enumerate forms */
1923 werror
= rpccli_spoolss_enumforms(cli
, mem_ctx
, &handle
, level
, &num_forms
, &forms
);
1925 if (!W_ERROR_IS_OK(werror
))
1928 /* Display output */
1930 for (i
= 0; i
< num_forms
; i
++) {
1932 display_form(&forms
[i
]);
1938 rpccli_spoolss_close_printer(cli
, mem_ctx
, &handle
);
1940 SAFE_FREE(servername
);
1941 SAFE_FREE(printername
);
1946 /****************************************************************************
1947 ****************************************************************************/
1949 static WERROR
cmd_spoolss_setprinterdata(struct rpc_pipe_client
*cli
,
1950 TALLOC_CTX
*mem_ctx
,
1951 int argc
, const char **argv
)
1954 fstring servername
, printername
, user
;
1956 BOOL opened_hnd
= False
;
1957 PRINTER_INFO_CTR ctr
;
1958 PRINTER_INFO_0 info
;
1959 REGISTRY_VALUE value
;
1961 /* parse the command arguements */
1963 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
1964 " <value> <data>\n",
1966 return WERR_INVALID_PARAM
;
1969 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
1970 strupper_m(servername
);
1971 slprintf(printername
, sizeof(servername
)-1, "%s\\%s", servername
, argv
[1]);
1972 fstrcpy(user
, cli
->user_name
);
1974 value
.type
= REG_NONE
;
1976 if (strequal(argv
[2], "string")) {
1977 value
.type
= REG_SZ
;
1980 if (strequal(argv
[2], "binary")) {
1981 value
.type
= REG_BINARY
;
1984 if (strequal(argv
[2], "dword")) {
1985 value
.type
= REG_DWORD
;
1988 if (strequal(argv
[2], "multistring")) {
1989 value
.type
= REG_MULTI_SZ
;
1992 if (value
.type
== REG_NONE
) {
1993 printf("Unknown data type: %s\n", argv
[2]);
1994 return WERR_INVALID_PARAM
;
1997 /* get a printer handle */
1998 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1999 MAXIMUM_ALLOWED_ACCESS
, servername
,
2001 if (!W_ERROR_IS_OK(result
))
2006 ctr
.printers_0
= &info
;
2008 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2010 if (!W_ERROR_IS_OK(result
))
2013 printf("%s\n", current_timestring(True
));
2014 printf("\tchange_id (before set)\t:[0x%x]\n", info
.change_id
);
2016 /* Set the printer data */
2018 fstrcpy(value
.valuename
, argv
[3]);
2020 switch (value
.type
) {
2023 init_unistr2(&data
, argv
[4], UNI_STR_TERMINATE
);
2024 value
.size
= data
.uni_str_len
* 2;
2026 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, data
.buffer
,
2029 value
.data_p
= NULL
;
2034 uint32 data
= strtoul(argv
[4], NULL
, 10);
2035 value
.size
= sizeof(data
);
2037 value
.data_p
= (uint8
*)TALLOC_MEMDUP(mem_ctx
, &data
,
2040 value
.data_p
= NULL
;
2045 DATA_BLOB data
= strhex_to_data_blob(mem_ctx
, argv
[4]);
2046 value
.data_p
= data
.data
;
2047 value
.size
= data
.length
;
2050 case REG_MULTI_SZ
: {
2055 for (i
=4; i
<argc
; i
++) {
2056 if (strcmp(argv
[i
], "NULL") == 0) {
2059 len
+= strlen(argv
[i
])+1;
2063 value
.data_p
= TALLOC_ARRAY(mem_ctx
, unsigned char, value
.size
);
2064 if (value
.data_p
== NULL
) {
2065 result
= WERR_NOMEM
;
2069 p
= (char *)value
.data_p
;
2071 for (i
=4; i
<argc
; i
++) {
2072 size_t l
= (strlen(argv
[i
])+1)*2;
2073 rpcstr_push(p
, argv
[i
], len
, STR_TERMINATE
);
2077 SMB_ASSERT(len
== 0);
2081 printf("Unknown data type: %s\n", argv
[2]);
2082 result
= WERR_INVALID_PARAM
;
2086 result
= rpccli_spoolss_setprinterdata(cli
, mem_ctx
, &pol
, &value
);
2088 if (!W_ERROR_IS_OK(result
)) {
2089 printf ("Unable to set [%s=%s]!\n", argv
[3], argv
[4]);
2092 printf("\tSetPrinterData succeeded [%s: %s]\n", argv
[3], argv
[4]);
2094 result
= rpccli_spoolss_getprinter(cli
, mem_ctx
, &pol
, 0, &ctr
);
2096 if (!W_ERROR_IS_OK(result
))
2099 printf("%s\n", current_timestring(True
));
2100 printf("\tchange_id (after set)\t:[0x%x]\n", info
.change_id
);
2105 rpccli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
2110 /****************************************************************************
2111 ****************************************************************************/
2113 static void display_job_info_1(JOB_INFO_1
*job
)
2115 fstring username
= "", document
= "", text_status
= "";
2117 rpcstr_pull(username
, job
->username
.buffer
,
2118 sizeof(username
), -1, STR_TERMINATE
);
2120 rpcstr_pull(document
, job
->document
.buffer
,
2121 sizeof(document
), -1, STR_TERMINATE
);
2123 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2124 sizeof(text_status
), -1, STR_TERMINATE
);
2126 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job
->position
, job
->jobid
,
2127 username
, document
, text_status
, job
->pagesprinted
,
2131 /****************************************************************************
2132 ****************************************************************************/
2134 static void display_job_info_2(JOB_INFO_2
*job
)
2136 fstring username
= "", document
= "", text_status
= "";
2138 rpcstr_pull(username
, job
->username
.buffer
,
2139 sizeof(username
), -1, STR_TERMINATE
);
2141 rpcstr_pull(document
, job
->document
.buffer
,
2142 sizeof(document
), -1, STR_TERMINATE
);
2144 rpcstr_pull(text_status
, job
->text_status
.buffer
,
2145 sizeof(text_status
), -1, STR_TERMINATE
);
2147 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job
->position
, job
->jobid
,
2148 username
, document
, text_status
, job
->pagesprinted
,
2149 job
->totalpages
, job
->size
);
2152 /****************************************************************************
2153 ****************************************************************************/
2155 static WERROR
cmd_spoolss_enum_jobs(struct rpc_pipe_client
*cli
,
2156 TALLOC_CTX
*mem_ctx
, int argc
,
2160 uint32 level
= 1, num_jobs
, i
;
2161 BOOL got_hnd
= False
;
2162 pstring printername
;
2163 fstring servername
, user
;
2167 if (argc
< 2 || argc
> 3) {
2168 printf("Usage: %s printername [level]\n", argv
[0]);
2173 level
= atoi(argv
[2]);
2175 /* Open printer handle */
2177 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2178 strupper_m(servername
);
2179 fstrcpy(user
, cli
->user_name
);
2180 slprintf(printername
, sizeof(servername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2181 strupper_m(printername
);
2182 pstrcat(printername
, argv
[1]);
2184 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2185 "", MAXIMUM_ALLOWED_ACCESS
,
2186 servername
, user
, &hnd
);
2188 if (!W_ERROR_IS_OK(result
))
2193 /* Enumerate ports */
2195 result
= rpccli_spoolss_enumjobs(cli
, mem_ctx
, &hnd
, level
, 0, 1000,
2198 if (!W_ERROR_IS_OK(result
))
2201 for (i
= 0; i
< num_jobs
; i
++) {
2204 display_job_info_1(&ctr
.job
.job_info_1
[i
]);
2207 display_job_info_2(&ctr
.job
.job_info_2
[i
]);
2210 d_printf("unknown info level %d\n", level
);
2217 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2222 /****************************************************************************
2223 ****************************************************************************/
2225 static WERROR
cmd_spoolss_enum_data( struct rpc_pipe_client
*cli
,
2226 TALLOC_CTX
*mem_ctx
, int argc
,
2230 uint32 i
=0, val_needed
, data_needed
;
2231 BOOL got_hnd
= False
;
2232 pstring printername
;
2233 fstring servername
, user
;
2237 printf("Usage: %s printername\n", argv
[0]);
2241 /* Open printer handle */
2243 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2244 strupper_m(servername
);
2245 fstrcpy(user
, cli
->user_name
);
2246 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2247 strupper_m(printername
);
2248 pstrcat(printername
, argv
[1]);
2250 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2251 "", MAXIMUM_ALLOWED_ACCESS
,
2252 servername
, user
, &hnd
);
2254 if (!W_ERROR_IS_OK(result
))
2259 /* Enumerate data */
2261 result
= rpccli_spoolss_enumprinterdata(cli
, mem_ctx
, &hnd
, i
, 0, 0,
2262 &val_needed
, &data_needed
,
2264 while (W_ERROR_IS_OK(result
)) {
2265 REGISTRY_VALUE value
;
2266 result
= rpccli_spoolss_enumprinterdata(
2267 cli
, mem_ctx
, &hnd
, i
++, val_needed
,
2268 data_needed
, 0, 0, &value
);
2269 if (W_ERROR_IS_OK(result
))
2270 display_reg_value(value
);
2272 if (W_ERROR_V(result
) == ERRnomoreitems
)
2273 result
= W_ERROR(ERRsuccess
);
2277 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2282 /****************************************************************************
2283 ****************************************************************************/
2285 static WERROR
cmd_spoolss_enum_data_ex( struct rpc_pipe_client
*cli
,
2286 TALLOC_CTX
*mem_ctx
, int argc
,
2291 BOOL got_hnd
= False
;
2292 pstring printername
;
2293 fstring servername
, user
;
2294 const char *keyname
= NULL
;
2296 REGVAL_CTR
*ctr
= NULL
;
2299 printf("Usage: %s printername <keyname>\n", argv
[0]);
2305 /* Open printer handle */
2307 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2308 strupper_m(servername
);
2309 fstrcpy(user
, cli
->user_name
);
2310 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2311 strupper_m(printername
);
2312 pstrcat(printername
, argv
[1]);
2314 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2315 "", MAXIMUM_ALLOWED_ACCESS
,
2316 servername
, user
, &hnd
);
2318 if (!W_ERROR_IS_OK(result
))
2323 /* Enumerate subkeys */
2325 if ( !(ctr
= TALLOC_ZERO_P( mem_ctx
, REGVAL_CTR
)) )
2328 result
= rpccli_spoolss_enumprinterdataex(cli
, mem_ctx
, &hnd
, keyname
, ctr
);
2330 if (!W_ERROR_IS_OK(result
))
2333 for (i
=0; i
< ctr
->num_values
; i
++) {
2334 display_reg_value(*(ctr
->values
[i
]));
2341 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2346 /****************************************************************************
2347 ****************************************************************************/
2349 static WERROR
cmd_spoolss_enum_printerkey( struct rpc_pipe_client
*cli
,
2350 TALLOC_CTX
*mem_ctx
, int argc
,
2354 BOOL got_hnd
= False
;
2355 pstring printername
;
2356 fstring servername
, user
;
2357 const char *keyname
= NULL
;
2359 uint16
*keylist
= NULL
, *curkey
;
2361 if (argc
< 2 || argc
> 3) {
2362 printf("Usage: %s printername [keyname]\n", argv
[0]);
2371 /* Open printer handle */
2373 slprintf(servername
, sizeof(servername
)-1, "\\\\%s", cli
->cli
->desthost
);
2374 strupper_m(servername
);
2375 fstrcpy(user
, cli
->user_name
);
2376 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\", cli
->cli
->desthost
);
2377 strupper_m(printername
);
2378 pstrcat(printername
, argv
[1]);
2380 result
= rpccli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
,
2381 "", MAXIMUM_ALLOWED_ACCESS
,
2382 servername
, user
, &hnd
);
2384 if (!W_ERROR_IS_OK(result
))
2389 /* Enumerate subkeys */
2391 result
= rpccli_spoolss_enumprinterkey(cli
, mem_ctx
, &hnd
, keyname
, &keylist
, NULL
);
2393 if (!W_ERROR_IS_OK(result
))
2397 while (*curkey
!= 0) {
2399 rpcstr_pull(subkey
, curkey
, sizeof(subkey
), -1,
2401 printf("%s\n", subkey
);
2402 curkey
+= strlen(subkey
) + 1;
2410 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2415 /****************************************************************************
2416 ****************************************************************************/
2418 static WERROR
cmd_spoolss_rffpcnex(struct rpc_pipe_client
*cli
,
2419 TALLOC_CTX
*mem_ctx
, int argc
,
2422 fstring servername
, printername
;
2424 BOOL got_hnd
= False
;
2426 SPOOL_NOTIFY_OPTION option
;
2429 printf("Usage: %s printername\n", argv
[0]);
2436 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", cli
->cli
->desthost
);
2437 strupper_m(servername
);
2439 slprintf(printername
, sizeof(printername
) - 1, "\\\\%s\\%s", cli
->cli
->desthost
,
2441 strupper_m(printername
);
2443 result
= rpccli_spoolss_open_printer_ex(
2444 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
,
2445 servername
, cli
->user_name
, &hnd
);
2447 if (!W_ERROR_IS_OK(result
)) {
2448 printf("Error opening %s\n", argv
[1]);
2454 /* Create spool options */
2456 ZERO_STRUCT(option
);
2459 option
.option_type_ptr
= 1;
2460 option
.count
= option
.ctr
.count
= 2;
2462 option
.ctr
.type
= TALLOC_ARRAY(mem_ctx
, SPOOL_NOTIFY_OPTION_TYPE
, 2);
2463 if (option
.ctr
.type
== NULL
) {
2464 result
= WERR_NOMEM
;
2468 ZERO_STRUCT(option
.ctr
.type
[0]);
2469 option
.ctr
.type
[0].type
= PRINTER_NOTIFY_TYPE
;
2470 option
.ctr
.type
[0].count
= option
.ctr
.type
[0].count2
= 1;
2471 option
.ctr
.type
[0].fields_ptr
= 1;
2472 option
.ctr
.type
[0].fields
[0] = PRINTER_NOTIFY_SERVER_NAME
;
2474 ZERO_STRUCT(option
.ctr
.type
[1]);
2475 option
.ctr
.type
[1].type
= JOB_NOTIFY_TYPE
;
2476 option
.ctr
.type
[1].count
= option
.ctr
.type
[1].count2
= 1;
2477 option
.ctr
.type
[1].fields_ptr
= 1;
2478 option
.ctr
.type
[1].fields
[0] = JOB_NOTIFY_PRINTER_NAME
;
2482 slprintf(servername
, sizeof(servername
) - 1, "\\\\%s", myhostname());
2483 strupper_m(servername
);
2485 result
= rpccli_spoolss_rffpcnex(
2486 cli
, mem_ctx
, &hnd
, 0, 0, servername
, 123, &option
);
2488 if (!W_ERROR_IS_OK(result
)) {
2489 printf("Error rffpcnex %s\n", argv
[1]);
2495 rpccli_spoolss_close_printer(cli
, mem_ctx
, &hnd
);
2500 /****************************************************************************
2501 ****************************************************************************/
2503 static BOOL
compare_printer( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2504 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2506 PRINTER_INFO_CTR ctr1
, ctr2
;
2508 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer");
2510 printf("Retrieving printer propertiesfor %s...", cli1
->cli
->desthost
);
2511 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 2, &ctr1
);
2512 if ( !W_ERROR_IS_OK(werror
) ) {
2513 printf("failed (%s)\n", dos_errstr(werror
));
2514 talloc_destroy(mem_ctx
);
2519 printf("Retrieving printer properties for %s...", cli2
->cli
->desthost
);
2520 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 2, &ctr2
);
2521 if ( !W_ERROR_IS_OK(werror
) ) {
2522 printf("failed (%s)\n", dos_errstr(werror
));
2523 talloc_destroy(mem_ctx
);
2528 talloc_destroy(mem_ctx
);
2533 /****************************************************************************
2534 ****************************************************************************/
2536 static BOOL
compare_printer_secdesc( struct rpc_pipe_client
*cli1
, POLICY_HND
*hnd1
,
2537 struct rpc_pipe_client
*cli2
, POLICY_HND
*hnd2
)
2539 PRINTER_INFO_CTR ctr1
, ctr2
;
2541 TALLOC_CTX
*mem_ctx
= talloc_init("compare_printer_secdesc");
2542 SEC_DESC
*sd1
, *sd2
;
2546 printf("Retreiving printer security for %s...", cli1
->cli
->desthost
);
2547 werror
= rpccli_spoolss_getprinter( cli1
, mem_ctx
, hnd1
, 3, &ctr1
);
2548 if ( !W_ERROR_IS_OK(werror
) ) {
2549 printf("failed (%s)\n", dos_errstr(werror
));
2555 printf("Retrieving printer security for %s...", cli2
->cli
->desthost
);
2556 werror
= rpccli_spoolss_getprinter( cli2
, mem_ctx
, hnd2
, 3, &ctr2
);
2557 if ( !W_ERROR_IS_OK(werror
) ) {
2558 printf("failed (%s)\n", dos_errstr(werror
));
2567 if ( (ctr1
.printers_3
!= ctr2
.printers_3
) && (!ctr1
.printers_3
|| !ctr2
.printers_3
) ) {
2568 printf("NULL PRINTER_INFO_3!\n");
2573 sd1
= ctr1
.printers_3
->secdesc
;
2574 sd2
= ctr2
.printers_3
->secdesc
;
2576 if ( (sd1
!= sd2
) && ( !sd1
|| !sd2
) ) {
2577 printf("NULL secdesc!\n");
2582 if (!sec_desc_equal( sd1
, sd2
) ) {
2583 printf("Security Descriptors *not* equal!\n");
2588 printf("Security descriptors match\n");
2591 talloc_destroy(mem_ctx
);
2596 /****************************************************************************
2597 ****************************************************************************/
2599 static WERROR
cmd_spoolss_printercmp(struct rpc_pipe_client
*cli
,
2600 TALLOC_CTX
*mem_ctx
, int argc
,
2603 fstring printername
, servername1
, servername2
;
2604 pstring printername_path
;
2605 struct cli_state
*cli_server1
= cli
->cli
;
2606 struct cli_state
*cli_server2
= NULL
;
2607 struct rpc_pipe_client
*cli2
= NULL
;
2608 POLICY_HND hPrinter1
, hPrinter2
;
2613 printf("Usage: %s <printer> <server>\n", argv
[0]);
2617 fstrcpy( printername
, argv
[1] );
2619 fstrcpy( servername1
, cli
->cli
->desthost
);
2620 fstrcpy( servername2
, argv
[2] );
2621 strupper_m( servername1
);
2622 strupper_m( servername2
);
2625 /* first get the connection to the remote server */
2627 nt_status
= cli_full_connection(&cli_server2
, global_myname(), servername2
,
2630 cmdline_auth_info
.username
,
2632 cmdline_auth_info
.password
,
2633 cmdline_auth_info
.use_kerberos
? CLI_FULL_CONNECTION_USE_KERBEROS
: 0,
2634 cmdline_auth_info
.signing_state
, NULL
);
2636 if ( !NT_STATUS_IS_OK(nt_status
) )
2637 return WERR_GENERAL_FAILURE
;
2639 cli2
= cli_rpc_pipe_open_noauth(cli_server2
, PI_SPOOLSS
, &nt_status
);
2641 printf("failed to open spoolss pipe on server %s (%s)\n",
2642 servername2
, nt_errstr(nt_status
));
2643 return WERR_GENERAL_FAILURE
;
2646 /* now open up both printers */
2648 pstr_sprintf( printername_path
, "\\\\%s\\%s", servername1
, printername
);
2649 printf("Opening %s...", printername_path
);
2650 werror
= rpccli_spoolss_open_printer_ex( cli
, mem_ctx
, printername_path
,
2651 "", PRINTER_ALL_ACCESS
, servername1
, cli_server1
->user_name
, &hPrinter1
);
2652 if ( !W_ERROR_IS_OK(werror
) ) {
2653 printf("failed (%s)\n", dos_errstr(werror
));
2658 pstr_sprintf( printername_path
, "\\\\%s\\%s", servername2
, printername
);
2659 printf("Opening %s...", printername_path
);
2660 werror
= rpccli_spoolss_open_printer_ex( cli2
, mem_ctx
, printername_path
,
2661 "", PRINTER_ALL_ACCESS
, servername2
, cli_server2
->user_name
, &hPrinter2
);
2662 if ( !W_ERROR_IS_OK(werror
) ) {
2663 printf("failed (%s)\n", dos_errstr(werror
));
2669 compare_printer( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2670 compare_printer_secdesc( cli
, &hPrinter1
, cli2
, &hPrinter2
);
2672 compare_printerdata( cli_server1
, &hPrinter1
, cli_server2
, &hPrinter2
);
2679 printf("Closing printers...");
2680 rpccli_spoolss_close_printer( cli
, mem_ctx
, &hPrinter1
);
2681 rpccli_spoolss_close_printer( cli2
, mem_ctx
, &hPrinter2
);
2684 /* close the second remote connection */
2686 cli_shutdown( cli_server2
);
2691 /* List of commands exported by this module */
2692 struct cmd_set spoolss_commands
[] = {
2696 { "adddriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterdriver
, PI_SPOOLSS
, NULL
, "Add a print driver", "" },
2697 { "addprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addprinterex
, PI_SPOOLSS
, NULL
, "Add a printer", "" },
2698 { "deldriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriver
, PI_SPOOLSS
, NULL
, "Delete a printer driver", "" },
2699 { "deldriverex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deletedriverex
, PI_SPOOLSS
, NULL
, "Delete a printer driver with files", "" },
2700 { "enumdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data
, PI_SPOOLSS
, NULL
, "Enumerate printer data", "" },
2701 { "enumdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_data_ex
, PI_SPOOLSS
, NULL
, "Enumerate printer data for a key", "" },
2702 { "enumkey", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printerkey
, PI_SPOOLSS
, NULL
, "Enumerate printer keys", "" },
2703 { "enumjobs", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_jobs
, PI_SPOOLSS
, NULL
, "Enumerate print jobs", "" },
2704 { "enumports", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_ports
, PI_SPOOLSS
, NULL
, "Enumerate printer ports", "" },
2705 { "enumdrivers", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_drivers
, PI_SPOOLSS
, NULL
, "Enumerate installed printer drivers", "" },
2706 { "enumprinters", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_printers
, PI_SPOOLSS
, NULL
, "Enumerate printers", "" },
2707 { "getdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdata
, PI_SPOOLSS
, NULL
, "Get print driver data", "" },
2708 { "getdataex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinterdataex
, PI_SPOOLSS
, NULL
, "Get printer driver data with keyname", ""},
2709 { "getdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriver
, PI_SPOOLSS
, NULL
, "Get print driver information", "" },
2710 { "getdriverdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getdriverdir
, PI_SPOOLSS
, NULL
, "Get print driver upload directory", "" },
2711 { "getprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprinter
, PI_SPOOLSS
, NULL
, "Get printer info", "" },
2712 { "openprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_open_printer_ex
, PI_SPOOLSS
, NULL
, "Open printer handle", "" },
2713 { "setdriver", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setdriver
, PI_SPOOLSS
, NULL
, "Set printer driver", "" },
2714 { "getprintprocdir", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getprintprocdir
, PI_SPOOLSS
, NULL
, "Get print processor directory", "" },
2715 { "addform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_addform
, PI_SPOOLSS
, NULL
, "Add form", "" },
2716 { "setform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setform
, PI_SPOOLSS
, NULL
, "Set form", "" },
2717 { "getform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_getform
, PI_SPOOLSS
, NULL
, "Get form", "" },
2718 { "deleteform", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_deleteform
, PI_SPOOLSS
, NULL
, "Delete form", "" },
2719 { "enumforms", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_enum_forms
, PI_SPOOLSS
, NULL
, "Enumerate forms", "" },
2720 { "setprinter", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinter
, PI_SPOOLSS
, NULL
, "Set printer comment", "" },
2721 { "setprintername", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprintername
, PI_SPOOLSS
, NULL
, "Set printername", "" },
2722 { "setprinterdata", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_setprinterdata
, PI_SPOOLSS
, NULL
, "Set REG_SZ printer data", "" },
2723 { "rffpcnex", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_rffpcnex
, PI_SPOOLSS
, NULL
, "Rffpcnex test", "" },
2724 { "printercmp", RPC_RTYPE_WERROR
, NULL
, cmd_spoolss_printercmp
, PI_SPOOLSS
, NULL
, "Printer comparison test", "" },