2 Unix SMB/CIFS implementation.
5 Copyright (C) Gerald Carter 2001-2005
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 1992-1999
8 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "rpcclient.h"
27 #define RPCCLIENT_PRINTERNAME(_printername, _cli, _arg) \
29 _printername = talloc_asprintf_strupper_m(mem_ctx, "%s\\%s", \
30 _cli->srv_name_slash, _arg); \
31 W_ERROR_HAVE_NO_MEMORY(_printername); \
35 const char *long_archi;
36 const char *short_archi;
40 /* The version int is used by getdrivers. Note that
41 all architecture strings that support mutliple
42 versions must be grouped together since enumdrivers
43 uses this property to prevent issuing multiple
44 enumdriver calls for the same arch */
47 static const struct table_node archi_table[]= {
49 {"Windows 4.0", "WIN40", 0 },
50 {"Windows NT x86", "W32X86", 2 },
51 {"Windows NT x86", "W32X86", 3 },
52 {"Windows NT R4000", "W32MIPS", 2 },
53 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
54 {"Windows NT PowerPC", "W32PPC", 2 },
55 {"Windows IA64", "IA64", 3 },
56 {"Windows x64", "x64", 3 },
63 * rpcclient module for SPOOLSS rpc pipe.
65 * This generally just parses and checks command lines, and then calls
66 * a cli_spoolss function.
69 /****************************************************************************
70 function to do the mapping between the long architecture name and
72 ****************************************************************************/
74 static const char *cmd_spoolss_get_short_archi(const char *long_archi)
78 DEBUG(107,("Getting architecture dependant directory\n"));
81 } while ( (archi_table[i].long_archi!=NULL ) &&
82 StrCaseCmp(long_archi, archi_table[i].long_archi) );
84 if (archi_table[i].long_archi==NULL) {
85 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
89 /* this might be client code - but shouldn't this be an fstrcpy etc? */
92 DEBUGADD(108,("index: [%d]\n", i));
93 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
94 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
96 return archi_table[i].short_archi;
99 /****************************************************************************
100 ****************************************************************************/
102 static WERROR cmd_spoolss_open_printer_ex(struct rpc_pipe_client *cli,
104 int argc, const char **argv)
110 printf("Usage: %s <printername>\n", argv[0]);
115 return WERR_GENERAL_FAILURE;
117 /* Open the printer handle */
119 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
123 if (W_ERROR_IS_OK(werror)) {
124 printf("Printer %s opened successfully\n", argv[1]);
125 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, &werror);
127 if (!W_ERROR_IS_OK(werror)) {
128 printf("Error closing printer handle! (%s)\n",
129 get_dos_error_msg(werror));
137 /****************************************************************************
138 ****************************************************************************/
140 static void display_print_info_0(PRINTER_INFO_0 *i0)
143 fstring servername = "";
148 rpcstr_pull(name, i0->printername.buffer, sizeof(name), -1, STR_TERMINATE);
150 rpcstr_pull(servername, i0->servername.buffer, sizeof(servername), -1,STR_TERMINATE);
152 printf("\tprintername:[%s]\n", name);
153 printf("\tservername:[%s]\n", servername);
154 printf("\tcjobs:[0x%x]\n", i0->cjobs);
155 printf("\ttotal_jobs:[0x%x]\n", i0->total_jobs);
157 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i0->year, i0->month,
158 i0->day, i0->dayofweek);
159 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i0->hour, i0->minute,
160 i0->second, i0->milliseconds);
162 printf("\tglobal_counter:[0x%x]\n", i0->global_counter);
163 printf("\ttotal_pages:[0x%x]\n", i0->total_pages);
165 printf("\tmajorversion:[0x%x]\n", i0->major_version);
166 printf("\tbuildversion:[0x%x]\n", i0->build_version);
168 printf("\tunknown7:[0x%x]\n", i0->unknown7);
169 printf("\tunknown8:[0x%x]\n", i0->unknown8);
170 printf("\tunknown9:[0x%x]\n", i0->unknown9);
171 printf("\tsession_counter:[0x%x]\n", i0->session_counter);
172 printf("\tunknown11:[0x%x]\n", i0->unknown11);
173 printf("\tprinter_errors:[0x%x]\n", i0->printer_errors);
174 printf("\tunknown13:[0x%x]\n", i0->unknown13);
175 printf("\tunknown14:[0x%x]\n", i0->unknown14);
176 printf("\tunknown15:[0x%x]\n", i0->unknown15);
177 printf("\tunknown16:[0x%x]\n", i0->unknown16);
178 printf("\tchange_id:[0x%x]\n", i0->change_id);
179 printf("\tunknown18:[0x%x]\n", i0->unknown18);
180 printf("\tstatus:[0x%x]\n", i0->status);
181 printf("\tunknown20:[0x%x]\n", i0->unknown20);
182 printf("\tc_setprinter:[0x%x]\n", i0->c_setprinter);
183 printf("\tunknown22:[0x%x]\n", i0->unknown22);
184 printf("\tunknown23:[0x%x]\n", i0->unknown23);
185 printf("\tunknown24:[0x%x]\n", i0->unknown24);
186 printf("\tunknown25:[0x%x]\n", i0->unknown25);
187 printf("\tunknown26:[0x%x]\n", i0->unknown26);
188 printf("\tunknown27:[0x%x]\n", i0->unknown27);
189 printf("\tunknown28:[0x%x]\n", i0->unknown28);
190 printf("\tunknown29:[0x%x]\n", i0->unknown29);
195 /****************************************************************************
196 ****************************************************************************/
198 static void display_print_info_1(PRINTER_INFO_1 *i1)
204 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), -1,
207 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
208 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), -1, STR_TERMINATE);
210 printf("\tflags:[0x%x]\n", i1->flags);
211 printf("\tname:[%s]\n", name);
212 printf("\tdescription:[%s]\n", desc);
213 printf("\tcomment:[%s]\n", comm);
218 /****************************************************************************
219 ****************************************************************************/
221 static void display_print_info_2(PRINTER_INFO_2 *i2)
223 fstring servername = "";
224 fstring printername = "";
225 fstring sharename = "";
226 fstring portname = "";
227 fstring drivername = "";
228 fstring comment = "";
229 fstring location = "";
230 fstring sepfile = "";
231 fstring printprocessor = "";
232 fstring datatype = "";
233 fstring parameters = "";
235 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), -1, STR_TERMINATE);
236 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), -1, STR_TERMINATE);
237 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), -1, STR_TERMINATE);
238 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), -1, STR_TERMINATE);
239 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), -1, STR_TERMINATE);
240 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), -1, STR_TERMINATE);
241 rpcstr_pull(location, i2->location.buffer,sizeof(location), -1, STR_TERMINATE);
242 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), -1, STR_TERMINATE);
243 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), -1, STR_TERMINATE);
244 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), -1, STR_TERMINATE);
245 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), -1, STR_TERMINATE);
247 printf("\tservername:[%s]\n", servername);
248 printf("\tprintername:[%s]\n", printername);
249 printf("\tsharename:[%s]\n", sharename);
250 printf("\tportname:[%s]\n", portname);
251 printf("\tdrivername:[%s]\n", drivername);
252 printf("\tcomment:[%s]\n", comment);
253 printf("\tlocation:[%s]\n", location);
254 printf("\tsepfile:[%s]\n", sepfile);
255 printf("\tprintprocessor:[%s]\n", printprocessor);
256 printf("\tdatatype:[%s]\n", datatype);
257 printf("\tparameters:[%s]\n", parameters);
258 printf("\tattributes:[0x%x]\n", i2->attributes);
259 printf("\tpriority:[0x%x]\n", i2->priority);
260 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
261 printf("\tstarttime:[0x%x]\n", i2->starttime);
262 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
263 printf("\tstatus:[0x%x]\n", i2->status);
264 printf("\tcjobs:[0x%x]\n", i2->cjobs);
265 printf("\taverageppm:[0x%x]\n", i2->averageppm);
268 display_sec_desc(i2->secdesc);
273 /****************************************************************************
274 ****************************************************************************/
276 static void display_print_info_3(PRINTER_INFO_3 *i3)
278 display_sec_desc(i3->secdesc);
283 /****************************************************************************
284 ****************************************************************************/
286 static void display_print_info7(struct spoolss_PrinterInfo7 *r)
288 printf("\tguid:[%s]\n", r->guid);
289 printf("\taction:[0x%x]\n", r->action);
293 /****************************************************************************
294 ****************************************************************************/
296 static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli,
298 int argc, const char **argv)
301 uint32 info_level = 1;
302 PRINTER_INFO_CTR ctr;
303 uint32 i = 0, num_printers;
308 printf("Usage: %s [level] [name]\n", argv[0]);
313 info_level = atoi(argv[1]);
316 fstrcpy(name, argv[2]);
318 slprintf(name, sizeof(name)-1, "\\\\%s", cli->desthost);
324 result = rpccli_spoolss_enum_printers(cli, mem_ctx, name, PRINTER_ENUM_LOCAL,
325 info_level, &num_printers, &ctr);
327 if (W_ERROR_IS_OK(result)) {
330 printf ("No printers returned.\n");
334 for (i = 0; i < num_printers; i++) {
337 display_print_info_0(&ctr.printers_0[i]);
340 display_print_info_1(&ctr.printers_1[i]);
343 display_print_info_2(&ctr.printers_2[i]);
346 display_print_info_3(&ctr.printers_3[i]);
349 printf("unknown info level %d\n", info_level);
359 /****************************************************************************
360 ****************************************************************************/
362 static void display_port_info_1(PORT_INFO_1 *i1)
366 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
367 printf("\tPort Name:\t[%s]\n", buffer);
370 /****************************************************************************
371 ****************************************************************************/
373 static void display_port_info_2(PORT_INFO_2 *i2)
377 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
378 printf("\tPort Name:\t[%s]\n", buffer);
379 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), -1, STR_TERMINATE);
381 printf("\tMonitor Name:\t[%s]\n", buffer);
382 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
384 printf("\tDescription:\t[%s]\n", buffer);
385 printf("\tPort Type:\t" );
386 if ( i2->port_type ) {
387 int comma = 0; /* hack */
389 if ( i2->port_type & PORT_TYPE_READ ) {
393 if ( i2->port_type & PORT_TYPE_WRITE ) {
394 printf( "%sWrite", comma ? ", " : "" );
397 /* These two have slightly different interpretations
398 on 95/98/ME but I'm disregarding that for now */
399 if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
400 printf( "%sRedirected", comma ? ", " : "" );
403 if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
404 printf( "%sNet-Attached", comma ? ", " : "" );
408 printf( "[Unset]\n" );
410 printf("\tReserved:\t[%d]\n", i2->reserved);
414 /****************************************************************************
415 ****************************************************************************/
417 static WERROR cmd_spoolss_enum_ports(struct rpc_pipe_client *cli,
418 TALLOC_CTX *mem_ctx, int argc,
422 uint32 info_level = 1;
427 printf("Usage: %s [level]\n", argv[0]);
432 info_level = atoi(argv[1]);
434 /* Enumerate ports */
438 result = rpccli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
440 if (W_ERROR_IS_OK(result)) {
443 for (i = 0; i < returned; i++) {
444 switch (info_level) {
446 display_port_info_1(&ctr.port.info_1[i]);
449 display_port_info_2(&ctr.port.info_2[i]);
452 printf("unknown info level %d\n", info_level);
461 /****************************************************************************
462 ****************************************************************************/
464 static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli,
466 int argc, const char **argv)
471 uint32 info_level = 2;
472 union spoolss_PrinterInfo info;
473 struct spoolss_SetPrinterInfoCtr info_ctr;
474 const char *printername, *comment = NULL;
475 struct spoolss_DevmodeContainer devmode_ctr;
476 struct sec_desc_buf secdesc_ctr;
478 if (argc == 1 || argc > 3) {
479 printf("Usage: %s printername comment\n", argv[0]);
484 /* Open a printer handle */
489 ZERO_STRUCT(devmode_ctr);
490 ZERO_STRUCT(secdesc_ctr);
492 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
494 /* get a printer handle */
495 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
499 if (!W_ERROR_IS_OK(result))
502 /* Get printer info */
503 result = rpccli_spoolss_getprinter(cli, mem_ctx,
508 if (!W_ERROR_IS_OK(result))
512 /* Modify the comment. */
513 info.info2.comment = comment;
514 info.info2.secdesc = NULL;
515 info.info2.devmode = NULL;
518 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
520 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
527 if (W_ERROR_IS_OK(result))
528 printf("Success in setting comment.\n");
531 if (is_valid_policy_hnd(&pol))
532 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
537 /****************************************************************************
538 ****************************************************************************/
540 static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli,
542 int argc, const char **argv)
547 uint32 info_level = 2;
548 union spoolss_PrinterInfo info;
549 const char *printername,
550 *new_printername = NULL;
551 struct spoolss_SetPrinterInfoCtr info_ctr;
552 struct spoolss_DevmodeContainer devmode_ctr;
553 struct sec_desc_buf secdesc_ctr;
555 ZERO_STRUCT(devmode_ctr);
556 ZERO_STRUCT(secdesc_ctr);
558 if (argc == 1 || argc > 3) {
559 printf("Usage: %s printername new_printername\n", argv[0]);
564 /* Open a printer handle */
566 new_printername = argv[2];
569 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
571 /* get a printer handle */
572 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
576 if (!W_ERROR_IS_OK(result))
579 /* Get printer info */
580 result = rpccli_spoolss_getprinter(cli, mem_ctx,
585 if (!W_ERROR_IS_OK(result))
588 /* Modify the printername. */
589 info.info2.printername = new_printername;
590 info.info2.devmode = NULL;
591 info.info2.secdesc = NULL;
593 info_ctr.level = info_level;
594 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
596 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
603 if (W_ERROR_IS_OK(result))
604 printf("Success in setting printername.\n");
607 if (is_valid_policy_hnd(&pol))
608 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
613 /****************************************************************************
614 ****************************************************************************/
616 static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli,
618 int argc, const char **argv)
622 uint32 info_level = 1;
623 const char *printername;
624 union spoolss_PrinterInfo info;
626 if (argc == 1 || argc > 3) {
627 printf("Usage: %s <printername> [level]\n", argv[0]);
631 /* Open a printer handle */
633 info_level = atoi(argv[2]);
636 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
638 /* get a printer handle */
640 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
642 SEC_FLAG_MAXIMUM_ALLOWED,
644 if (!W_ERROR_IS_OK(result))
647 /* Get printer info */
649 result = rpccli_spoolss_getprinter(cli, mem_ctx,
654 if (!W_ERROR_IS_OK(result))
657 /* Display printer info */
658 switch (info_level) {
661 display_print_info_0(ctr.printers_0);
664 display_print_info_1(ctr.printers_1);
667 display_print_info_2(ctr.printers_2);
670 display_print_info_3(ctr.printers_3);
674 display_print_info7(&info.info7);
677 printf("unknown info level %d\n", info_level);
681 if (is_valid_policy_hnd(&pol))
682 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
687 /****************************************************************************
688 ****************************************************************************/
690 static void display_reg_value(REGISTRY_VALUE value)
696 printf("%s: REG_DWORD: 0x%08x\n", value.valuename,
697 *((uint32 *) value.data_p));
700 rpcstr_pull_talloc(talloc_tos(),
705 printf("%s: REG_SZ: %s\n", value.valuename, text ? text : "");
708 char *hex = hex_encode_talloc(NULL, value.data_p, value.size);
710 printf("%s: REG_BINARY:", value.valuename);
712 for (i=0; i<len; i++) {
713 if (hex[i] == '\0') {
726 uint32 i, num_values;
729 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
730 value.size, &num_values,
732 d_printf("reg_pull_multi_sz failed\n");
736 for (i=0; i<num_values; i++) {
737 d_printf("%s\n", values[i]);
743 printf("%s: unknown type %d\n", value.valuename, value.type);
748 /****************************************************************************
749 ****************************************************************************/
751 static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli,
753 int argc, const char **argv)
758 const char *valuename;
759 REGISTRY_VALUE value;
762 printf("Usage: %s <printername> <valuename>\n", argv[0]);
763 printf("<printername> of . queries print server\n");
768 /* Open a printer handle */
770 if (strncmp(argv[1], ".", sizeof(".")) == 0)
771 fstrcpy(printername, cli->srv_name_slash);
773 slprintf(printername, sizeof(printername)-1, "%s\\%s",
774 cli->srv_name_slash, argv[1]);
776 /* get a printer handle */
778 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
780 SEC_FLAG_MAXIMUM_ALLOWED,
782 if (!W_ERROR_IS_OK(result))
785 /* Get printer info */
787 result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value);
789 if (!W_ERROR_IS_OK(result))
792 /* Display printer data */
794 fstrcpy(value.valuename, valuename);
795 display_reg_value(value);
799 if (is_valid_policy_hnd(&pol))
800 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
805 /****************************************************************************
806 ****************************************************************************/
808 static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli,
810 int argc, const char **argv)
816 const char *valuename, *keyname;
817 REGISTRY_VALUE value;
820 uint8_t *buffer = NULL;
821 uint32_t offered = 0;
825 printf("Usage: %s <printername> <keyname> <valuename>\n",
827 printf("<printername> of . queries print server\n");
833 /* Open a printer handle */
835 if (strncmp(argv[1], ".", sizeof(".")) == 0)
836 fstrcpy(printername, cli->srv_name_slash);
838 slprintf(printername, sizeof(printername)-1, "%s\\%s",
839 cli->srv_name_slash, argv[1]);
841 /* get a printer handle */
843 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
845 SEC_FLAG_MAXIMUM_ALLOWED,
847 if (!W_ERROR_IS_OK(result))
850 /* Get printer info */
852 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
861 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
863 buffer = talloc_array(mem_ctx, uint8_t, needed);
864 status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx,
875 if (!NT_STATUS_IS_OK(status)) {
879 if (!W_ERROR_IS_OK(result)) {
884 if (!W_ERROR_IS_OK(result))
887 /* Display printer data */
889 fstrcpy(value.valuename, valuename);
892 value.data_p = buffer;
894 display_reg_value(value);
897 if (is_valid_policy_hnd(&pol))
898 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
903 /****************************************************************************
904 ****************************************************************************/
906 static void display_print_driver_1(DRIVER_INFO_1 *i1)
912 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
914 printf ("Printer Driver Info 1:\n");
915 printf ("\tDriver Name: [%s]\n\n", name);
920 /****************************************************************************
921 ****************************************************************************/
923 static void display_print_driver_2(DRIVER_INFO_2 *i1)
926 fstring architecture;
933 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
934 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
935 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
936 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
937 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
939 printf ("Printer Driver Info 2:\n");
940 printf ("\tVersion: [%x]\n", i1->version);
941 printf ("\tDriver Name: [%s]\n", name);
942 printf ("\tArchitecture: [%s]\n", architecture);
943 printf ("\tDriver Path: [%s]\n", driverpath);
944 printf ("\tDatafile: [%s]\n", datafile);
945 printf ("\tConfigfile: [%s]\n\n", configfile);
950 /****************************************************************************
951 ****************************************************************************/
953 static void display_print_driver_3(DRIVER_INFO_3 *i1)
956 fstring architecture = "";
957 fstring driverpath = "";
958 fstring datafile = "";
959 fstring configfile = "";
960 fstring helpfile = "";
961 fstring dependentfiles = "";
962 fstring monitorname = "";
963 fstring defaultdatatype = "";
971 rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE);
972 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), -1, STR_TERMINATE);
973 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE);
974 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE);
975 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE);
976 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE);
977 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), -1, STR_TERMINATE);
978 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), -1, STR_TERMINATE);
980 printf ("Printer Driver Info 3:\n");
981 printf ("\tVersion: [%x]\n", i1->version);
982 printf ("\tDriver Name: [%s]\n",name);
983 printf ("\tArchitecture: [%s]\n", architecture);
984 printf ("\tDriver Path: [%s]\n", driverpath);
985 printf ("\tDatafile: [%s]\n", datafile);
986 printf ("\tConfigfile: [%s]\n", configfile);
987 printf ("\tHelpfile: [%s]\n\n", helpfile);
991 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE);
993 length+=strlen(dependentfiles)+1;
995 if (strlen(dependentfiles) > 0)
997 printf ("\tDependentfiles: [%s]\n", dependentfiles);
1007 printf ("\tMonitorname: [%s]\n", monitorname);
1008 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
1013 /****************************************************************************
1014 ****************************************************************************/
1016 static void display_print_driver1(struct spoolss_DriverInfo1 *r)
1022 printf("Printer Driver Info 1:\n");
1023 printf("\tDriver Name: [%s]\n\n", r->driver_name);
1026 /****************************************************************************
1027 ****************************************************************************/
1029 static void display_print_driver2(struct spoolss_DriverInfo2 *r)
1035 printf("Printer Driver Info 2:\n");
1036 printf("\tVersion: [%x]\n", r->version);
1037 printf("\tDriver Name: [%s]\n", r->driver_name);
1038 printf("\tArchitecture: [%s]\n", r->architecture);
1039 printf("\tDriver Path: [%s]\n", r->driver_path);
1040 printf("\tDatafile: [%s]\n", r->data_file);
1041 printf("\tConfigfile: [%s]\n\n", r->config_file);
1044 /****************************************************************************
1045 ****************************************************************************/
1047 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
1055 printf("Printer Driver Info 3:\n");
1056 printf("\tVersion: [%x]\n", r->version);
1057 printf("\tDriver Name: [%s]\n", r->driver_name);
1058 printf("\tArchitecture: [%s]\n", r->architecture);
1059 printf("\tDriver Path: [%s]\n", r->driver_path);
1060 printf("\tDatafile: [%s]\n", r->data_file);
1061 printf("\tConfigfile: [%s]\n\n", r->config_file);
1062 printf("\tHelpfile: [%s]\n\n", r->help_file);
1064 for (i=0; r->dependent_files[i] != NULL; i++) {
1065 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
1070 printf("\tMonitorname: [%s]\n", r->monitor_name);
1071 printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype);
1075 /****************************************************************************
1076 ****************************************************************************/
1078 static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli,
1079 TALLOC_CTX *mem_ctx,
1080 int argc, const char **argv)
1084 uint32 info_level = 3;
1085 const char *printername;
1087 bool success = False;
1088 union spoolss_DriverInfo info;
1089 uint32_t server_major_version;
1090 uint32_t server_minor_version;
1092 if ((argc == 1) || (argc > 3))
1094 printf("Usage: %s <printername> [level]\n", argv[0]);
1098 /* get the arguments need to open the printer handle */
1100 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1103 info_level = atoi(argv[2]);
1105 /* Open a printer handle */
1107 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1111 if (!W_ERROR_IS_OK(werror)) {
1112 printf("Error opening printer handle for %s!\n", printername);
1116 /* loop through and print driver info level for each architecture */
1118 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1120 werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
1122 archi_table[i].long_archi,
1125 archi_table[i].version,
1128 &server_major_version,
1129 &server_minor_version);
1130 if (!W_ERROR_IS_OK(werror))
1133 /* need at least one success */
1137 printf ("\n[%s]\n", archi_table[i].long_archi);
1139 switch (info_level) {
1141 display_print_driver1(&info.info1);
1144 display_print_driver2(&info.info2);
1147 display_print_driver3(&info.info3);
1150 printf("unknown info level %d\n", info_level);
1157 if (is_valid_policy_hnd(&pol))
1158 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1166 /****************************************************************************
1167 ****************************************************************************/
1169 static WERROR cmd_spoolss_enum_drivers(struct rpc_pipe_client *cli,
1170 TALLOC_CTX *mem_ctx,
1171 int argc, const char **argv)
1173 WERROR werror = WERR_OK;
1174 uint32 info_level = 1;
1175 PRINTER_DRIVER_CTR ctr;
1180 printf("Usage: enumdrivers [level]\n");
1185 info_level = atoi(argv[1]);
1188 /* loop through and print driver info level for each architecture */
1189 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1190 /* check to see if we already asked for this architecture string */
1192 if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
1195 werror = rpccli_spoolss_enumprinterdrivers(
1196 cli, mem_ctx, info_level,
1197 archi_table[i].long_archi, &returned, &ctr);
1199 if (W_ERROR_V(werror) == W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
1200 printf ("Server does not support environment [%s]\n",
1201 archi_table[i].long_archi);
1209 if (!W_ERROR_IS_OK(werror)) {
1210 printf ("Error getting driver for environment [%s] - %d\n",
1211 archi_table[i].long_archi, W_ERROR_V(werror));
1215 printf ("\n[%s]\n", archi_table[i].long_archi);
1220 for (j=0; j < returned; j++) {
1221 display_print_driver_1 (&ctr.info1[j]);
1225 for (j=0; j < returned; j++) {
1226 display_print_driver_2 (&ctr.info2[j]);
1230 for (j=0; j < returned; j++) {
1231 display_print_driver_3 (&ctr.info3[j]);
1235 printf("unknown info level %d\n", info_level);
1236 return WERR_UNKNOWN_LEVEL;
1243 /****************************************************************************
1244 ****************************************************************************/
1246 static void display_printdriverdir_1(struct spoolss_DriverDirectoryInfo1 *r)
1248 printf("\tDirectory Name:[%s]\n", r->directory_name);
1251 /****************************************************************************
1252 ****************************************************************************/
1254 static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli,
1255 TALLOC_CTX *mem_ctx,
1256 int argc, const char **argv)
1260 const char *env = SPOOLSS_ARCHITECTURE_NT_X86;
1263 union spoolss_DriverDirectoryInfo info;
1267 printf("Usage: %s [environment]\n", argv[0]);
1271 /* Get the arguments need to open the printer handle */
1277 /* Get the directory. Only use Info level 1 */
1279 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1280 cli->srv_name_slash,
1288 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1290 buffer = data_blob_talloc_zero(mem_ctx, needed);
1292 status = rpccli_spoolss_GetPrinterDriverDirectory(cli, mem_ctx,
1293 cli->srv_name_slash,
1303 if (W_ERROR_IS_OK(result)) {
1304 display_printdriverdir_1(&info.info1);
1310 /****************************************************************************
1311 ****************************************************************************/
1313 static void set_drv_info_3_env(TALLOC_CTX *mem_ctx,
1314 struct spoolss_AddDriverInfo3 *info,
1320 for (i=0; archi_table[i].long_archi != NULL; i++)
1322 if (strcmp(arch, archi_table[i].short_archi) == 0)
1324 info->version = archi_table[i].version;
1325 info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi);
1330 if (archi_table[i].long_archi == NULL)
1332 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
1339 /**************************************************************************
1340 wrapper for strtok to get the next parameter from a delimited list.
1341 Needed to handle the empty parameter string denoted by "NULL"
1342 *************************************************************************/
1344 static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str,
1345 const char *delim, const char **dest,
1350 /* get the next token */
1351 ptr = strtok_r(str, delim, saveptr);
1353 /* a string of 'NULL' is used to represent an empty
1354 parameter because two consecutive delimiters
1355 will not return an empty string. See man strtok(3)
1357 if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) {
1362 *dest = talloc_strdup(mem_ctx, ptr);
1368 /********************************************************************************
1369 fill in the members of a spoolss_AddDriverInfo3 struct using a character
1370 string in the form of
1371 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1372 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1373 <Default Data Type>:<Comma Separated list of Files>
1374 *******************************************************************************/
1376 static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r,
1381 char *saveptr = NULL;
1382 struct spoolss_StringArray *deps;
1383 const char **file_array = NULL;
1386 /* fill in the UNISTR fields */
1387 str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr);
1388 str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr);
1389 str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr);
1390 str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr);
1391 str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr);
1392 str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr);
1393 str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr);
1395 /* <Comma Separated List of Dependent Files> */
1396 /* save the beginning of the string */
1397 str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr);
1400 /* begin to strip out each filename */
1401 str = strtok_r(str, ",", &saveptr);
1403 /* no dependent files, we are done */
1408 deps = talloc_zero(mem_ctx, struct spoolss_StringArray);
1413 while (str != NULL) {
1414 add_string_to_array(deps, str, &file_array, &count);
1415 str = strtok_r(NULL, ",", &saveptr);
1418 deps->string = talloc_zero_array(deps, const char *, count + 1);
1419 if (!deps->string) {
1423 for (i=0; i < count; i++) {
1424 deps->string[i] = file_array[i];
1427 r->dependent_files = deps;
1432 /****************************************************************************
1433 ****************************************************************************/
1435 static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli,
1436 TALLOC_CTX *mem_ctx,
1437 int argc, const char **argv)
1442 struct spoolss_AddDriverInfoCtr info_ctr;
1443 struct spoolss_AddDriverInfo3 info3;
1447 /* parse the command arguments */
1448 if (argc != 3 && argc != 4)
1450 printf ("Usage: %s <Environment> \\\n", argv[0]);
1451 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1452 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1453 printf ("\t<Default Data Type>:<Comma Separated list of Files> \\\n");
1454 printf ("\t[version]\n");
1459 /* Fill in the spoolss_AddDriverInfo3 struct */
1462 arch = cmd_spoolss_get_short_archi(argv[1]);
1464 printf ("Error Unknown architechture [%s]\n", argv[1]);
1465 return WERR_INVALID_PARAM;
1468 set_drv_info_3_env(mem_ctx, &info3, arch);
1470 driver_args = talloc_strdup( mem_ctx, argv[2] );
1471 if (!init_drv_info_3_members(mem_ctx, &info3, driver_args ))
1473 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1474 return WERR_INVALID_PARAM;
1477 /* if printer driver version specified, override the default version
1478 * used by the architecture. This allows installation of Windows
1479 * 2000 (version 3) printer drivers. */
1482 info3.version = atoi(argv[3]);
1486 info_ctr.level = level;
1487 info_ctr.info.info3 = &info3;
1489 status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx,
1490 cli->srv_name_slash,
1493 if (!NT_STATUS_IS_OK(status)) {
1494 return ntstatus_to_werror(status);
1496 if (W_ERROR_IS_OK(result)) {
1497 printf ("Printer Driver %s successfully installed.\n",
1505 /****************************************************************************
1506 ****************************************************************************/
1508 static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli,
1509 TALLOC_CTX *mem_ctx,
1510 int argc, const char **argv)
1513 struct spoolss_SetPrinterInfoCtr info_ctr;
1514 struct spoolss_SetPrinterInfo2 info2;
1516 /* parse the command arguments */
1519 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1523 /* Fill in the DRIVER_INFO_2 struct */
1526 info2.printername = argv[1];
1527 info2.drivername = argv[3];
1528 info2.sharename = argv[2];
1529 info2.portname = argv[4];
1530 info2.comment = "Created by rpcclient";
1531 info2.printprocessor = "winprint";
1532 info2.datatype = "RAW";
1533 info2.devmode = NULL;
1534 info2.secdesc = NULL;
1535 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1537 info2.defaultpriority = 0;
1538 info2.starttime = 0;
1539 info2.untiltime = 0;
1541 /* These three fields must not be used by AddPrinter()
1542 as defined in the MS Platform SDK documentation..
1546 info2.averageppm = 0;
1550 info_ctr.info.info2 = &info2;
1552 result = rpccli_spoolss_addprinterex(cli, mem_ctx,
1554 if (W_ERROR_IS_OK(result))
1555 printf ("Printer %s successfully installed.\n", argv[1]);
1560 /****************************************************************************
1561 ****************************************************************************/
1563 static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli,
1564 TALLOC_CTX *mem_ctx,
1565 int argc, const char **argv)
1571 const char *printername;
1572 union spoolss_PrinterInfo info;
1573 struct spoolss_SetPrinterInfoCtr info_ctr;
1574 struct spoolss_DevmodeContainer devmode_ctr;
1575 struct sec_desc_buf secdesc_ctr;
1577 ZERO_STRUCT(devmode_ctr);
1578 ZERO_STRUCT(secdesc_ctr);
1580 /* parse the command arguments */
1583 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1587 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1589 /* Get a printer handle */
1591 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1595 if (!W_ERROR_IS_OK(result))
1598 /* Get printer info */
1600 result = rpccli_spoolss_getprinter(cli, mem_ctx,
1605 if (!W_ERROR_IS_OK(result)) {
1606 printf ("Unable to retrieve printer information!\n");
1610 /* Set the printer driver */
1612 info.info2.drivername = argv[2];
1613 info.info2.devmode = NULL;
1614 info.info2.secdesc = NULL;
1617 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2;
1619 status = rpccli_spoolss_SetPrinter(cli, mem_ctx,
1626 if (!W_ERROR_IS_OK(result)) {
1627 printf("SetPrinter call failed!\n");
1631 printf("Successfully set %s to driver %s.\n", argv[1], argv[2]);
1636 if (is_valid_policy_hnd(&pol))
1637 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
1643 /****************************************************************************
1644 ****************************************************************************/
1646 static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli,
1647 TALLOC_CTX *mem_ctx,
1648 int argc, const char **argv)
1650 WERROR result, ret = WERR_UNKNOWN_PRINTER_DRIVER;
1656 const char *arch = NULL;
1657 uint32_t delete_flags = 0;
1659 /* parse the command arguments */
1660 if (argc < 2 || argc > 4) {
1661 printf ("Usage: %s <driver> [arch] [version]\n", argv[0]);
1668 vers = atoi (argv[3]);
1671 delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1674 /* delete the driver for all architectures */
1675 for (i=0; archi_table[i].long_archi; i++) {
1677 if (arch && !strequal( archi_table[i].long_archi, arch))
1680 if (vers >= 0 && archi_table[i].version != vers)
1683 /* make the call to remove the driver */
1684 status = rpccli_spoolss_DeletePrinterDriverEx(cli, mem_ctx,
1685 cli->srv_name_slash,
1686 archi_table[i].long_archi,
1689 archi_table[i].version,
1692 if ( !W_ERROR_IS_OK(result) )
1694 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1695 printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n",
1696 argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result));
1701 printf ("Driver %s and files removed for arch [%s] (version: %d).\n", argv[1],
1702 archi_table[i].long_archi, archi_table[i].version);
1711 /****************************************************************************
1712 ****************************************************************************/
1714 static WERROR cmd_spoolss_deletedriver(struct rpc_pipe_client *cli,
1715 TALLOC_CTX *mem_ctx,
1716 int argc, const char **argv)
1718 WERROR result = WERR_OK;
1722 /* parse the command arguments */
1724 printf ("Usage: %s <driver>\n", argv[0]);
1728 /* delete the driver for all architectures */
1729 for (i=0; archi_table[i].long_archi; i++) {
1730 /* make the call to remove the driver */
1731 status = rpccli_spoolss_DeletePrinterDriver(cli, mem_ctx,
1732 cli->srv_name_slash,
1733 archi_table[i].long_archi,
1736 if (!NT_STATUS_IS_OK(status)) {
1739 if ( !W_ERROR_IS_OK(result) ) {
1740 if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) {
1741 printf ("Failed to remove driver %s for arch [%s] - error 0x%x!\n",
1742 argv[1], archi_table[i].long_archi,
1746 printf ("Driver %s removed for arch [%s].\n", argv[1],
1747 archi_table[i].long_archi);
1754 /****************************************************************************
1755 ****************************************************************************/
1757 static WERROR cmd_spoolss_getprintprocdir(struct rpc_pipe_client *cli,
1758 TALLOC_CTX *mem_ctx,
1759 int argc, const char **argv)
1763 const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
1766 union spoolss_PrintProcessorDirectoryInfo info;
1769 /* parse the command arguments */
1771 printf ("Usage: %s [environment]\n", argv[0]);
1776 environment = argv[1];
1779 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1780 cli->srv_name_slash,
1788 if (W_ERROR_EQUAL(result, WERR_INSUFFICIENT_BUFFER)) {
1790 buffer = data_blob_talloc_zero(mem_ctx, needed);
1792 status = rpccli_spoolss_GetPrintProcessorDirectory(cli, mem_ctx,
1793 cli->srv_name_slash,
1803 if (W_ERROR_IS_OK(result)) {
1804 printf("%s\n", info.info1.directory_name);
1810 /****************************************************************************
1811 ****************************************************************************/
1813 static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1814 int argc, const char **argv)
1819 const char *printername;
1820 union spoolss_AddFormInfo info;
1821 struct spoolss_AddFormInfo1 info1;
1822 struct spoolss_AddFormInfo2 info2;
1825 /* Parse the command arguments */
1827 if (argc < 3 || argc > 5) {
1828 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
1832 /* Get a printer handle */
1834 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1836 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1840 if (!W_ERROR_IS_OK(werror))
1843 /* Dummy up some values for the form data */
1846 level = atoi(argv[3]);
1851 info1.flags = FORM_USER;
1852 info1.form_name = argv[2];
1853 info1.size.width = 100;
1854 info1.size.height = 100;
1855 info1.area.left = 0;
1856 info1.area.top = 10;
1857 info1.area.right = 20;
1858 info1.area.bottom = 30;
1860 info.info1 = &info1;
1864 info2.flags = FORM_USER;
1865 info2.form_name = argv[2];
1866 info2.size.width = 100;
1867 info2.size.height = 100;
1868 info2.area.left = 0;
1869 info2.area.top = 10;
1870 info2.area.right = 20;
1871 info2.area.bottom = 30;
1872 info2.keyword = argv[2];
1873 info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE;
1874 info2.mui_dll = NULL;
1875 info2.ressource_id = 0;
1876 info2.display_name = argv[2];
1879 info.info2 = &info2;
1887 status = rpccli_spoolss_AddForm(cli, mem_ctx,
1894 if (is_valid_policy_hnd(&handle))
1895 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1900 /****************************************************************************
1901 ****************************************************************************/
1903 static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1904 int argc, const char **argv)
1909 const char *printername;
1910 union spoolss_AddFormInfo info;
1911 struct spoolss_AddFormInfo1 info1;
1913 /* Parse the command arguments */
1916 printf ("Usage: %s <printer> <formname>\n", argv[0]);
1920 /* Get a printer handle */
1922 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
1924 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
1926 SEC_FLAG_MAXIMUM_ALLOWED,
1928 if (!W_ERROR_IS_OK(werror))
1931 /* Dummy up some values for the form data */
1933 info1.flags = FORM_PRINTER;
1934 info1.size.width = 100;
1935 info1.size.height = 100;
1936 info1.area.left = 0;
1937 info1.area.top = 1000;
1938 info1.area.right = 2000;
1939 info1.area.bottom = 3000;
1940 info1.form_name = argv[2];
1942 info.info1 = &info1;
1946 status = rpccli_spoolss_SetForm(cli, mem_ctx,
1954 if (is_valid_policy_hnd(&handle))
1955 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
1960 /****************************************************************************
1961 ****************************************************************************/
1963 static const char *get_form_flag(int form_flag)
1965 switch (form_flag) {
1969 return "FORM_BUILTIN";
1971 return "FORM_PRINTER";
1977 /****************************************************************************
1978 ****************************************************************************/
1980 static void display_form(FORM_1 *form)
1982 fstring form_name = "";
1984 if (form->name.buffer)
1985 rpcstr_pull(form_name, form->name.buffer,
1986 sizeof(form_name), -1, STR_TERMINATE);
1989 "\tflag: %s (%d)\n" \
1990 "\twidth: %d, length: %d\n" \
1991 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
1992 form_name, get_form_flag(form->flag), form->flag,
1993 form->width, form->length,
1994 form->left, form->right,
1995 form->top, form->bottom);
1998 /****************************************************************************
1999 ****************************************************************************/
2001 static void display_form_info1(struct spoolss_FormInfo1 *r)
2004 "\tflag: %s (%d)\n" \
2005 "\twidth: %d, length: %d\n" \
2006 "\tleft: %d, right: %d, top: %d, bottom: %d\n\n",
2007 r->form_name, get_form_flag(r->flags), r->flags,
2008 r->size.width, r->size.height,
2009 r->area.left, r->area.right,
2010 r->area.top, r->area.bottom);
2013 /****************************************************************************
2014 ****************************************************************************/
2016 static void display_form_info2(struct spoolss_FormInfo2 *r)
2019 "\tflag: %s (%d)\n" \
2020 "\twidth: %d, length: %d\n" \
2021 "\tleft: %d, right: %d, top: %d, bottom: %d\n",
2022 r->form_name, get_form_flag(r->flags), r->flags,
2023 r->size.width, r->size.height,
2024 r->area.left, r->area.right,
2025 r->area.top, r->area.bottom);
2026 printf("\tkeyword: %s\n", r->keyword);
2027 printf("\tstring_type: 0x%08x\n", r->string_type);
2028 printf("\tmui_dll: %s\n", r->mui_dll);
2029 printf("\tressource_id: 0x%08x\n", r->ressource_id);
2030 printf("\tdisplay_name: %s\n", r->display_name);
2031 printf("\tlang_id: %d\n", r->lang_id);
2035 /****************************************************************************
2036 ****************************************************************************/
2038 static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2039 int argc, const char **argv)
2044 const char *printername;
2046 uint32_t offered = 0;
2047 union spoolss_FormInfo info;
2051 /* Parse the command arguments */
2053 if (argc < 3 || argc > 5) {
2054 printf ("Usage: %s <printer> <formname> [level]\n", argv[0]);
2058 /* Get a printer handle */
2060 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2062 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2064 SEC_FLAG_MAXIMUM_ALLOWED,
2066 if (!W_ERROR_IS_OK(werror))
2070 level = atoi(argv[3]);
2075 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2084 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
2085 buffer = data_blob_talloc_zero(mem_ctx, needed);
2087 status = rpccli_spoolss_GetForm(cli, mem_ctx,
2098 if (!NT_STATUS_IS_OK(status)) {
2104 display_form_info1(&info.info1);
2107 display_form_info2(&info.info2);
2112 if (is_valid_policy_hnd(&handle))
2113 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2118 /****************************************************************************
2119 ****************************************************************************/
2121 static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli,
2122 TALLOC_CTX *mem_ctx, int argc,
2128 const char *printername;
2130 /* Parse the command arguments */
2133 printf ("Usage: %s <printer> <formname>\n", argv[0]);
2137 /* Get a printer handle */
2139 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2141 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2143 SEC_FLAG_MAXIMUM_ALLOWED,
2145 if (!W_ERROR_IS_OK(werror))
2148 /* Delete the form */
2150 status = rpccli_spoolss_DeleteForm(cli, mem_ctx,
2154 if (!NT_STATUS_IS_OK(status)) {
2155 return ntstatus_to_werror(status);
2159 if (is_valid_policy_hnd(&handle))
2160 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2165 /****************************************************************************
2166 ****************************************************************************/
2168 static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli,
2169 TALLOC_CTX *mem_ctx, int argc,
2174 const char *printername;
2175 uint32 num_forms, level = 1, i;
2178 /* Parse the command arguments */
2181 printf ("Usage: %s <printer>\n", argv[0]);
2185 /* Get a printer handle */
2187 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2189 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2191 SEC_FLAG_MAXIMUM_ALLOWED,
2193 if (!W_ERROR_IS_OK(werror))
2196 /* Enumerate forms */
2198 werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms);
2200 if (!W_ERROR_IS_OK(werror))
2203 /* Display output */
2205 for (i = 0; i < num_forms; i++) {
2207 display_form(&forms[i]);
2212 if (is_valid_policy_hnd(&handle))
2213 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
2218 /****************************************************************************
2219 ****************************************************************************/
2221 static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli,
2222 TALLOC_CTX *mem_ctx,
2223 int argc, const char **argv)
2226 const char *printername;
2228 union spoolss_PrinterInfo info;
2229 REGISTRY_VALUE value;
2230 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2232 /* parse the command arguments */
2234 printf ("Usage: %s <printer> <string|binary|dword|multistring>"
2235 " <value> <data>\n",
2237 result = WERR_INVALID_PARAM;
2241 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2243 value.type = REG_NONE;
2245 if (strequal(argv[2], "string")) {
2246 value.type = REG_SZ;
2249 if (strequal(argv[2], "binary")) {
2250 value.type = REG_BINARY;
2253 if (strequal(argv[2], "dword")) {
2254 value.type = REG_DWORD;
2257 if (strequal(argv[2], "multistring")) {
2258 value.type = REG_MULTI_SZ;
2261 if (value.type == REG_NONE) {
2262 printf("Unknown data type: %s\n", argv[2]);
2263 result = WERR_INVALID_PARAM;
2267 /* get a printer handle */
2269 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2271 SEC_FLAG_MAXIMUM_ALLOWED,
2273 if (!W_ERROR_IS_OK(result))
2276 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2281 if (!W_ERROR_IS_OK(result))
2284 printf("%s\n", current_timestring(tmp_ctx, True));
2285 printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id);
2287 /* Set the printer data */
2289 fstrcpy(value.valuename, argv[3]);
2291 switch (value.type) {
2294 init_unistr2(&data, argv[4], UNI_STR_TERMINATE);
2295 value.size = data.uni_str_len * 2;
2297 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer,
2300 value.data_p = NULL;
2305 uint32 data = strtoul(argv[4], NULL, 10);
2306 value.size = sizeof(data);
2308 value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, &data,
2311 value.data_p = NULL;
2316 DATA_BLOB data = strhex_to_data_blob(mem_ctx, argv[4]);
2317 value.data_p = data.data;
2318 value.size = data.length;
2321 case REG_MULTI_SZ: {
2326 for (i=4; i<argc; i++) {
2327 if (strcmp(argv[i], "NULL") == 0) {
2330 len += strlen(argv[i])+1;
2334 value.data_p = TALLOC_ARRAY(mem_ctx, unsigned char, value.size);
2335 if (value.data_p == NULL) {
2336 result = WERR_NOMEM;
2340 p = (char *)value.data_p;
2342 for (i=4; i<argc; i++) {
2343 size_t l = (strlen(argv[i])+1)*2;
2344 rpcstr_push(p, argv[i], len, STR_TERMINATE);
2348 SMB_ASSERT(len == 0);
2352 printf("Unknown data type: %s\n", argv[2]);
2353 result = WERR_INVALID_PARAM;
2357 result = rpccli_spoolss_setprinterdata(cli, mem_ctx, &pol, &value);
2359 if (!W_ERROR_IS_OK(result)) {
2360 printf ("Unable to set [%s=%s]!\n", argv[3], argv[4]);
2363 printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]);
2365 result = rpccli_spoolss_getprinter(cli, mem_ctx,
2370 if (!W_ERROR_IS_OK(result))
2373 printf("%s\n", current_timestring(tmp_ctx, True));
2374 printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id);
2378 TALLOC_FREE(tmp_ctx);
2379 if (is_valid_policy_hnd(&pol))
2380 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
2385 /****************************************************************************
2386 ****************************************************************************/
2388 static void display_job_info_1(JOB_INFO_1 *job)
2390 fstring username = "", document = "", text_status = "";
2392 rpcstr_pull(username, job->username.buffer,
2393 sizeof(username), -1, STR_TERMINATE);
2395 rpcstr_pull(document, job->document.buffer,
2396 sizeof(document), -1, STR_TERMINATE);
2398 rpcstr_pull(text_status, job->text_status.buffer,
2399 sizeof(text_status), -1, STR_TERMINATE);
2401 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", job->position, job->jobid,
2402 username, document, text_status, job->pagesprinted,
2406 /****************************************************************************
2407 ****************************************************************************/
2409 static void display_job_info_2(JOB_INFO_2 *job)
2411 fstring username = "", document = "", text_status = "";
2413 rpcstr_pull(username, job->username.buffer,
2414 sizeof(username), -1, STR_TERMINATE);
2416 rpcstr_pull(document, job->document.buffer,
2417 sizeof(document), -1, STR_TERMINATE);
2419 rpcstr_pull(text_status, job->text_status.buffer,
2420 sizeof(text_status), -1, STR_TERMINATE);
2422 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", job->position, job->jobid,
2423 username, document, text_status, job->pagesprinted,
2424 job->totalpages, job->size);
2427 /****************************************************************************
2428 ****************************************************************************/
2430 static void display_job_info1(struct spoolss_JobInfo1 *r)
2432 printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id,
2433 r->user_name, r->document_name, r->text_status, r->pages_printed,
2437 /****************************************************************************
2438 ****************************************************************************/
2440 static void display_job_info2(struct spoolss_JobInfo2 *r)
2442 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n",
2443 r->position, r->job_id,
2444 r->user_name, r->document_name, r->text_status, r->pages_printed,
2445 r->total_pages, r->size);
2448 /****************************************************************************
2449 ****************************************************************************/
2451 static void display_job_info3(struct spoolss_JobInfo3 *r)
2453 printf("jobid[%d], next_jobid[%d]\n",
2454 r->job_id, r->next_job_id);
2457 /****************************************************************************
2458 ****************************************************************************/
2460 static void display_job_info4(struct spoolss_JobInfo4 *r)
2462 printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n",
2463 r->position, r->job_id,
2464 r->user_name, r->document_name, r->text_status, r->pages_printed,
2465 r->total_pages, r->size, r->size_high);
2468 /****************************************************************************
2469 ****************************************************************************/
2471 static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli,
2472 TALLOC_CTX *mem_ctx, int argc,
2476 uint32 level = 1, num_jobs, i;
2477 const char *printername;
2481 if (argc < 2 || argc > 3) {
2482 printf("Usage: %s printername [level]\n", argv[0]);
2487 level = atoi(argv[2]);
2489 /* Open printer handle */
2491 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2493 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2495 SEC_FLAG_MAXIMUM_ALLOWED,
2497 if (!W_ERROR_IS_OK(result))
2500 /* Enumerate ports */
2502 result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000,
2505 if (!W_ERROR_IS_OK(result))
2508 for (i = 0; i < num_jobs; i++) {
2511 display_job_info_1(&ctr.job.job_info_1[i]);
2514 display_job_info_2(&ctr.job.job_info_2[i]);
2517 d_printf("unknown info level %d\n", level);
2523 if (is_valid_policy_hnd(&hnd))
2524 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2529 /****************************************************************************
2530 ****************************************************************************/
2532 static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli,
2533 TALLOC_CTX *mem_ctx, int argc,
2537 const char *printername;
2538 struct policy_handle hnd;
2541 union spoolss_JobInfo info;
2543 if (argc < 3 || argc > 4) {
2544 printf("Usage: %s printername job_id [level]\n", argv[0]);
2548 job_id = atoi(argv[2]);
2551 level = atoi(argv[3]);
2554 /* Open printer handle */
2556 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2558 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2560 SEC_FLAG_MAXIMUM_ALLOWED,
2562 if (!W_ERROR_IS_OK(result)) {
2566 /* Enumerate ports */
2568 result = rpccli_spoolss_getjob(cli, mem_ctx,
2575 if (!W_ERROR_IS_OK(result)) {
2581 display_job_info1(&info.info1);
2584 display_job_info2(&info.info2);
2587 display_job_info3(&info.info3);
2590 display_job_info4(&info.info4);
2593 d_printf("unknown info level %d\n", level);
2598 if (is_valid_policy_hnd(&hnd)) {
2599 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2606 /****************************************************************************
2607 ****************************************************************************/
2609 static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli,
2610 TALLOC_CTX *mem_ctx, int argc,
2614 uint32 i=0, val_needed, data_needed;
2615 const char *printername;
2619 printf("Usage: %s printername\n", argv[0]);
2623 /* Open printer handle */
2625 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2627 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2629 SEC_FLAG_MAXIMUM_ALLOWED,
2631 if (!W_ERROR_IS_OK(result))
2634 /* Enumerate data */
2636 result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0,
2637 &val_needed, &data_needed,
2639 while (W_ERROR_IS_OK(result)) {
2640 REGISTRY_VALUE value;
2641 result = rpccli_spoolss_enumprinterdata(
2642 cli, mem_ctx, &hnd, i++, val_needed,
2643 data_needed, 0, 0, &value);
2644 if (W_ERROR_IS_OK(result))
2645 display_reg_value(value);
2647 if (W_ERROR_V(result) == ERRnomoreitems)
2648 result = W_ERROR(ERRsuccess);
2651 if (is_valid_policy_hnd(&hnd))
2652 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2657 /****************************************************************************
2658 ****************************************************************************/
2660 static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli,
2661 TALLOC_CTX *mem_ctx, int argc,
2666 const char *printername;
2667 const char *keyname = NULL;
2669 REGVAL_CTR *ctr = NULL;
2672 printf("Usage: %s printername <keyname>\n", argv[0]);
2678 /* Open printer handle */
2680 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2682 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2684 SEC_FLAG_MAXIMUM_ALLOWED,
2686 if (!W_ERROR_IS_OK(result))
2689 /* Enumerate subkeys */
2691 if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
2694 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &hnd, keyname, ctr);
2696 if (!W_ERROR_IS_OK(result))
2699 for (i=0; i < ctr->num_values; i++) {
2700 display_reg_value(*(ctr->values[i]));
2706 if (is_valid_policy_hnd(&hnd))
2707 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2712 /****************************************************************************
2713 ****************************************************************************/
2715 static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli,
2716 TALLOC_CTX *mem_ctx, int argc,
2720 const char *printername;
2721 const char *keyname = NULL;
2723 uint16 *keylist = NULL, *curkey;
2725 if (argc < 2 || argc > 3) {
2726 printf("Usage: %s printername [keyname]\n", argv[0]);
2735 /* Open printer handle */
2737 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2739 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2741 SEC_FLAG_MAXIMUM_ALLOWED,
2743 if (!W_ERROR_IS_OK(result))
2746 /* Enumerate subkeys */
2748 result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL);
2750 if (!W_ERROR_IS_OK(result))
2754 while (*curkey != 0) {
2755 char *subkey = NULL;
2756 rpcstr_pull_talloc(mem_ctx, &subkey, curkey, -1,
2761 printf("%s\n", subkey);
2762 curkey += strlen(subkey) + 1;
2769 if (is_valid_policy_hnd(&hnd))
2770 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2775 /****************************************************************************
2776 ****************************************************************************/
2778 static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli,
2779 TALLOC_CTX *mem_ctx, int argc,
2782 const char *printername;
2783 const char *clientname;
2787 struct spoolss_NotifyOption option;
2790 printf("Usage: %s printername\n", argv[0]);
2797 RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
2799 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
2801 SEC_FLAG_MAXIMUM_ALLOWED,
2803 if (!W_ERROR_IS_OK(result)) {
2804 printf("Error opening %s\n", argv[1]);
2808 /* Create spool options */
2813 option.types = talloc_array(mem_ctx, struct spoolss_NotifyOptionType, 2);
2814 if (option.types == NULL) {
2815 result = WERR_NOMEM;
2819 option.types[0].type = PRINTER_NOTIFY_TYPE;
2820 option.types[0].count = 1;
2821 option.types[0].fields = talloc_array(mem_ctx, enum spoolss_Field, 1);
2822 if (option.types[0].fields == NULL) {
2823 result = WERR_NOMEM;
2826 option.types[0].fields[0] = PRINTER_NOTIFY_SERVER_NAME;
2828 option.types[1].type = JOB_NOTIFY_TYPE;
2829 option.types[1].count = 1;
2830 option.types[1].fields = talloc_array(mem_ctx, enum spoolss_Field, 1);
2831 if (option.types[1].fields == NULL) {
2832 result = WERR_NOMEM;
2835 option.types[1].fields[0] = JOB_NOTIFY_PRINTER_NAME;
2837 clientname = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
2839 result = WERR_NOMEM;
2845 status = rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(cli, mem_ctx,
2853 if (!W_ERROR_IS_OK(result)) {
2854 printf("Error rffpcnex %s\n", argv[1]);
2859 if (is_valid_policy_hnd(&hnd))
2860 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL);
2865 /****************************************************************************
2866 ****************************************************************************/
2868 static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2869 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2871 union spoolss_PrinterInfo info1, info2;
2873 TALLOC_CTX *mem_ctx = talloc_init("compare_printer");
2875 printf("Retrieving printer propertiesfor %s...", cli1->desthost);
2876 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
2881 if ( !W_ERROR_IS_OK(werror) ) {
2882 printf("failed (%s)\n", win_errstr(werror));
2883 talloc_destroy(mem_ctx);
2888 printf("Retrieving printer properties for %s...", cli2->desthost);
2889 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
2894 if ( !W_ERROR_IS_OK(werror) ) {
2895 printf("failed (%s)\n", win_errstr(werror));
2896 talloc_destroy(mem_ctx);
2901 talloc_destroy(mem_ctx);
2906 /****************************************************************************
2907 ****************************************************************************/
2909 static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1,
2910 struct rpc_pipe_client *cli2, POLICY_HND *hnd2 )
2912 union spoolss_PrinterInfo info1, info2;
2914 TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc");
2915 SEC_DESC *sd1, *sd2;
2919 printf("Retrieving printer security for %s...", cli1->desthost);
2920 werror = rpccli_spoolss_getprinter(cli1, mem_ctx,
2925 if ( !W_ERROR_IS_OK(werror) ) {
2926 printf("failed (%s)\n", win_errstr(werror));
2932 printf("Retrieving printer security for %s...", cli2->desthost);
2933 werror = rpccli_spoolss_getprinter(cli2, mem_ctx,
2938 if ( !W_ERROR_IS_OK(werror) ) {
2939 printf("failed (%s)\n", win_errstr(werror));
2948 sd1 = info1.info3.secdesc;
2949 sd2 = info2.info3.secdesc;
2951 if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) {
2952 printf("NULL secdesc!\n");
2957 if (!sec_desc_equal( sd1, sd2 ) ) {
2958 printf("Security Descriptors *not* equal!\n");
2963 printf("Security descriptors match\n");
2966 talloc_destroy(mem_ctx);
2971 /****************************************************************************
2972 ****************************************************************************/
2974 extern struct user_auth_info *rpcclient_auth_info;
2976 static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
2977 TALLOC_CTX *mem_ctx, int argc,
2980 const char *printername;
2981 char *printername_path = NULL;
2982 struct cli_state *cli_server2 = NULL;
2983 struct rpc_pipe_client *cli2 = NULL;
2984 POLICY_HND hPrinter1, hPrinter2;
2989 printf("Usage: %s <printer> <server>\n", argv[0]);
2993 printername = argv[1];
2995 /* first get the connection to the remote server */
2997 nt_status = cli_full_connection(&cli_server2, global_myname(), argv[2],
3000 get_cmdline_auth_info_username(rpcclient_auth_info),
3002 get_cmdline_auth_info_password(rpcclient_auth_info),
3003 get_cmdline_auth_info_use_kerberos(rpcclient_auth_info) ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
3004 get_cmdline_auth_info_signing_state(rpcclient_auth_info), NULL);
3006 if ( !NT_STATUS_IS_OK(nt_status) )
3007 return WERR_GENERAL_FAILURE;
3009 nt_status = cli_rpc_pipe_open_noauth(cli_server2, &syntax_spoolss,
3011 if (!NT_STATUS_IS_OK(nt_status)) {
3012 printf("failed to open spoolss pipe on server %s (%s)\n",
3013 argv[2], nt_errstr(nt_status));
3014 return WERR_GENERAL_FAILURE;
3017 /* now open up both printers */
3019 RPCCLIENT_PRINTERNAME(printername_path, cli, printername);
3021 printf("Opening %s...", printername_path);
3023 werror = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
3027 if ( !W_ERROR_IS_OK(werror) ) {
3028 printf("failed (%s)\n", win_errstr(werror));
3033 RPCCLIENT_PRINTERNAME(printername_path, cli2, printername);
3035 printf("Opening %s...", printername_path);
3036 werror = rpccli_spoolss_openprinter_ex(cli2, mem_ctx,
3040 if ( !W_ERROR_IS_OK(werror) ) {
3041 printf("failed (%s)\n", win_errstr(werror));
3046 compare_printer( cli, &hPrinter1, cli2, &hPrinter2 );
3047 compare_printer_secdesc( cli, &hPrinter1, cli2, &hPrinter2 );
3049 compare_printerdata( cli_server1, &hPrinter1, cli_server2, &hPrinter2 );
3056 printf("Closing printers...");
3057 rpccli_spoolss_ClosePrinter( cli, mem_ctx, &hPrinter1, NULL );
3058 rpccli_spoolss_ClosePrinter( cli2, mem_ctx, &hPrinter2, NULL );
3061 /* close the second remote connection */
3063 cli_shutdown( cli_server2 );
3067 /* List of commands exported by this module */
3068 struct cmd_set spoolss_commands[] = {
3072 { "adddriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterdriver, &syntax_spoolss, NULL, "Add a print driver", "" },
3073 { "addprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addprinterex, &syntax_spoolss, NULL, "Add a printer", "" },
3074 { "deldriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriver, &syntax_spoolss, NULL, "Delete a printer driver", "" },
3075 { "deldriverex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deletedriverex, &syntax_spoolss, NULL, "Delete a printer driver with files", "" },
3076 { "enumdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data, &syntax_spoolss, NULL, "Enumerate printer data", "" },
3077 { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &syntax_spoolss, NULL, "Enumerate printer data for a key", "" },
3078 { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &syntax_spoolss, NULL, "Enumerate printer keys", "" },
3079 { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &syntax_spoolss, NULL, "Enumerate print jobs", "" },
3080 { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &syntax_spoolss, NULL, "Get print job", "" },
3081 { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &syntax_spoolss, NULL, "Enumerate printer ports", "" },
3082 { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" },
3083 { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &syntax_spoolss, NULL, "Enumerate printers", "" },
3084 { "getdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdata, &syntax_spoolss, NULL, "Get print driver data", "" },
3085 { "getdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinterdataex, &syntax_spoolss, NULL, "Get printer driver data with keyname", ""},
3086 { "getdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriver, &syntax_spoolss, NULL, "Get print driver information", "" },
3087 { "getdriverdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getdriverdir, &syntax_spoolss, NULL, "Get print driver upload directory", "" },
3088 { "getprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprinter, &syntax_spoolss, NULL, "Get printer info", "" },
3089 { "openprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_open_printer_ex, &syntax_spoolss, NULL, "Open printer handle", "" },
3090 { "setdriver", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setdriver, &syntax_spoolss, NULL, "Set printer driver", "" },
3091 { "getprintprocdir", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getprintprocdir, &syntax_spoolss, NULL, "Get print processor directory", "" },
3092 { "addform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_addform, &syntax_spoolss, NULL, "Add form", "" },
3093 { "setform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setform, &syntax_spoolss, NULL, "Set form", "" },
3094 { "getform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_getform, &syntax_spoolss, NULL, "Get form", "" },
3095 { "deleteform", RPC_RTYPE_WERROR, NULL, cmd_spoolss_deleteform, &syntax_spoolss, NULL, "Delete form", "" },
3096 { "enumforms", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_forms, &syntax_spoolss, NULL, "Enumerate forms", "" },
3097 { "setprinter", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinter, &syntax_spoolss, NULL, "Set printer comment", "" },
3098 { "setprintername", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprintername, &syntax_spoolss, NULL, "Set printername", "" },
3099 { "setprinterdata", RPC_RTYPE_WERROR, NULL, cmd_spoolss_setprinterdata, &syntax_spoolss, NULL, "Set REG_SZ printer data", "" },
3100 { "rffpcnex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_rffpcnex, &syntax_spoolss, NULL, "Rffpcnex test", "" },
3101 { "printercmp", RPC_RTYPE_WERROR, NULL, cmd_spoolss_printercmp, &syntax_spoolss, NULL, "Printer comparison test", "" },