2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
9 Copyright (C) Guenther Deschner 2009
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "rpcclient.h"
28 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
30 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
31 _cli->srv_name_slash, _arg); \
32 W_ERROR_HAVE_NO_MEMORY(_printername); \
36 const char *long_archi;
37 const char *short_archi;
41 /* The version int is used by getdrivers. Note that
42 all architecture strings that support mutliple
43 versions must be grouped together since enumdrivers
44 uses this property to prevent issuing multiple
45 enumdriver calls for the same arch */
48 static const struct table_node archi_table[]= {
50 {"Windows 4.0", "WIN40", 0 },
51 {"Windows NT x86", "W32X86", 2 },
52 {"Windows NT x86", "W32X86", 3 },
53 {"Windows NT R4000", "W32MIPS", 2 },
54 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
55 {"Windows NT PowerPC", "W32PPC", 2 },
56 {"Windows IA64", "IA64", 3 },
57 {"Windows x64", "x64", 3 },
64 * rpcclient module for SPOOLSS rpc pipe.
66 * This generally just parses and checks command lines, and then calls
67 * a cli_spoolss function.
70 /****************************************************************************
71 function to do the mapping between the long architecture name and
73 ****************************************************************************/
75 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
79 DEBUG(107,("Getting architecture dependant directory\n"));
82 } while ( (archi_table[i].long_archi!=NULL ) &&
83 StrCaseCmp(long_archi, archi_table[i].long_archi) );
85 if (archi_table[i].long_archi==NULL) {
86 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
90 /* this might be client code - but shouldn't this be an fstrcpy etc? */
93 DEBUGADD(108,("index: [%d]\n", i));
94 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
95 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
97 return archi_table[i].short_archi;
100 /****************************************************************************
101 ****************************************************************************/
103 static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
105 int argc, const char **argv)
108 struct policy_handle hnd;
111 printf("Usage: %s <printername>\n", argv[0]);
116 return WERR_GENERAL_FAILURE;
118 /* Open the printer handle */
120 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
124 if (W_ERROR_IS_OK(werror)) {
125 printf("Printer %s opened successfully\n", argv[1]);
126 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, &werror);
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_info0(struct spoolss_PrinterInfo0 *r)
146 printf("\tprintername:[%s]\n", r->printername);
147 printf("\tservername:[%s]\n", r->servername);
148 printf("\tcjobs:[0x%x]\n", r->cjobs);
149 printf("\ttotal_jobs:[0x%x]\n", r->total_jobs);
150 printf("\ttotal_bytes:[0x%x]\n", r->total_bytes);
151 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", r->time.year, r->time.month,
152 r->time.day, r->time.day_of_week);
153 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", r->time.hour, r->time.minute,
154 r->time.second, r->time.millisecond);
156 printf("\tglobal_counter:[0x%x]\n", r->global_counter);
157 printf("\ttotal_pages:[0x%x]\n", r->total_pages);
159 printf("\tversion:[0x%x]\n", r->version);
160 printf("\tfree_build:[0x%x]\n", r->free_build);
161 printf("\tspooling:[0x%x]\n", r->spooling);
162 printf("\tmax_spooling:[0x%x]\n", r->max_spooling);
163 printf("\tsession_counter:[0x%x]\n", r->session_counter);
164 printf("\tnum_error_out_of_paper:[0x%x]\n", r->num_error_out_of_paper);
165 printf("\tnum_error_not_ready:[0x%x]\n", r->num_error_not_ready);
166 printf("\tjob_error:[0x%x]\n", r->job_error);
167 printf("\tnumber_of_processors:[0x%x]\n", r->number_of_processors);
168 printf("\tprocessor_type:[0x%x]\n", r->processor_type);
169 printf("\thigh_part_total_bytes:[0x%x]\n", r->high_part_total_bytes);
170 printf("\tchange_id:[0x%x]\n", r->change_id);
171 printf("\tlast_error: %s\n", win_errstr(r->last_error));
172 printf("\tstatus:[0x%x]\n", r->status);
173 printf("\tenumerate_network_printers:[0x%x]\n", r->enumerate_network_printers);
174 printf("\tc_setprinter:[0x%x]\n", r->c_setprinter);
175 printf("\tprocessor_architecture:[0x%x]\n", r->processor_architecture);
176 printf("\tprocessor_level:[0x%x]\n", r->processor_level);
177 printf("\tref_ic:[0x%x]\n", r->ref_ic);
178 printf("\treserved2:[0x%x]\n", r->reserved2);
179 printf("\treserved3:[0x%x]\n", r->reserved3);
184 /****************************************************************************
185 ****************************************************************************/
187 static void display_print_info1(struct spoolss_PrinterInfo1 *r)
189 printf("\tflags:[0x%x]\n", r->flags);
190 printf("\tname:[%s]\n", r->name);
191 printf("\tdescription:[%s]\n", r->description);
192 printf("\tcomment:[%s]\n", r->comment);
197 /****************************************************************************
198 ****************************************************************************/
200 static void display_print_info2(struct spoolss_PrinterInfo2 *r)
202 printf("\tservername:[%s]\n", r->servername);
203 printf("\tprintername:[%s]\n", r->printername);
204 printf("\tsharename:[%s]\n", r->sharename);
205 printf("\tportname:[%s]\n", r->portname);
206 printf("\tdrivername:[%s]\n", r->drivername);
207 printf("\tcomment:[%s]\n", r->comment);
208 printf("\tlocation:[%s]\n", r->location);
209 printf("\tsepfile:[%s]\n", r->sepfile);
210 printf("\tprintprocessor:[%s]\n", r->printprocessor);
211 printf("\tdatatype:[%s]\n", r->datatype);
212 printf("\tparameters:[%s]\n", r->parameters);
213 printf("\tattributes:[0x%x]\n", r->attributes);
214 printf("\tpriority:[0x%x]\n", r->priority);
215 printf("\tdefaultpriority:[0x%x]\n", r->defaultpriority);
216 printf("\tstarttime:[0x%x]\n", r->starttime);
217 printf("\tuntiltime:[0x%x]\n", r->untiltime);
218 printf("\tstatus:[0x%x]\n", r->status);
219 printf("\tcjobs:[0x%x]\n", r->cjobs);
220 printf("\taverageppm:[0x%x]\n", r->averageppm);
223 display_sec_desc(r->secdesc);
228 /****************************************************************************
229 ****************************************************************************/
231 static void display_print_info3(struct spoolss_PrinterInfo3 *r)
233 display_sec_desc(r->secdesc);
238 /****************************************************************************
239 ****************************************************************************/
241 static void display_print_info4(struct spoolss_PrinterInfo4 *r)
243 printf("\tservername:[%s]\n", r->servername);
244 printf("\tprintername:[%s]\n", r->printername);
245 printf("\tattributes:[0x%x]\n", r->attributes);
249 /****************************************************************************
250 ****************************************************************************/
252 static void display_print_info5(struct spoolss_PrinterInfo5 *r)
254 printf("\tprintername:[%s]\n", r->printername);
255 printf("\tportname:[%s]\n", r->portname);
256 printf("\tattributes:[0x%x]\n", r->attributes);
257 printf("\tdevice_not_selected_timeout:[0x%x]\n", r->device_not_selected_timeout);
258 printf("\ttransmission_retry_timeout:[0x%x]\n", r->transmission_retry_timeout);
262 /****************************************************************************
263 ****************************************************************************/
265 static void display_print_info6(struct spoolss_PrinterInfo6 *r)
267 printf("\tstatus:[0x%x]\n", r->status);
271 /****************************************************************************
272 ****************************************************************************/
274 static void display_print_info7(struct spoolss_PrinterInfo7 *r)
276 printf("\tguid:[%s]\n", r->guid);
277 printf("\taction:[0x%x]\n", r->action);
281 /****************************************************************************
282 ****************************************************************************/
284 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
286 int argc, const char **argv)
290 union spoolss_PrinterInfo *info;
293 uint32_t flags = PRINTER_ENUM_LOCAL;
296 printf("Usage: %s [level] [name] [flags]\n", argv[0]);
301 level = atoi(argv[1]);
307 name = cli->srv_name_slash;
311 flags = atoi(argv[3]);
314 result = rpccli_spoolss_enumprinters(cli, mem_ctx,
321 if (W_ERROR_IS_OK(result)) {
324 printf ("No printers returned.\n");
328 for (i = 0; i < count; i++) {
331 display_print_info0(&info[i].info0);
334 display_print_info1(&info[i].info1);
337 display_print_info2(&info[i].info2);
340 display_print_info3(&info[i].info3);
343 display_print_info4(&info[i].info4);
346 display_print_info5(&info[i].info5);
349 display_print_info6(&info[i].info6);
352 printf("unknown info level %d\n", level);
362 /****************************************************************************
363 ****************************************************************************/
365 static void display_port_info_1(struct spoolss_PortInfo1 *r)
367 printf("\tPort Name:\t[%s]\n", r->port_name);
370 /****************************************************************************
371 ****************************************************************************/
373 static void display_port_info_2(struct spoolss_PortInfo2 *r)
375 printf("\tPort Name:\t[%s]\n", r->port_name);
376 printf("\tMonitor Name:\t[%s]\n", r->monitor_name);
377 printf("\tDescription:\t[%s]\n", r->description);
378 printf("\tPort Type:\t" );
380 int comma = 0; /* hack */
382 if (r->port_type & SPOOLSS_PORT_TYPE_READ) {
386 if (r->port_type & SPOOLSS_PORT_TYPE_WRITE) {
387 printf( "%sWrite", comma ? ", " : "" );
390 /* These two have slightly different interpretations
391 on 95/98/ME but I'm disregarding that for now */
392 if (r->port_type & SPOOLSS_PORT_TYPE_REDIRECTED) {
393 printf( "%sRedirected", comma ? ", " : "" );
396 if (r->port_type & SPOOLSS_PORT_TYPE_NET_ATTACHED) {
397 printf( "%sNet-Attached", comma ? ", " : "" );
401 printf( "[Unset]\n" );
403 printf("\tReserved:\t[%d]\n", r->reserved);
407 /****************************************************************************
408 ****************************************************************************/
410 static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
411 TALLOC_CTX *mem_ctx, int argc,
417 union spoolss_PortInfo *info;
420 printf("Usage: %s [level]\n", argv[0]);
425 level = atoi(argv[1]);
428 /* Enumerate ports */
430 result = rpccli_spoolss_enumports(cli, mem_ctx,
436 if (W_ERROR_IS_OK(result)) {
439 for (i = 0; i < count; i++) {
442 display_port_info_1(&info[i].info1);
445 display_port_info_2(&info[i].info2);
448 printf("unknown info level %d\n", level);
457 /****************************************************************************
458 ****************************************************************************/
460 static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
462 int argc, const char **argv)
464 struct policy_handle pol;
467 uint32_t info_level = 2;
468 union spoolss_PrinterInfo info;
469 struct spoolss_SetPrinterInfoCtr info_ctr;
470 const char *printername, *comment = NULL;
471 struct spoolss_DevmodeContainer devmode_ctr;
472 struct sec_desc_buf secdesc_ctr;
474 if (argc == 1 || argc > 3) {
475 printf("Usage: %s printername comment\n", argv[0]);
480 /* Open a printer handle */
485 ZERO_STRUCT(devmode_ctr);
486 ZERO_STRUCT(secdesc_ctr);
488 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
490 /* get a printer handle */
491 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
495 if (!W_ERROR_IS_OK(result))
498 /* Get printer info */
499 result = rpccli_spoolss_getprinter(cli, mem_ctx,
504 if (!W_ERROR_IS_OK(result))
508 /* Modify the comment. */
509 info.info2.comment = comment;
510 info.info2.secdesc = NULL;
511 info.info2.devmode = NULL;
514 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
516 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
523 if (W_ERROR_IS_OK(result))
524 printf("Success in setting comment.\n");
527 if (is_valid_policy_hnd(&pol))
528 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
533 /****************************************************************************
534 ****************************************************************************/
536 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
538 int argc, const char **argv)
540 struct policy_handle pol;
543 uint32_t info_level = 2;
544 union spoolss_PrinterInfo info;
545 const char *printername,
546 *new_printername = NULL;
547 struct spoolss_SetPrinterInfoCtr info_ctr;
548 struct spoolss_DevmodeContainer devmode_ctr;
549 struct sec_desc_buf secdesc_ctr;
551 ZERO_STRUCT(devmode_ctr);
552 ZERO_STRUCT(secdesc_ctr);
554 if (argc == 1 || argc > 3) {
555 printf("Usage: %s printername new_printername\n", argv[0]);
560 /* Open a printer handle */
562 new_printername = argv[2];
565 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
567 /* get a printer handle */
568 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
572 if (!W_ERROR_IS_OK(result))
575 /* Get printer info */
576 result = rpccli_spoolss_getprinter(cli, mem_ctx,
581 if (!W_ERROR_IS_OK(result))
584 /* Modify the printername. */
585 info.info2.printername = new_printername;
586 info.info2.devmode = NULL;
587 info.info2.secdesc = NULL;
589 info_ctr.level = info_level;
590 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
592 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
599 if (W_ERROR_IS_OK(result))
600 printf("Success in setting printername.\n");
603 if (is_valid_policy_hnd(&pol))
604 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
609 /****************************************************************************
610 ****************************************************************************/
612 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
614 int argc, const char **argv)
616 struct policy_handle pol;
619 const char *printername;
620 union spoolss_PrinterInfo info;
622 if (argc == 1 || argc > 3) {
623 printf("Usage: %s <printername> [level]\n", argv[0]);
627 /* Open a printer handle */
629 level = atoi(argv[2]);
632 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
634 /* get a printer handle */
636 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
638 SEC_FLAG_MAXIMUM_ALLOWED,
640 if (!W_ERROR_IS_OK(result)) {
644 /* Get printer info */
646 result = rpccli_spoolss_getprinter(cli, mem_ctx,
651 if (!W_ERROR_IS_OK(result)) {
655 /* Display printer info */
658 display_print_info0(&info.info0);
661 display_print_info1(&info.info1);
664 display_print_info2(&info.info2);
667 display_print_info3(&info.info3);
670 display_print_info4(&info.info4);
673 display_print_info5(&info.info5);
676 display_print_info6(&info.info6);
679 display_print_info7(&info.info7);
682 printf("unknown info level %d\n", level);
686 if (is_valid_policy_hnd(&pol)) {
687 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
693 /****************************************************************************
694 ****************************************************************************/
696 static void display_reg_value(struct regval_blob value)
702 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
703 *((uint32_t *) value.data_p));
706 rpcstr_pull_talloc(talloc_tos(),
711 printf("%s: REG_SZ: %s\n", value.valuename, text ? text : "");
714 char *hex = hex_encode_talloc(NULL, value.data_p, value.size);
716 printf("%s: REG_BINARY:", value.valuename);
718 for (i=0; i<len; i++) {
719 if (hex[i] == '\0') {
732 uint32_t i, num_values;
735 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
736 value.size, &num_values,
738 d_printf("reg_pull_multi_sz failed\n");
742 printf("%s: REG_MULTI_SZ: \n", value.valuename);
743 for (i=0; i<num_values; i++) {
744 d_printf("%s\n", values[i]);
750 printf("%s: unknown type %d\n", value.valuename, value.type);
755 /****************************************************************************
756 ****************************************************************************/
758 static void display_printer_data(const char *v,
759 enum winreg_Type type,
760 union spoolss_PrinterData *r)
766 printf("%s: REG_DWORD: 0x%08x\n", v, r->value);
769 printf("%s: REG_SZ: %s\n", v, r->string);
772 char *hex = hex_encode_talloc(NULL,
773 r->binary.data, r->binary.length);
775 printf("%s: REG_BINARY:", v);
777 for (i=0; i<len; i++) {
778 if (hex[i] == '\0') {
791 printf("%s: REG_MULTI_SZ: ", v);
792 for (i=0; r->string_array[i] != NULL; i++) {
793 printf("%s ", r->string_array[i]);
798 printf("%s: unknown type 0x%02x:\n", v, type);
803 /****************************************************************************
804 ****************************************************************************/
806 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
808 int argc, const char **argv)
810 struct policy_handle pol;
813 const char *valuename;
814 enum winreg_Type type;
815 union spoolss_PrinterData data;
818 printf("Usage: %s <printername> <valuename>\n", argv[0]);
819 printf("<printername> of . queries print server\n");
824 /* Open a printer handle */
826 if (strncmp(argv[1], ".", sizeof(".")) == 0)
827 fstrcpy(printername, cli->srv_name_slash);
829 slprintf(printername, sizeof(printername)-1, "%s\\%s",
830 cli->srv_name_slash, argv[1]);
832 /* get a printer handle */
834 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
836 SEC_FLAG_MAXIMUM_ALLOWED,
838 if (!W_ERROR_IS_OK(result))
841 /* Get printer info */
843 result = rpccli_spoolss_getprinterdata(cli, mem_ctx,
849 if (!W_ERROR_IS_OK(result))
852 /* Display printer data */
854 display_printer_data(valuename, type, &data);
857 if (is_valid_policy_hnd(&pol))
858 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
863 /****************************************************************************
864 ****************************************************************************/
866 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
868 int argc, const char **argv)
870 struct policy_handle pol;
874 const char *valuename, *keyname;
875 struct regval_blob value;
877 enum winreg_Type type;
878 uint8_t *buffer = NULL;
879 uint32_t offered = 0;
883 printf("Usage: %s <printername> <keyname> <valuename>\n",
885 printf("<printername> of . queries print server\n");
891 /* Open a printer handle */
893 if (strncmp(argv[1], ".", sizeof(".")) == 0)
894 fstrcpy(printername, cli->srv_name_slash);
896 slprintf(printername, sizeof(printername)-1, "%s\\%s",
897 cli->srv_name_slash, argv[1]);
899 /* get a printer handle */
901 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
903 SEC_FLAG_MAXIMUM_ALLOWED,
905 if (!W_ERROR_IS_OK(result))
908 /* Get printer info */
910 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
919 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
921 buffer = talloc_array(mem_ctx, uint8_t, needed);
922 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
933 if (!NT_STATUS_IS_OK(status)) {
937 if (!W_ERROR_IS_OK(result)) {
942 if (!W_ERROR_IS_OK(result))
945 /* Display printer data */
947 fstrcpy(value.valuename, valuename);
950 value.data_p = buffer;
952 display_reg_value(value);
955 if (is_valid_policy_hnd(&pol))
956 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
961 /****************************************************************************
962 ****************************************************************************/
964 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
970 printf("Printer Driver Info 1:\n");
971 printf("\tDriver Name: [%s]\n", r->driver_name);
975 /****************************************************************************
976 ****************************************************************************/
978 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
984 printf("Printer Driver Info 2:\n");
985 printf("\tVersion: [%x]\n", r->version);
986 printf("\tDriver Name: [%s]\n", r->driver_name);
987 printf("\tArchitecture: [%s]\n", r->architecture);
988 printf("\tDriver Path: [%s]\n", r->driver_path);
989 printf("\tDatafile: [%s]\n", r->data_file);
990 printf("\tConfigfile: [%s]\n", r->config_file);
994 /****************************************************************************
995 ****************************************************************************/
997 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1005 printf("Printer Driver Info 3:\n");
1006 printf("\tVersion: [%x]\n", r->version);
1007 printf("\tDriver Name: [%s]\n", r->driver_name);
1008 printf("\tArchitecture: [%s]\n", r->architecture);
1009 printf("\tDriver Path: [%s]\n", r->driver_path);
1010 printf("\tDatafile: [%s]\n", r->data_file);
1011 printf("\tConfigfile: [%s]\n", r->config_file);
1012 printf("\tHelpfile: [%s]\n", r->help_file);
1014 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1015 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1018 printf("\tMonitorname: [%s]\n", r->monitor_name);
1019 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1023 /****************************************************************************
1024 ****************************************************************************/
1026 static void display_print_driver4(struct spoolss_DriverInfo4 *r)
1034 printf("Printer Driver Info 4:\n");
1035 printf("\tVersion: [%x]\n", r->version);
1036 printf("\tDriver Name: [%s]\n", r->driver_name);
1037 printf("\tArchitecture: [%s]\n", r->architecture);
1038 printf("\tDriver Path: [%s]\n", r->driver_path);
1039 printf("\tDatafile: [%s]\n", r->data_file);
1040 printf("\tConfigfile: [%s]\n", r->config_file);
1041 printf("\tHelpfile: [%s]\n", r->help_file);
1043 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1044 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1047 printf("\tMonitorname: [%s]\n", r->monitor_name);
1048 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1050 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1051 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1056 /****************************************************************************
1057 ****************************************************************************/
1059 static void display_print_driver5(struct spoolss_DriverInfo5 *r)
1065 printf("Printer Driver Info 5:\n");
1066 printf("\tVersion: [%x]\n", r->version);
1067 printf("\tDriver Name: [%s]\n", r->driver_name);
1068 printf("\tArchitecture: [%s]\n", r->architecture);
1069 printf("\tDriver Path: [%s]\n", r->driver_path);
1070 printf("\tDatafile: [%s]\n", r->data_file);
1071 printf("\tConfigfile: [%s]\n", r->config_file);
1072 printf("\tDriver Attributes: [0x%x]\n", r->driver_attributes);
1073 printf("\tConfig Version: [0x%x]\n", r->config_version);
1074 printf("\tDriver Version: [0x%x]\n", r->driver_version);
1078 /****************************************************************************
1079 ****************************************************************************/
1081 static void display_print_driver6(struct spoolss_DriverInfo6 *r)
1089 printf("Printer Driver Info 6:\n");
1090 printf("\tVersion: [%x]\n", r->version);
1091 printf("\tDriver Name: [%s]\n", r->driver_name);
1092 printf("\tArchitecture: [%s]\n", r->architecture);
1093 printf("\tDriver Path: [%s]\n", r->driver_path);
1094 printf("\tDatafile: [%s]\n", r->data_file);
1095 printf("\tConfigfile: [%s]\n", r->config_file);
1096 printf("\tHelpfile: [%s]\n", r->help_file);
1098 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1099 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1102 printf("\tMonitorname: [%s]\n", r->monitor_name);
1103 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1105 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1106 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1109 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1110 printf("\tDriver Version: [0x%016llx]\n", r->driver_version);
1111 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1112 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1113 printf("\tHardware ID: [%s]\n", r->hardware_id);
1114 printf("\tProvider: [%s]\n", r->provider);
1119 /****************************************************************************
1120 ****************************************************************************/
1122 static void display_print_driver8(struct spoolss_DriverInfo8 *r)
1130 printf("Printer Driver Info 8:\n");
1131 printf("\tVersion: [%x]\n", r->version);
1132 printf("\tDriver Name: [%s]\n", r->driver_name);
1133 printf("\tArchitecture: [%s]\n", r->architecture);
1134 printf("\tDriver Path: [%s]\n", r->driver_path);
1135 printf("\tDatafile: [%s]\n", r->data_file);
1136 printf("\tConfigfile: [%s]\n", r->config_file);
1137 printf("\tHelpfile: [%s]\n", r->help_file);
1138 printf("\tMonitorname: [%s]\n", r->monitor_name);
1139 printf("\tDefaultdatatype: [%s]\n", r->default_datatype);
1141 for (i=0; r->dependent_files && r->dependent_files[i] != NULL; i++) {
1142 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1145 for (i=0; r->previous_names && r->previous_names[i] != NULL; i++) {
1146 printf("\tPrevious Names: [%s]\n", r->previous_names[i]);
1149 printf("\tDriver Date: [%s]\n", nt_time_string(talloc_tos(), r->driver_date));
1150 printf("\tDriver Version: [0x%016llx]\n", r->driver_version);
1151 printf("\tManufacturer Name: [%s]\n", r->manufacturer_name);
1152 printf("\tManufacturer Url: [%s]\n", r->manufacturer_url);
1153 printf("\tHardware ID: [%s]\n", r->hardware_id);
1154 printf("\tProvider: [%s]\n", r->provider);
1155 printf("\tPrint Processor: [%s]\n", r->print_processor);
1156 printf("\tVendor Setup: [%s]\n", r->vendor_setup);
1157 for (i=0; r->color_profiles && r->color_profiles[i] != NULL; i++) {
1158 printf("\tColor Profiles: [%s]\n", r->color_profiles[i]);
1160 printf("\tInf Path: [%s]\n", r->inf_path);
1161 printf("\tPrinter Driver Attributes: [0x%x]\n", r->printer_driver_attributes);
1162 for (i=0; r->core_driver_dependencies && r->core_driver_dependencies[i] != NULL; i++) {
1163 printf("\tCore Driver Dependencies: [%s]\n", r->core_driver_dependencies[i]);
1165 printf("\tMin Driver Inbox Driver Version Date: [%s]\n", nt_time_string(talloc_tos(), r->min_inbox_driver_ver_date));
1166 printf("\tMin Driver Inbox Driver Version Version: [0x%016llx]\n", r->min_inbox_driver_ver_version);
1171 /****************************************************************************
1172 ****************************************************************************/
1174 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1175 TALLOC_CTX *mem_ctx,
1176 int argc, const char **argv)
1178 struct policy_handle pol;
1181 const char *printername;
1183 bool success = false;
1184 union spoolss_DriverInfo info;
1185 uint32_t server_major_version;
1186 uint32_t server_minor_version;
1188 if ((argc == 1) || (argc > 3)) {
1189 printf("Usage: %s <printername> [level]\n", argv[0]);
1193 /* get the arguments need to open the printer handle */
1195 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1198 level = atoi(argv[2]);
1201 /* Open a printer handle */
1203 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1207 if (!W_ERROR_IS_OK(werror)) {
1208 printf("Error opening printer handle for %s!\n", printername);
1212 /* loop through and print driver info level for each architecture */
1214 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1216 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1218 archi_table[i].long_archi,
1221 archi_table[i].version,
1224 &server_major_version,
1225 &server_minor_version);
1226 if (!W_ERROR_IS_OK(werror)) {
1230 /* need at least one success */
1234 printf("\n[%s]\n", archi_table[i].long_archi);
1238 display_print_driver1(&info.info1);
1241 display_print_driver2(&info.info2);
1244 display_print_driver3(&info.info3);
1247 display_print_driver4(&info.info4);
1250 display_print_driver5(&info.info5);
1253 display_print_driver6(&info.info6);
1256 display_print_driver8(&info.info8);
1259 printf("unknown info level %d\n", level);
1266 if (is_valid_policy_hnd(&pol)) {
1267 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1277 /****************************************************************************
1278 ****************************************************************************/
1280 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1281 TALLOC_CTX *mem_ctx,
1282 int argc, const char **argv)
1284 WERROR werror = WERR_OK;
1286 union spoolss_DriverInfo *info;
1287 uint32_t i, j, count;
1290 printf("Usage: enumdrivers [level]\n");
1295 level = atoi(argv[1]);
1299 /* loop through and print driver info level for each architecture */
1300 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1301 /* check to see if we already asked for this architecture string */
1303 if (i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi)) {
1307 werror = rpccli_spoolss_enumprinterdrivers(cli, mem_ctx,
1308 cli->srv_name_slash,
1309 archi_table[i].long_archi,
1315 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
1316 printf("Server does not support environment [%s]\n",
1317 archi_table[i].long_archi);
1326 if (!W_ERROR_IS_OK(werror)) {
1327 printf("Error getting driver for environment [%s] - %d\n",
1328 archi_table[i].long_archi, W_ERROR_V(werror));
1332 printf("\n[%s]\n", archi_table[i].long_archi);
1336 for (j=0; j < count; j++) {
1337 display_print_driver1(&info[j].info1);
1341 for (j=0; j < count; j++) {
1342 display_print_driver2(&info[j].info2);
1346 for (j=0; j < count; j++) {
1347 display_print_driver3(&info[j].info3);
1351 for (j=0; j < count; j++) {
1352 display_print_driver4(&info[j].info4);
1356 for (j=0; j < count; j++) {
1357 display_print_driver5(&info[j].info5);
1361 for (j=0; j < count; j++) {
1362 display_print_driver6(&info[j].info6);
1366 for (j=0; j < count; j++) {
1367 display_print_driver8(&info[j].info8);
1371 printf("unknown info level %d\n", level);
1372 return WERR_UNKNOWN_LEVEL;
1379 /****************************************************************************
1380 ****************************************************************************/
1382 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1384 printf("\tDirectory Name:[%s]\n", r->directory_name);
1387 /****************************************************************************
1388 ****************************************************************************/
1390 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1391 TALLOC_CTX *mem_ctx,
1392 int argc, const char **argv)
1396 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1399 union spoolss_DriverDirectoryInfo info;
1403 printf("Usage: %s [environment]\n", argv[0]);
1407 /* Get the arguments need to open the printer handle */
1413 /* Get the directory. Only use Info level 1 */
1415 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1416 cli->srv_name_slash,
1424 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1426 buffer = data_blob_talloc_zero(mem_ctx, needed);
1428 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1429 cli->srv_name_slash,
1439 if (W_ERROR_IS_OK(result)) {
1440 display_printdriverdir_1(&info.info1);
1446 /****************************************************************************
1447 ****************************************************************************/
1449 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1450 struct spoolss_AddDriverInfo3 *info,
1456 for (i=0; archi_table[i].long_archi != NULL; i++)
1458 if (strcmp(arch, archi_table[i].short_archi) == 0)
1460 info->version = archi_table[i].version;
1461 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1466 if (archi_table[i].long_archi == NULL)
1468 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1475 /**************************************************************************
1476 wrapper for strtok to get the next parameter from a delimited list.
1477 Needed to handle the empty parameter string denoted by "NULL"
1478 *************************************************************************/
1480 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1481 const char *delim, const char **dest,
1486 /* get the next token */
1487 ptr = strtok_r(str, delim, saveptr);
1489 /* a string of 'NULL' is used to represent an empty
1490 parameter because two consecutive delimiters
1491 will not return an empty string. See man strtok(3)
1493 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1498 *dest = talloc_strdup(mem_ctx, ptr);
1504 /********************************************************************************
1505 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1506 string in the form of
1507 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1508 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1509 <Default Data Type>:<Comma Separated list of Files>
1510 *******************************************************************************/
1512 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1517 char *saveptr = NULL;
1518 struct spoolss_StringArray *deps;
1519 const char **file_array = NULL;
1522 /* fill in the UNISTR fields */
1523 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1524 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1525 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1526 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1527 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1528 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1529 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1531 /* <Comma Separated List of Dependent Files> */
1532 /* save the beginning of the string */
1533 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1536 /* begin to strip out each filename */
1537 str = strtok_r(str, ",", &saveptr);
1539 /* no dependent files, we are done */
1544 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1549 while (str != NULL) {
1550 add_string_to_array(deps, str, &file_array, &count);
1551 str = strtok_r(NULL, ",", &saveptr);
1554 deps->string = talloc_zero_array(deps, const char *, count + 1);
1555 if (!deps->string) {
1559 for (i=0; i < count; i++) {
1560 deps->string[i] = file_array[i];
1563 r->dependent_files = deps;
1568 /****************************************************************************
1569 ****************************************************************************/
1571 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1572 TALLOC_CTX *mem_ctx,
1573 int argc, const char **argv)
1578 struct spoolss_AddDriverInfoCtr info_ctr;
1579 struct spoolss_AddDriverInfo3 info3;
1583 /* parse the command arguments */
1584 if (argc != 3 && argc != 4)
1586 printf ("Usage: %s <Environment> \\\n", argv[0]);
1587 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1588 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1589 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1590 printf ("\t[version]\n");
1595 /* Fill in the spoolss_AddDriverInfo3 struct */
1598 arch = cmd_spoolss_get_short_archi(argv[1]);
1600 printf ("Error Unknown architechture [%s]\n", argv[1]);
1601 return WERR_INVALID_PARAM;
1604 set_drv_info_3_env(mem_ctx, &info3, arch);
1606 driver_args = talloc_strdup( mem_ctx, argv[2] );
1607 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1609 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1610 return WERR_INVALID_PARAM;
1613 /* if printer driver version specified, override the default version
1614 * used by the architecture. This allows installation of Windows
1615 * 2000 (version 3) printer drivers. */
1618 info3.version = atoi(argv[3]);
1622 info_ctr.level = level;
1623 info_ctr.info.info3 = &info3;
1625 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1626 cli->srv_name_slash,
1629 if (!NT_STATUS_IS_OK(status)) {
1630 return ntstatus_to_werror(status);
1632 if (W_ERROR_IS_OK(result)) {
1633 printf ("Printer Driver %s successfully installed.\n",
1641 /****************************************************************************
1642 ****************************************************************************/
1644 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1645 TALLOC_CTX *mem_ctx,
1646 int argc, const char **argv)
1649 struct spoolss_SetPrinterInfoCtr info_ctr;
1650 struct spoolss_SetPrinterInfo2 info2;
1652 /* parse the command arguments */
1655 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1659 /* Fill in the DRIVER_INFO_2 struct */
1662 info2.printername = argv[1];
1663 info2.drivername = argv[3];
1664 info2.sharename = argv[2];
1665 info2.portname = argv[4];
1666 info2.comment = "Created by rpcclient";
1667 info2.printprocessor = "winprint";
1668 info2.datatype = "RAW";
1669 info2.devmode = NULL;
1670 info2.secdesc = NULL;
1671 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1673 info2.defaultpriority = 0;
1674 info2.starttime = 0;
1675 info2.untiltime = 0;
1677 /* These three fields must not be used by AddPrinter()
1678 as defined in the MS Platform SDK documentation..
1682 info2.averageppm = 0;
1686 info_ctr.info.info2 = &info2;
1688 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1690 if (W_ERROR_IS_OK(result))
1691 printf ("Printer %s successfully installed.\n", argv[1]);
1696 /****************************************************************************
1697 ****************************************************************************/
1699 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1700 TALLOC_CTX *mem_ctx,
1701 int argc, const char **argv)
1703 struct policy_handle pol;
1707 const char *printername;
1708 union spoolss_PrinterInfo info;
1709 struct spoolss_SetPrinterInfoCtr info_ctr;
1710 struct spoolss_DevmodeContainer devmode_ctr;
1711 struct sec_desc_buf secdesc_ctr;
1713 ZERO_STRUCT(devmode_ctr);
1714 ZERO_STRUCT(secdesc_ctr);
1716 /* parse the command arguments */
1719 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1723 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1725 /* Get a printer handle */
1727 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1731 if (!W_ERROR_IS_OK(result))
1734 /* Get printer info */
1736 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1741 if (!W_ERROR_IS_OK(result)) {
1742 printf ("Unable to retrieve printer information!\n");
1746 /* Set the printer driver */
1748 info.info2.drivername = argv[2];
1749 info.info2.devmode = NULL;
1750 info.info2.secdesc = NULL;
1753 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
1755 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1762 if (!W_ERROR_IS_OK(result)) {
1763 printf("SetPrinter call failed!\n");
1767 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1772 if (is_valid_policy_hnd(&pol))
1773 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1779 /****************************************************************************
1780 ****************************************************************************/
1782 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1783 TALLOC_CTX *mem_ctx,
1784 int argc, const char **argv)
1786 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1792 const char *arch = NULL;
1793 uint32_t delete_flags = 0;
1795 /* parse the command arguments */
1796 if (argc < 2 || argc > 4) {
1797 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1804 vers = atoi (argv[3]);
1807 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1810 /* delete the driver for all architectures */
1811 for (i=0; archi_table[i].long_archi; i++) {
1813 if (arch && !strequal( archi_table[i].long_archi, arch))
1816 if (vers >= 0 && archi_table[i].version != vers)
1819 /* make the call to remove the driver */
1820 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1821 cli->srv_name_slash,
1822 archi_table[i].long_archi,
1825 archi_table[i].version,
1828 if ( !W_ERROR_IS_OK(result) )
1830 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1831 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1832 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1837 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1838 archi_table[i].long_archi, archi_table[i].version);
1847 /****************************************************************************
1848 ****************************************************************************/
1850 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1851 TALLOC_CTX *mem_ctx,
1852 int argc, const char **argv)
1854 WERROR result = WERR_OK;
1858 /* parse the command arguments */
1860 printf ("Usage: %s <driver>\n", argv[0]);
1864 /* delete the driver for all architectures */
1865 for (i=0; archi_table[i].long_archi; i++) {
1866 /* make the call to remove the driver */
1867 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1868 cli->srv_name_slash,
1869 archi_table[i].long_archi,
1872 if (!NT_STATUS_IS_OK(status)) {
1875 if ( !W_ERROR_IS_OK(result) ) {
1876 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1877 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1878 argv[1], archi_table[i].long_archi,
1882 printf ("Driver %s removed for arch [%s].\n", argv[1],
1883 archi_table[i].long_archi);
1890 /****************************************************************************
1891 ****************************************************************************/
1893 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1894 TALLOC_CTX *mem_ctx,
1895 int argc, const char **argv)
1899 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1902 union spoolss_PrintProcessorDirectoryInfo info;
1905 /* parse the command arguments */
1907 printf ("Usage: %s [environment]\n", argv[0]);
1912 environment = argv[1];
1915 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1916 cli->srv_name_slash,
1924 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1926 buffer = data_blob_talloc_zero(mem_ctx, needed);
1928 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1929 cli->srv_name_slash,
1939 if (W_ERROR_IS_OK(result)) {
1940 printf("%s\n", info.info1.directory_name);
1946 /****************************************************************************
1947 ****************************************************************************/
1949 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1950 int argc, const char **argv)
1952 struct policy_handle handle;
1955 const char *printername;
1956 union spoolss_AddFormInfo info;
1957 struct spoolss_AddFormInfo1 info1;
1958 struct spoolss_AddFormInfo2 info2;
1961 /* Parse the command arguments */
1963 if (argc < 3 || argc > 5) {
1964 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
1968 /* Get a printer handle */
1970 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1972 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1976 if (!W_ERROR_IS_OK(werror))
1979 /* Dummy up some values for the form data */
1982 level = atoi(argv[3]);
1987 info1.flags = SPOOLSS_FORM_USER;
1988 info1.form_name = argv[2];
1989 info1.size.width = 100;
1990 info1.size.height = 100;
1991 info1.area.left = 0;
1992 info1.area.top = 10;
1993 info1.area.right = 20;
1994 info1.area.bottom = 30;
1996 info.info1 = &info1;
2000 info2.flags = SPOOLSS_FORM_USER;
2001 info2.form_name = argv[2];
2002 info2.size.width = 100;
2003 info2.size.height = 100;
2004 info2.area.left = 0;
2005 info2.area.top = 10;
2006 info2.area.right = 20;
2007 info2.area.bottom = 30;
2008 info2.keyword = argv[2];
2009 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
2010 info2.mui_dll = NULL;
2011 info2.ressource_id = 0;
2012 info2.display_name = argv[2];
2015 info.info2 = &info2;
2023 status = rpccli_spoolss_AddForm(cli, mem_ctx,
2030 if (is_valid_policy_hnd(&handle))
2031 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2036 /****************************************************************************
2037 ****************************************************************************/
2039 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2040 int argc, const char **argv)
2042 struct policy_handle handle;
2045 const char *printername;
2046 union spoolss_AddFormInfo info;
2047 struct spoolss_AddFormInfo1 info1;
2049 /* Parse the command arguments */
2052 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2056 /* Get a printer handle */
2058 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2060 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2062 SEC_FLAG_MAXIMUM_ALLOWED,
2064 if (!W_ERROR_IS_OK(werror))
2067 /* Dummy up some values for the form data */
2069 info1.flags = SPOOLSS_FORM_PRINTER;
2070 info1.size.width = 100;
2071 info1.size.height = 100;
2072 info1.area.left = 0;
2073 info1.area.top = 1000;
2074 info1.area.right = 2000;
2075 info1.area.bottom = 3000;
2076 info1.form_name = argv[2];
2078 info.info1 = &info1;
2082 status = rpccli_spoolss_SetForm(cli, mem_ctx,
2090 if (is_valid_policy_hnd(&handle))
2091 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2096 /****************************************************************************
2097 ****************************************************************************/
2099 static const char *get_form_flag(int form_flag)
2101 switch (form_flag) {
2102 case SPOOLSS_FORM_USER:
2104 case SPOOLSS_FORM_BUILTIN:
2105 return "FORM_BUILTIN";
2106 case SPOOLSS_FORM_PRINTER:
2107 return "FORM_PRINTER";
2113 /****************************************************************************
2114 ****************************************************************************/
2116 static void display_form_info1(struct spoolss_FormInfo1 *r)
2119 "\tflag: %s (%d)\n" \
2120 "\twidth: %d, length: %d\n" \
2121 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2122 r->form_name, get_form_flag(r->flags), r->flags,
2123 r->size.width, r->size.height,
2124 r->area.left, r->area.right,
2125 r->area.top, r->area.bottom);
2128 /****************************************************************************
2129 ****************************************************************************/
2131 static void display_form_info2(struct spoolss_FormInfo2 *r)
2134 "\tflag: %s (%d)\n" \
2135 "\twidth: %d, length: %d\n" \
2136 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2137 r->form_name, get_form_flag(r->flags), r->flags,
2138 r->size.width, r->size.height,
2139 r->area.left, r->area.right,
2140 r->area.top, r->area.bottom);
2141 printf("\tkeyword: %s\n", r->keyword);
2142 printf("\tstring_type: 0x%08x\n", r->string_type);
2143 printf("\tmui_dll: %s\n", r->mui_dll);
2144 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2145 printf("\tdisplay_name: %s\n", r->display_name);
2146 printf("\tlang_id: %d\n", r->lang_id);
2150 /****************************************************************************
2151 ****************************************************************************/
2153 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2154 int argc, const char **argv)
2156 struct policy_handle handle;
2159 const char *printername;
2161 uint32_t offered = 0;
2162 union spoolss_FormInfo info;
2166 /* Parse the command arguments */
2168 if (argc < 3 || argc > 5) {
2169 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2173 /* Get a printer handle */
2175 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2177 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2179 SEC_FLAG_MAXIMUM_ALLOWED,
2181 if (!W_ERROR_IS_OK(werror))
2185 level = atoi(argv[3]);
2190 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2199 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2200 buffer = data_blob_talloc_zero(mem_ctx, needed);
2202 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2213 if (!NT_STATUS_IS_OK(status)) {
2219 display_form_info1(&info.info1);
2222 display_form_info2(&info.info2);
2227 if (is_valid_policy_hnd(&handle))
2228 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2233 /****************************************************************************
2234 ****************************************************************************/
2236 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2237 TALLOC_CTX *mem_ctx, int argc,
2240 struct policy_handle handle;
2243 const char *printername;
2245 /* Parse the command arguments */
2248 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2252 /* Get a printer handle */
2254 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2256 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2258 SEC_FLAG_MAXIMUM_ALLOWED,
2260 if (!W_ERROR_IS_OK(werror))
2263 /* Delete the form */
2265 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2269 if (!NT_STATUS_IS_OK(status)) {
2270 return ntstatus_to_werror(status);
2274 if (is_valid_policy_hnd(&handle))
2275 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2280 /****************************************************************************
2281 ****************************************************************************/
2283 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2284 TALLOC_CTX *mem_ctx, int argc,
2287 struct policy_handle handle;
2289 const char *printername;
2290 uint32_t num_forms, level = 1, i;
2291 union spoolss_FormInfo *forms;
2293 /* Parse the command arguments */
2295 if (argc < 2 || argc > 4) {
2296 printf ("Usage: %s <printer> [level]\n", argv[0]);
2300 /* Get a printer handle */
2302 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2304 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2306 SEC_FLAG_MAXIMUM_ALLOWED,
2308 if (!W_ERROR_IS_OK(werror))
2312 level = atoi(argv[2]);
2315 /* Enumerate forms */
2317 werror = rpccli_spoolss_enumforms(cli, mem_ctx,
2324 if (!W_ERROR_IS_OK(werror))
2327 /* Display output */
2329 for (i = 0; i < num_forms; i++) {
2332 display_form_info1(&forms[i].info1);
2335 display_form_info2(&forms[i].info2);
2341 if (is_valid_policy_hnd(&handle))
2342 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2347 /****************************************************************************
2348 ****************************************************************************/
2350 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2351 TALLOC_CTX *mem_ctx,
2352 int argc, const char **argv)
2356 const char *printername;
2357 struct policy_handle pol;
2358 union spoolss_PrinterInfo info;
2359 enum winreg_Type type;
2360 union spoolss_PrinterData data;
2362 /* parse the command arguments */
2364 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2365 " <value> <data>\n",
2367 result = WERR_INVALID_PARAM;
2371 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2375 if (strequal(argv[2], "string")) {
2379 if (strequal(argv[2], "binary")) {
2383 if (strequal(argv[2], "dword")) {
2387 if (strequal(argv[2], "multistring")) {
2388 type = REG_MULTI_SZ;
2391 if (type == REG_NONE) {
2392 printf("Unknown data type: %s\n", argv[2]);
2393 result = WERR_INVALID_PARAM;
2397 /* get a printer handle */
2399 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2401 SEC_FLAG_MAXIMUM_ALLOWED,
2403 if (!W_ERROR_IS_OK(result)) {
2407 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2412 if (!W_ERROR_IS_OK(result)) {
2416 printf("%s\n", current_timestring(mem_ctx, true));
2417 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2419 /* Set the printer data */
2423 data.string = talloc_strdup(mem_ctx, argv[4]);
2424 W_ERROR_HAVE_NO_MEMORY(data.string);
2427 data.value = strtoul(argv[4], NULL, 10);
2430 data.binary = strhex_to_data_blob(mem_ctx, argv[4]);
2432 case REG_MULTI_SZ: {
2434 const char **strings = NULL;
2436 for (i=4; i<argc; i++) {
2437 if (strcmp(argv[i], "NULL") == 0) {
2440 if (!add_string_to_array(mem_ctx, argv[i],
2443 result = WERR_NOMEM;
2447 data.string_array = talloc_zero_array(mem_ctx, const char *, num_strings + 1);
2448 if (!data.string_array) {
2449 result = WERR_NOMEM;
2452 for (i=0; i < num_strings; i++) {
2453 data.string_array[i] = strings[i];
2458 printf("Unknown data type: %s\n", argv[2]);
2459 result = WERR_INVALID_PARAM;
2463 status = rpccli_spoolss_SetPrinterData(cli, mem_ctx,
2465 argv[3], /* value_name */
2468 0, /* autocalculated size */
2470 if (!W_ERROR_IS_OK(result)) {
2471 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2474 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2476 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2481 if (!W_ERROR_IS_OK(result)) {
2485 printf("%s\n", current_timestring(mem_ctx, true));
2486 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2490 if (is_valid_policy_hnd(&pol)) {
2491 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2497 /****************************************************************************
2498 ****************************************************************************/
2500 static void display_job_info1(struct spoolss_JobInfo1 *r)
2502 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2503 r->user_name, r->document_name, r->text_status, r->pages_printed,
2507 /****************************************************************************
2508 ****************************************************************************/
2510 static void display_job_info2(struct spoolss_JobInfo2 *r)
2512 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2513 r->position, r->job_id,
2514 r->user_name, r->document_name, r->text_status, r->pages_printed,
2515 r->total_pages, r->size);
2518 /****************************************************************************
2519 ****************************************************************************/
2521 static void display_job_info3(struct spoolss_JobInfo3 *r)
2523 printf("jobid[%d], next_jobid[%d]\n",
2524 r->job_id, r->next_job_id);
2527 /****************************************************************************
2528 ****************************************************************************/
2530 static void display_job_info4(struct spoolss_JobInfo4 *r)
2532 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2533 r->position, r->job_id,
2534 r->user_name, r->document_name, r->text_status, r->pages_printed,
2535 r->total_pages, r->size, r->size_high);
2538 /****************************************************************************
2539 ****************************************************************************/
2541 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2542 TALLOC_CTX *mem_ctx, int argc,
2546 uint32_t level = 1, count, i;
2547 const char *printername;
2548 struct policy_handle hnd;
2549 union spoolss_JobInfo *info;
2551 if (argc < 2 || argc > 3) {
2552 printf("Usage: %s printername [level]\n", argv[0]);
2557 level = atoi(argv[2]);
2560 /* Open printer handle */
2562 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2564 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2566 SEC_FLAG_MAXIMUM_ALLOWED,
2568 if (!W_ERROR_IS_OK(result))
2571 /* Enumerate ports */
2573 result = rpccli_spoolss_enumjobs(cli, mem_ctx,
2581 if (!W_ERROR_IS_OK(result)) {
2585 for (i = 0; i < count; i++) {
2588 display_job_info1(&info[i].info1);
2591 display_job_info2(&info[i].info2);
2594 d_printf("unknown info level %d\n", level);
2600 if (is_valid_policy_hnd(&hnd)) {
2601 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2607 /****************************************************************************
2608 ****************************************************************************/
2610 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2611 TALLOC_CTX *mem_ctx, int argc,
2615 const char *printername;
2616 struct policy_handle hnd;
2619 union spoolss_JobInfo info;
2621 if (argc < 3 || argc > 4) {
2622 printf("Usage: %s printername job_id [level]\n", argv[0]);
2626 job_id = atoi(argv[2]);
2629 level = atoi(argv[3]);
2632 /* Open printer handle */
2634 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2636 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2638 SEC_FLAG_MAXIMUM_ALLOWED,
2640 if (!W_ERROR_IS_OK(result)) {
2644 /* Enumerate ports */
2646 result = rpccli_spoolss_getjob(cli, mem_ctx,
2653 if (!W_ERROR_IS_OK(result)) {
2659 display_job_info1(&info.info1);
2662 display_job_info2(&info.info2);
2665 display_job_info3(&info.info3);
2668 display_job_info4(&info.info4);
2671 d_printf("unknown info level %d\n", level);
2676 if (is_valid_policy_hnd(&hnd)) {
2677 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2683 /****************************************************************************
2684 ****************************************************************************/
2686 static WERROR cmd_spoolss_set_job(struct rpc_pipe_client *cli,
2687 TALLOC_CTX *mem_ctx, int argc,
2692 const char *printername;
2693 struct policy_handle hnd;
2695 enum spoolss_JobControl command;
2698 printf("Usage: %s printername job_id command\n", argv[0]);
2702 job_id = atoi(argv[2]);
2703 command = atoi(argv[3]);
2705 /* Open printer handle */
2707 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2709 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2711 SEC_FLAG_MAXIMUM_ALLOWED,
2713 if (!W_ERROR_IS_OK(result)) {
2719 status = rpccli_spoolss_SetJob(cli, mem_ctx,
2726 if (!W_ERROR_IS_OK(result)) {
2731 if (is_valid_policy_hnd(&hnd)) {
2732 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2738 /****************************************************************************
2739 ****************************************************************************/
2741 static WERROR cmd_spoolss_enum_data(struct rpc_pipe_client *cli,
2742 TALLOC_CTX *mem_ctx, int argc,
2748 const char *printername;
2749 struct policy_handle hnd;
2750 uint32_t value_offered = 0;
2751 const char *value_name = NULL;
2752 uint32_t value_needed;
2753 enum winreg_Type type;
2754 uint8_t *data = NULL;
2755 uint32_t data_offered = 0;
2756 uint32_t data_needed;
2759 printf("Usage: %s printername\n", argv[0]);
2763 /* Open printer handle */
2765 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2767 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2769 SEC_FLAG_MAXIMUM_ALLOWED,
2771 if (!W_ERROR_IS_OK(result)) {
2775 /* Enumerate data */
2777 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2789 data_offered = data_needed;
2790 value_offered = value_needed;
2791 data = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2792 value_name = talloc_zero_array(mem_ctx, char, value_needed);
2794 while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2796 status = rpccli_spoolss_EnumPrinterData(cli, mem_ctx,
2807 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(result)) {
2808 struct regval_blob v;
2809 fstrcpy(v.valuename, value_name);
2811 v.size = data_offered;
2813 display_reg_value(v);
2817 if (W_ERROR_V(result) == ERRnomoreitems) {
2818 result = W_ERROR(ERRsuccess);
2822 if (is_valid_policy_hnd(&hnd)) {
2823 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2829 /****************************************************************************
2830 ****************************************************************************/
2832 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2833 TALLOC_CTX *mem_ctx, int argc,
2838 const char *printername;
2839 struct policy_handle hnd;
2841 struct spoolss_PrinterEnumValues *info;
2844 printf("Usage: %s printername <keyname>\n", argv[0]);
2848 /* Open printer handle */
2850 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2852 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2854 SEC_FLAG_MAXIMUM_ALLOWED,
2856 if (!W_ERROR_IS_OK(result)) {
2860 /* Enumerate subkeys */
2862 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx,
2868 if (!W_ERROR_IS_OK(result)) {
2872 for (i=0; i < count; i++) {
2873 display_printer_data(info[i].value_name,
2879 if (is_valid_policy_hnd(&hnd)) {
2880 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2886 /****************************************************************************
2887 ****************************************************************************/
2889 static WERROR cmd_spoolss_enum_printerkey(struct rpc_pipe_client *cli,
2890 TALLOC_CTX *mem_ctx, int argc,
2894 const char *printername;
2895 const char *keyname = NULL;
2896 struct policy_handle hnd;
2897 const char **key_buffer = NULL;
2900 if (argc < 2 || argc > 3) {
2901 printf("Usage: %s printername [keyname]\n", argv[0]);
2911 /* Open printer handle */
2913 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2915 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2917 SEC_FLAG_MAXIMUM_ALLOWED,
2919 if (!W_ERROR_IS_OK(result)) {
2923 /* Enumerate subkeys */
2925 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx,
2931 if (!W_ERROR_IS_OK(result)) {
2935 for (i=0; key_buffer && key_buffer[i]; i++) {
2936 printf("%s\n", key_buffer[i]);
2941 if (is_valid_policy_hnd(&hnd)) {
2942 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2948 /****************************************************************************
2949 ****************************************************************************/
2951 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
2952 TALLOC_CTX *mem_ctx, int argc,
2955 const char *printername;
2956 const char *clientname;
2957 struct policy_handle hnd;
2960 struct spoolss_NotifyOption option;
2963 printf("Usage: %s printername\n", argv[0]);
2970 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2972 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2974 SEC_FLAG_MAXIMUM_ALLOWED,
2976 if (!W_ERROR_IS_OK(result)) {
2977 printf("Error opening %s\n", argv[1]);
2981 /* Create spool options */
2986 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
2987 if (option.types == NULL) {
2988 result = WERR_NOMEM;
2992 option.types[0].type = PRINTER_NOTIFY_TYPE;
2993 option.types[0].count = 1;
2994 option.types[0].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
2995 if (option.types[0].fields == NULL) {
2996 result = WERR_NOMEM;
2999 option.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
3001 option.types[1].type = JOB_NOTIFY_TYPE;
3002 option.types[1].count = 1;
3003 option.types[1].fields = talloc_array(mem_ctx, union spoolss_Field, 1);
3004 if (option.types[1].fields == NULL) {
3005 result = WERR_NOMEM;
3008 option.types[1].fields[0].field = JOB_NOTIFY_FIELD_PRINTER_NAME;
3010 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
3012 result = WERR_NOMEM;
3018 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
3026 if (!W_ERROR_IS_OK(result)) {
3027 printf("Error rffpcnex %s\n", argv[1]);
3032 if (is_valid_policy_hnd(&hnd))
3033 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
3038 /****************************************************************************
3039 ****************************************************************************/
3041 static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3042 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3044 union spoolss_PrinterInfo info1, info2;
3046 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
3048 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
3049 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3054 if ( !W_ERROR_IS_OK(werror) ) {
3055 printf("failed (%s)\n", win_errstr(werror));
3056 talloc_destroy(mem_ctx);
3061 printf("Retrieving printer properties for %s...", cli2->desthost);
3062 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3067 if ( !W_ERROR_IS_OK(werror) ) {
3068 printf("failed (%s)\n", win_errstr(werror));
3069 talloc_destroy(mem_ctx);
3074 talloc_destroy(mem_ctx);
3079 /****************************************************************************
3080 ****************************************************************************/
3082 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy_handle *hnd1,
3083 struct rpc_pipe_client *cli2, struct policy_handle *hnd2 )
3085 union spoolss_PrinterInfo info1, info2;
3087 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
3088 SEC_DESC *sd1, *sd2;
3092 printf("Retrieving printer security for %s...", cli1->desthost);
3093 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
3098 if ( !W_ERROR_IS_OK(werror) ) {
3099 printf("failed (%s)\n", win_errstr(werror));
3105 printf("Retrieving printer security for %s...", cli2->desthost);
3106 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
3111 if ( !W_ERROR_IS_OK(werror) ) {
3112 printf("failed (%s)\n", win_errstr(werror));
3121 sd1 = info1.info3.secdesc;
3122 sd2 = info2.info3.secdesc;
3124 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
3125 printf("NULL secdesc!\n");
3130 if (!security_descriptor_equal( sd1, sd2 ) ) {
3131 printf("Security Descriptors *not* equal!\n");
3136 printf("Security descriptors match\n");
3139 talloc_destroy(mem_ctx);
3144 /****************************************************************************
3145 ****************************************************************************/
3147 extern struct user_auth_info *rpcclient_auth_info;
3149 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
3150 TALLOC_CTX *mem_ctx, int argc,
3153 const char *printername;
3154 char *printername_path = NULL;
3155 struct cli_state *cli_server2 = NULL;
3156 struct rpc_pipe_client *cli2 = NULL;
3157 struct policy_handle hPrinter1, hPrinter2;
3162 printf("Usage: %s <printer> <server>\n", argv[0]);
3166 printername = argv[1];
3168 /* first get the connection to the remote server */
3170 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3173 get_cmdline_auth_info_username(rpcclient_auth_info),
3175 get_cmdline_auth_info_password(rpcclient_auth_info),
3176 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3177 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
3179 if ( !NT_STATUS_IS_OK(nt_status) )
3180 return WERR_GENERAL_FAILURE;
3182 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &ndr_table_spoolss.syntax_id,
3184 if (!NT_STATUS_IS_OK(nt_status)) {
3185 printf("failed to open spoolss pipe on server %s (%s)\n",
3186 argv[2], nt_errstr(nt_status));
3187 return WERR_GENERAL_FAILURE;
3190 /* now open up both printers */
3192 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3194 printf("Opening %s...", printername_path);
3196 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3200 if ( !W_ERROR_IS_OK(werror) ) {
3201 printf("failed (%s)\n", win_errstr(werror));
3206 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3208 printf("Opening %s...", printername_path);
3209 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3213 if ( !W_ERROR_IS_OK(werror) ) {
3214 printf("failed (%s)\n", win_errstr(werror));
3219 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3220 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3222 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3229 printf("Closing printers...");
3230 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3231 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3234 /* close the second remote connection */
3236 cli_shutdown( cli_server2 );
3240 static void display_proc_info1(struct spoolss_PrintProcessorInfo1 *r)
3242 printf("print_processor_name: %s\n", r->print_processor_name);
3245 static WERROR cmd_spoolss_enum_procs(struct rpc_pipe_client *cli,
3246 TALLOC_CTX *mem_ctx, int argc,
3250 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
3251 uint32_t num_procs, level = 1, i;
3252 union spoolss_PrintProcessorInfo *procs;
3254 /* Parse the command arguments */
3256 if (argc < 1 || argc > 4) {
3257 printf ("Usage: %s [environment] [level]\n", argv[0]);
3262 environment = argv[1];
3266 level = atoi(argv[2]);
3269 /* Enumerate Print Processors */
3271 werror = rpccli_spoolss_enumprintprocessors(cli, mem_ctx,
3272 cli->srv_name_slash,
3278 if (!W_ERROR_IS_OK(werror))
3281 /* Display output */
3283 for (i = 0; i < num_procs; i++) {
3286 display_proc_info1(&procs[i].info1);
3295 static void display_proc_data_types_info1(struct spoolss_PrintProcDataTypesInfo1 *r)
3297 printf("name_array: %s\n", r->name_array);
3300 static WERROR cmd_spoolss_enum_proc_data_types(struct rpc_pipe_client *cli,
3301 TALLOC_CTX *mem_ctx, int argc,
3305 const char *print_processor_name = "winprint";
3306 uint32_t num_procs, level = 1, i;
3307 union spoolss_PrintProcDataTypesInfo *procs;
3309 /* Parse the command arguments */
3311 if (argc < 1 || argc > 4) {
3312 printf ("Usage: %s [environment] [level]\n", argv[0]);
3317 print_processor_name = argv[1];
3321 level = atoi(argv[2]);
3324 /* Enumerate Print Processor Data Types */
3326 werror = rpccli_spoolss_enumprintprocessordatatypes(cli, mem_ctx,
3327 cli->srv_name_slash,
3328 print_processor_name,
3333 if (!W_ERROR_IS_OK(werror))
3336 /* Display output */
3338 for (i = 0; i < num_procs; i++) {
3341 display_proc_data_types_info1(&procs[i].info1);
3350 static void display_monitor1(const struct spoolss_MonitorInfo1 *r)
3352 printf("monitor_name: %s\n", r->monitor_name);
3355 static void display_monitor2(const struct spoolss_MonitorInfo2 *r)
3357 printf("monitor_name: %s\n", r->monitor_name);
3358 printf("environment: %s\n", r->environment);
3359 printf("dll_name: %s\n", r->dll_name);
3362 static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
3363 TALLOC_CTX *mem_ctx, int argc,
3367 uint32_t count, level = 1, i;
3368 union spoolss_MonitorInfo *info;
3370 /* Parse the command arguments */
3373 printf("Usage: %s [level]\n", argv[0]);
3378 level = atoi(argv[1]);
3381 /* Enumerate Print Monitors */
3383 werror = rpccli_spoolss_enummonitors(cli, mem_ctx,
3384 cli->srv_name_slash,
3389 if (!W_ERROR_IS_OK(werror)) {
3393 /* Display output */
3395 for (i = 0; i < count; i++) {
3398 display_monitor1(&info[i].info1);
3401 display_monitor2(&info[i].info2);
3410 /* List of commands exported by this module */
3411 struct cmd_set spoolss_commands[] = {
3415 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &ndr_table_spoolss.syntax_id, NULL, "Add a print driver", "" },
3416 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &ndr_table_spoolss.syntax_id, NULL, "Add a printer", "" },
3417 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver", "" },
3418 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &ndr_table_spoolss.syntax_id, NULL, "Delete a printer driver with files", "" },
3419 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data", "" },
3420 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer data for a key", "" },
3421 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer keys", "" },
3422 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate print jobs", "" },
3423 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &ndr_table_spoolss.syntax_id, NULL, "Get print job", "" },
3424 { "setjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_set_job, &ndr_table_spoolss.syntax_id, NULL, "Set print job", "" },
3425 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printer ports", "" },
3426 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate installed printer drivers", "" },
3427 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &ndr_table_spoolss.syntax_id, NULL, "Enumerate printers", "" },
3428 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Get print driver data", "" },
3429 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &ndr_table_spoolss.syntax_id, NULL, "Get printer driver data with keyname", ""},
3430 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &ndr_table_spoolss.syntax_id, NULL, "Get print driver information", "" },
3431 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &ndr_table_spoolss.syntax_id, NULL, "Get print driver upload directory", "" },
3432 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &ndr_table_spoolss.syntax_id, NULL, "Get printer info", "" },
3433 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &ndr_table_spoolss.syntax_id, NULL, "Open printer handle", "" },
3434 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &ndr_table_spoolss.syntax_id, NULL, "Set printer driver", "" },
3435 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &ndr_table_spoolss.syntax_id, NULL, "Get print processor directory", "" },
3436 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &ndr_table_spoolss.syntax_id, NULL, "Add form", "" },
3437 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &ndr_table_spoolss.syntax_id, NULL, "Set form", "" },
3438 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &ndr_table_spoolss.syntax_id, NULL, "Get form", "" },
3439 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &ndr_table_spoolss.syntax_id, NULL, "Delete form", "" },
3440 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &ndr_table_spoolss.syntax_id, NULL, "Enumerate forms", "" },
3441 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &ndr_table_spoolss.syntax_id, NULL, "Set printer comment", "" },
3442 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &ndr_table_spoolss.syntax_id, NULL, "Set printername", "" },
3443 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &ndr_table_spoolss.syntax_id, NULL, "Set REG_SZ printer data", "" },
3444 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &ndr_table_spoolss.syntax_id, NULL, "Rffpcnex test", "" },
3445 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &ndr_table_spoolss.syntax_id, NULL, "Printer comparison test", "" },
3446 { "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
3447 { "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
3448 { "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },