2 Unix SMB/Netbios implementation.
6 Copyright (C) Gerald Carter 2001
7 Copyright (C) Tim Potter 2000
8 Copyright (C) Andrew Tridgell 1992-1999
9 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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 2 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, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 extern pstring server;
29 extern pstring global_myname;
30 extern pstring username, password;
31 extern pstring workgroup;
39 struct table_node archi_table[]= {
41 {"Windows 4.0", "WIN40", 0 },
42 {"Windows NT x86", "W32X86", 2 },
43 {"Windows NT R4000", "W32MIPS", 2 },
44 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
45 {"Windows NT PowerPC", "W32PPC", 2 },
49 /****************************************************************************
50 function to do the mapping between the long architecture name and
52 ****************************************************************************/
53 BOOL get_short_archi(char *short_archi, char *long_archi)
57 DEBUG(107,("Getting architecture dependant directory\n"));
60 } while ( (archi_table[i].long_archi!=NULL ) &&
61 StrCaseCmp(long_archi, archi_table[i].long_archi) );
63 if (archi_table[i].long_archi==NULL) {
64 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
68 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
70 DEBUGADD(108,("index: [%d]\n", i));
71 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
72 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
78 /**********************************************************************
79 * dummy function -- placeholder
81 static NTSTATUS cmd_spoolss_not_implemented (struct cli_state *cli,
82 int argc, char **argv)
84 printf ("(*) This command is not currently implemented.\n");
88 /****************************************************************************
89 display sec_ace structure
90 ****************************************************************************/
91 static void display_sec_ace(SEC_ACE *ace)
95 sid_to_string(sid_str, &ace->sid);
96 printf("\t\tSID: %s\n", sid_str);
98 printf("\t\ttype:[%d], flags:[0x%02x], mask:[0x%08x]\n",
99 ace->type, ace->flags, ace->info.mask);
102 /****************************************************************************
103 display sec_acl structure
104 ****************************************************************************/
105 static void display_sec_acl(SEC_ACL *acl)
107 if (acl->size != 0 && acl->num_aces != 0) {
110 printf("\t\tRevision:[%d]\n", acl->revision);
111 for (i = 0; i < acl->num_aces; i++) {
112 display_sec_ace(&acl->ace[i]);
117 /****************************************************************************
118 display sec_desc structure
119 ****************************************************************************/
120 static void display_sec_desc(SEC_DESC *sec)
124 printf("\tRevision:[%d]\n", sec->revision);
126 if (sec->off_owner_sid) {
127 sid_to_string(sid_str, sec->owner_sid);
128 printf("\tOwner SID: %s\n", sid_str);
131 if (sec->off_grp_sid) {
132 sid_to_string(sid_str, sec->grp_sid);
133 printf("\tGroup SID: %s\n", sid_str);
136 if (sec->off_sacl) display_sec_acl(sec->sacl);
137 if (sec->off_dacl) display_sec_acl(sec->dacl);
140 /***********************************************************************
141 * Get printer information
143 static NTSTATUS cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char **argv)
145 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
147 fstring servername, user;
152 printf("Usage: %s <printername>\n", argv[0]);
157 return NT_STATUS_UNSUCCESSFUL;
159 if (!(mem_ctx=talloc_init()))
161 DEBUG(0,("cmd_spoolss_open_printer_ex: talloc_init returned NULL!\n"));
162 return NT_STATUS_UNSUCCESSFUL;
166 slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
167 strupper (servername);
168 fstrcpy (user, cli->user_name);
169 fstrcpy (printername, argv[1]);
172 /* Initialise RPC connection */
173 if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
174 fprintf (stderr, "Could not initialize spoolss pipe!\n");
175 talloc_destroy(mem_ctx);
176 return NT_STATUS_UNSUCCESSFUL;
179 /* Open the printer handle */
180 result = cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "",
181 MAXIMUM_ALLOWED_ACCESS, servername, user, &hnd);
183 if (NT_STATUS_IS_OK(result)) {
184 printf ("Printer %s opened successfully\n", printername);
185 result = cli_spoolss_close_printer (cli, mem_ctx, &hnd);
186 if (!NT_STATUS_IS_OK(result)) {
187 printf ("Error closing printer handle! (%s)\n", get_nt_error_msg(result));
191 cli_nt_session_close(cli);
192 talloc_destroy(mem_ctx);
198 /****************************************************************************
199 printer info level 0 display function
200 ****************************************************************************/
201 static void display_print_info_0(PRINTER_INFO_0 *i1)
206 rpcstr_pull(name, i1->printername.buffer, sizeof(name), 0, STR_TERMINATE);
207 rpcstr_pull(servername, i1->servername.buffer, sizeof(servername), 0,STR_TERMINATE);
209 printf("\tprintername:[%s]\n", name);
210 printf("\tservername:[%s]\n", servername);
211 printf("\tcjobs:[0x%x]\n", i1->cjobs);
212 printf("\ttotal_jobs:[0x%x]\n", i1->total_jobs);
214 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i1->year, i1->month,
215 i1->day, i1->dayofweek);
216 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i1->hour, i1->minute,
217 i1->second, i1->milliseconds);
219 printf("\tglobal_counter:[0x%x]\n", i1->global_counter);
220 printf("\ttotal_pages:[0x%x]\n", i1->total_pages);
222 printf("\tmajorversion:[0x%x]\n", i1->major_version);
223 printf("\tbuildversion:[0x%x]\n", i1->build_version);
225 printf("\tunknown7:[0x%x]\n", i1->unknown7);
226 printf("\tunknown8:[0x%x]\n", i1->unknown8);
227 printf("\tunknown9:[0x%x]\n", i1->unknown9);
228 printf("\tsession_counter:[0x%x]\n", i1->session_counter);
229 printf("\tunknown11:[0x%x]\n", i1->unknown11);
230 printf("\tprinter_errors:[0x%x]\n", i1->printer_errors);
231 printf("\tunknown13:[0x%x]\n", i1->unknown13);
232 printf("\tunknown14:[0x%x]\n", i1->unknown14);
233 printf("\tunknown15:[0x%x]\n", i1->unknown15);
234 printf("\tunknown16:[0x%x]\n", i1->unknown16);
235 printf("\tchange_id:[0x%x]\n", i1->change_id);
236 printf("\tunknown18:[0x%x]\n", i1->unknown18);
237 printf("\tstatus:[0x%x]\n", i1->status);
238 printf("\tunknown20:[0x%x]\n", i1->unknown20);
239 printf("\tc_setprinter:[0x%x]\n", i1->c_setprinter);
240 printf("\tunknown22:[0x%x]\n", i1->unknown22);
241 printf("\tunknown23:[0x%x]\n", i1->unknown23);
242 printf("\tunknown24:[0x%x]\n", i1->unknown24);
243 printf("\tunknown25:[0x%x]\n", i1->unknown25);
244 printf("\tunknown26:[0x%x]\n", i1->unknown26);
245 printf("\tunknown27:[0x%x]\n", i1->unknown27);
246 printf("\tunknown28:[0x%x]\n", i1->unknown28);
247 printf("\tunknown29:[0x%x]\n", i1->unknown29);
250 /****************************************************************************
251 printer info level 1 display function
252 ****************************************************************************/
253 static void display_print_info_1(PRINTER_INFO_1 *i1)
259 rpcstr_pull(desc, i1->description.buffer, sizeof(desc), 0, STR_TERMINATE);
260 rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
261 rpcstr_pull(comm, i1->comment.buffer, sizeof(comm), 0, STR_TERMINATE);
263 printf("\tflags:[0x%x]\n", i1->flags);
264 printf("\tname:[%s]\n", name);
265 printf("\tdescription:[%s]\n", desc);
266 printf("\tcomment:[%s]\n\n", comm);
269 /****************************************************************************
270 printer info level 2 display function
271 ****************************************************************************/
272 static void display_print_info_2(PRINTER_INFO_2 *i2)
282 fstring printprocessor;
286 rpcstr_pull(servername, i2->servername.buffer,sizeof(servername), 0, STR_TERMINATE);
287 rpcstr_pull(printername, i2->printername.buffer,sizeof(printername), 0, STR_TERMINATE);
288 rpcstr_pull(sharename, i2->sharename.buffer,sizeof(sharename), 0, STR_TERMINATE);
289 rpcstr_pull(portname, i2->portname.buffer,sizeof(portname), 0, STR_TERMINATE);
290 rpcstr_pull(drivername, i2->drivername.buffer,sizeof(drivername), 0, STR_TERMINATE);
291 rpcstr_pull(comment, i2->comment.buffer,sizeof(comment), 0, STR_TERMINATE);
292 rpcstr_pull(location, i2->location.buffer,sizeof(location), 0, STR_TERMINATE);
293 rpcstr_pull(sepfile, i2->sepfile.buffer,sizeof(sepfile), 0, STR_TERMINATE);
294 rpcstr_pull(printprocessor, i2->printprocessor.buffer,sizeof(printprocessor), 0, STR_TERMINATE);
295 rpcstr_pull(datatype, i2->datatype.buffer,sizeof(datatype), 0, STR_TERMINATE);
296 rpcstr_pull(parameters, i2->parameters.buffer,sizeof(parameters), 0, STR_TERMINATE);
298 printf("\tservername:[%s]\n", servername);
299 printf("\tprintername:[%s]\n", printername);
300 printf("\tsharename:[%s]\n", sharename);
301 printf("\tportname:[%s]\n", portname);
302 printf("\tdrivername:[%s]\n", drivername);
303 printf("\tcomment:[%s]\n", comment);
304 printf("\tlocation:[%s]\n", location);
305 printf("\tsepfile:[%s]\n", sepfile);
306 printf("\tprintprocessor:[%s]\n", printprocessor);
307 printf("\tdatatype:[%s]\n", datatype);
308 printf("\tparameters:[%s]\n", parameters);
309 printf("\tattributes:[0x%x]\n", i2->attributes);
310 printf("\tpriority:[0x%x]\n", i2->priority);
311 printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
312 printf("\tstarttime:[0x%x]\n", i2->starttime);
313 printf("\tuntiltime:[0x%x]\n", i2->untiltime);
314 printf("\tstatus:[0x%x]\n", i2->status);
315 printf("\tcjobs:[0x%x]\n", i2->cjobs);
316 printf("\taverageppm:[0x%x]\n", i2->averageppm);
318 if (i2->secdesc) display_sec_desc(i2->secdesc);
321 /****************************************************************************
322 printer info level 3 display function
323 ****************************************************************************/
324 static void display_print_info_3(PRINTER_INFO_3 *i3)
326 printf("\tflags:[0x%x]\n", i3->flags);
328 display_sec_desc(i3->secdesc);
331 /* Enumerate printers */
333 static NTSTATUS cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char **argv)
335 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
336 uint32 info_level = 1;
337 PRINTER_INFO_CTR ctr;
344 printf("Usage: %s [level]\n", argv[0]);
348 if (!(mem_ctx=talloc_init()))
350 DEBUG(0,("cmd_spoolss_enum_printers: talloc_init returned NULL!\n"));
351 return NT_STATUS_UNSUCCESSFUL;
356 info_level = atoi(argv[1]);
359 /* Initialise RPC connection */
360 if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
361 fprintf (stderr, "Could not initialize spoolss pipe!\n");
362 talloc_destroy(mem_ctx);
363 return NT_STATUS_UNSUCCESSFUL;
366 /* Enumerate printers -- Should we enumerate types other
367 than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
369 result = cli_spoolss_enum_printers(cli, mem_ctx, PRINTER_ENUM_LOCAL,
370 info_level, &returned, &ctr);
372 if (NT_STATUS_IS_OK(result))
375 printf ("No Printers printers returned.\n");
379 for (i=0; i<returned; i++) {
380 display_print_info_0(&(ctr.printers_0[i]));
384 for (i=0; i<returned; i++) {
385 display_print_info_1(&(ctr.printers_1[i]));
389 for (i=0; i<returned; i++) {
390 display_print_info_2(&(ctr.printers_2[i]));
394 for (i=0; i<returned; i++) {
395 display_print_info_3(&(ctr.printers_3[i]));
399 printf("unknown info level %d\n", info_level);
404 cli_nt_session_close(cli);
405 talloc_destroy(mem_ctx);
410 /****************************************************************************
411 port info level 1 display function
412 ****************************************************************************/
413 static void display_port_info_1(PORT_INFO_1 *i1)
417 rpcstr_pull(buffer, i1->port_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
418 printf("\tPort Name:\t[%s]\n", buffer);
421 /****************************************************************************
422 port info level 2 display function
423 ****************************************************************************/
424 static void display_port_info_2(PORT_INFO_2 *i2)
428 rpcstr_pull(buffer, i2->port_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
429 printf("\tPort Name:\t[%s]\n", buffer);
430 rpcstr_pull(buffer, i2->monitor_name.buffer, sizeof(buffer), 0, STR_TERMINATE);
432 printf("\tMonitor Name:\t[%s]\n", buffer);
433 rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), 0, STR_TERMINATE);
435 printf("\tDescription:\t[%s]\n", buffer);
436 printf("\tPort Type:\t[%d]\n", i2->port_type);
437 printf("\tReserved:\t[%d]\n", i2->reserved);
441 /* Enumerate ports */
443 static NTSTATUS cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **argv)
445 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
446 uint32 info_level = 1;
452 printf("Usage: %s [level]\n", argv[0]);
456 if (!(mem_ctx=talloc_init()))
458 DEBUG(0,("cmd_spoolss_enum_ports: talloc_init returned NULL!\n"));
459 return NT_STATUS_UNSUCCESSFUL;
464 info_level = atoi(argv[1]);
467 /* Initialise RPC connection */
468 if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
469 fprintf (stderr, "Could not initialize spoolss pipe!\n");
470 talloc_destroy(mem_ctx);
471 return NT_STATUS_UNSUCCESSFUL;
474 /* Enumerate ports */
477 result = cli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
479 if (NT_STATUS_IS_OK(result)) {
482 for (i = 0; i < returned; i++) {
483 switch (info_level) {
485 display_port_info_1(&ctr.port.info_1[i]);
488 display_port_info_2(&ctr.port.info_2[i]);
491 printf("unknown info level %d\n", info_level);
497 cli_nt_session_close(cli);
498 talloc_destroy(mem_ctx);
503 /***********************************************************************
504 * Get printer information
506 static NTSTATUS cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **argv)
510 uint32 info_level = 1;
511 BOOL opened_hnd = False;
512 PRINTER_INFO_CTR ctr;
518 if (argc == 1 || argc > 3) {
519 printf("Usage: %s <printername> [level]\n", argv[0]);
523 if (!(mem_ctx=talloc_init()))
525 DEBUG(0,("cmd_spoolss_getprinter: talloc_init returned NULL!\n"));
526 return NT_STATUS_UNSUCCESSFUL;
530 /* Initialise RPC connection */
531 if (!cli_nt_session_open (cli, PIPE_SPOOLSS)) {
532 fprintf (stderr, "Could not initialize spoolss pipe!\n");
533 talloc_destroy(mem_ctx);
534 return NT_STATUS_UNSUCCESSFUL;
537 /* Open a printer handle */
539 info_level = atoi(argv[2]);
542 slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
543 strupper (servername);
544 slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
545 fstrcpy (user, cli->user_name);
547 /* get a printer handle */
548 result = cli_spoolss_open_printer_ex(
549 cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, servername,
551 if (!NT_STATUS_IS_OK(result)) {
557 /* Get printer info */
558 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr);
559 if (!NT_STATUS_IS_OK(result)) {
563 /* Display printer info */
565 switch (info_level) {
567 display_print_info_0(ctr.printers_0);
570 display_print_info_1(ctr.printers_1);
573 display_print_info_2(ctr.printers_2);
576 display_print_info_3(ctr.printers_3);
579 printf("unknown info level %d\n", info_level);
585 cli_spoolss_close_printer(cli, mem_ctx, &pol);
587 cli_nt_session_close(cli);
588 talloc_destroy(mem_ctx);
593 /****************************************************************************
594 printer info level 0 display function
595 ****************************************************************************/
596 static void display_print_driver_1(DRIVER_INFO_1 *i1)
602 rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
604 printf ("Printer Driver Info 1:\n");
605 printf ("\tDriver Name: [%s]\n\n", name);
610 /****************************************************************************
611 printer info level 1 display function
612 ****************************************************************************/
613 static void display_print_driver_2(DRIVER_INFO_2 *i1)
616 fstring architecture;
623 rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
624 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
625 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
626 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
627 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
629 printf ("Printer Driver Info 2:\n");
630 printf ("\tVersion: [%x]\n", i1->version);
631 printf ("\tDriver Name: [%s]\n", name);
632 printf ("\tArchitecture: [%s]\n", architecture);
633 printf ("\tDriver Path: [%s]\n", driverpath);
634 printf ("\tDatafile: [%s]\n", datafile);
635 printf ("\tConfigfile: [%s]\n\n", configfile);
640 /****************************************************************************
641 printer info level 2 display function
642 ****************************************************************************/
643 static void display_print_driver_3(DRIVER_INFO_3 *i1)
646 fstring architecture;
651 fstring dependentfiles;
653 fstring defaultdatatype;
661 rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
662 rpcstr_pull(architecture, i1->architecture.buffer, sizeof(architecture), 0, STR_TERMINATE);
663 rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), 0, STR_TERMINATE);
664 rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), 0, STR_TERMINATE);
665 rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), 0, STR_TERMINATE);
666 rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), 0, STR_TERMINATE);
667 rpcstr_pull(monitorname, i1->monitorname.buffer, sizeof(monitorname), 0, STR_TERMINATE);
668 rpcstr_pull(defaultdatatype, i1->defaultdatatype.buffer, sizeof(defaultdatatype), 0, STR_TERMINATE);
670 printf ("Printer Driver Info 3:\n");
671 printf ("\tVersion: [%x]\n", i1->version);
672 printf ("\tDriver Name: [%s]\n",name);
673 printf ("\tArchitecture: [%s]\n", architecture);
674 printf ("\tDriver Path: [%s]\n", driverpath);
675 printf ("\tDatafile: [%s]\n", datafile);
676 printf ("\tConfigfile: [%s]\n", configfile);
677 printf ("\tHelpfile: [%s]\n\n", helpfile);
681 rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), 0, STR_TERMINATE);
683 length+=strlen(dependentfiles)+1;
685 if (strlen(dependentfiles) > 0)
687 printf ("\tDependentfiles: [%s]\n", dependentfiles);
697 printf ("\tMonitorname: [%s]\n", monitorname);
698 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype);
703 /***********************************************************************
704 * Get printer information
706 static NTSTATUS cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv)
710 uint32 info_level = 3;
711 BOOL opened_hnd = False;
712 PRINTER_DRIVER_CTR ctr;
719 if ((argc == 1) || (argc > 3))
721 printf("Usage: %s <printername> [level]\n", argv[0]);
725 if (!(mem_ctx=talloc_init()))
727 DEBUG(0,("cmd_spoolss_getdriver: talloc_init returned NULL!\n"));
728 return NT_STATUS_UNSUCCESSFUL;
731 /* Initialise RPC connection */
732 if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
734 fprintf (stderr, "Could not initialize spoolss pipe!\n");
735 talloc_destroy(mem_ctx);
736 return NT_STATUS_UNSUCCESSFUL;
739 /* get the arguments need to open the printer handle */
740 slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
741 strupper (servername);
742 fstrcpy (user, cli->user_name);
743 fstrcpy (printername, argv[1]);
745 info_level = atoi(argv[2]);
747 /* Open a printer handle */
748 result=cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "",
749 MAXIMUM_ALLOWED_ACCESS, servername, user, &pol);
750 if (!NT_STATUS_IS_OK(result)) {
751 printf ("Error opening printer handle for %s!\n", printername);
757 /* loop through and print driver info level for each architecture */
758 for (i=0; archi_table[i].long_archi!=NULL; i++)
760 result = cli_spoolss_getprinterdriver(cli, mem_ctx, &pol, info_level,
761 archi_table[i].long_archi, &ctr);
762 if (!NT_STATUS_IS_OK(result)) {
767 printf ("\n[%s]\n", archi_table[i].long_archi);
772 display_print_driver_1 (ctr.info1);
775 display_print_driver_2 (ctr.info2);
778 display_print_driver_3 (ctr.info3);
781 printf("unknown info level %d\n", info_level);
789 cli_spoolss_close_printer (cli, mem_ctx, &pol);
790 cli_nt_session_close (cli);
791 talloc_destroy(mem_ctx);
797 /***********************************************************************
798 * Get printer information
800 static NTSTATUS cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **argv)
802 NTSTATUS result = NT_STATUS_OK;
803 uint32 info_level = 1;
804 PRINTER_DRIVER_CTR ctr;
812 printf("Usage: enumdrivers [level]\n");
816 if (!(mem_ctx=talloc_init()))
818 DEBUG(0,("cmd_spoolss_enum_drivers: talloc_init returned NULL!\n"));
819 return NT_STATUS_NO_MEMORY;
822 /* Initialise RPC connection */
823 if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
825 fprintf (stderr, "Could not initialize spoolss pipe!\n");
826 talloc_destroy(mem_ctx);
827 return NT_STATUS_UNSUCCESSFUL;
830 /* get the arguments need to open the printer handle */
831 slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
832 strupper (servername);
834 info_level = atoi(argv[1]);
837 /* loop through and print driver info level for each architecture */
838 for (i=0; archi_table[i].long_archi!=NULL; i++)
841 result = cli_spoolss_enumprinterdrivers (cli, mem_ctx, info_level,
842 archi_table[i].long_archi, &returned, &ctr);
848 if (!NT_STATUS_IS_OK(result))
850 printf ("Error getting driver for environment [%s] - %s\n",
851 archi_table[i].long_archi, get_nt_error_msg(result));
855 printf ("\n[%s]\n", archi_table[i].long_archi);
860 for (j=0; j < returned; j++) {
861 display_print_driver_1 (&(ctr.info1[j]));
865 for (j=0; j < returned; j++) {
866 display_print_driver_2 (&(ctr.info2[j]));
870 for (j=0; j < returned; j++) {
871 display_print_driver_3 (&(ctr.info3[j]));
875 printf("unknown info level %d\n", info_level);
882 cli_nt_session_close (cli);
883 talloc_destroy(mem_ctx);
888 /****************************************************************************
889 printer info level 1 display function
890 ****************************************************************************/
891 static void display_printdriverdir_1(DRIVER_DIRECTORY_1 *i1)
897 rpcstr_pull(name, i1->name.buffer, sizeof(name), 0, STR_TERMINATE);
899 printf ("\tDirectory Name:[%s]\n", name);
902 /***********************************************************************
903 * Get printer driver directory information
905 static NTSTATUS cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **argv)
909 DRIVER_DIRECTORY_CTR ctr;
914 printf("Usage: %s [environment]\n", argv[0]);
918 /* Initialise RPC connection */
919 if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
921 fprintf (stderr, "Could not initialize spoolss pipe!\n");
922 return NT_STATUS_UNSUCCESSFUL;
925 if (!(mem_ctx=talloc_init()))
927 DEBUG(0,("cmd_spoolss_getdriverdir: talloc_init returned NULL!\n"));
928 return NT_STATUS_UNSUCCESSFUL;
932 /* get the arguments need to open the printer handle */
934 fstrcpy (env, argv[1]);
936 fstrcpy (env, "Windows NT x86");
938 /* Get the directory. Only use Info level 1 */
939 result = cli_spoolss_getprinterdriverdir (cli, mem_ctx, 1, env, &ctr);
940 if (!NT_STATUS_IS_OK(result)) {
945 display_printdriverdir_1 (ctr.info1);
948 cli_nt_session_close (cli);
949 talloc_destroy(mem_ctx);
955 /*******************************************************************************
956 set the version and environment fields of a DRIVER_INFO_3 struct
957 ******************************************************************************/
958 void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch)
963 for (i=0; archi_table[i].long_archi != NULL; i++)
965 if (strcmp(arch, archi_table[i].short_archi) == 0)
967 info->version = archi_table[i].version;
968 init_unistr (&info->architecture, archi_table[i].long_archi);
973 if (archi_table[i].long_archi == NULL)
975 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch));
982 /**************************************************************************
983 wrapper for strtok to get the next parameter from a delimited list.
984 Needed to handle the empty parameter string denoted by "NULL"
985 *************************************************************************/
986 static char* get_driver_3_param (char* str, char* delim, UNISTR* dest)
990 /* get the next token */
991 ptr = strtok(str, delim);
993 /* a string of 'NULL' is used to represent an empty
994 parameter because two consecutive delimiters
995 will not return an empty string. See man strtok(3)
997 if (StrCaseCmp(ptr, "NULL") == 0)
1001 init_unistr(dest, ptr);
1006 /********************************************************************************
1007 fill in the members of a DRIVER_INFO_3 struct using a character
1008 string in the form of
1009 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1010 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1011 <Default Data Type>:<Comma Separated list of Files>
1012 *******************************************************************************/
1013 static BOOL init_drv_info_3_members (
1014 TALLOC_CTX *mem_ctx,
1015 DRIVER_INFO_3 *info,
1022 /* fill in the UNISTR fields */
1023 str = get_driver_3_param (args, ":", &info->name);
1024 str = get_driver_3_param (NULL, ":", &info->driverpath);
1025 str = get_driver_3_param (NULL, ":", &info->datafile);
1026 str = get_driver_3_param (NULL, ":", &info->configfile);
1027 str = get_driver_3_param (NULL, ":", &info->helpfile);
1028 str = get_driver_3_param (NULL, ":", &info->monitorname);
1029 str = get_driver_3_param (NULL, ":", &info->defaultdatatype);
1031 /* <Comma Separated List of Dependent Files> */
1032 str2 = get_driver_3_param (NULL, ":", NULL); /* save the beginning of the string */
1035 /* begin to strip out each filename */
1036 str = strtok(str, ",");
1040 /* keep a cumlative count of the str lengths */
1041 len += strlen(str)+1;
1042 str = strtok(NULL, ",");
1045 /* allocate the space; add one extra slot for a terminating NULL.
1046 Each filename is NULL terminated and the end contains a double
1048 if ((info->dependentfiles=(uint16*)talloc(mem_ctx, (len+1)*sizeof(uint16))) == NULL)
1050 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1053 for (i=0; i<len; i++)
1055 info->dependentfiles[i] = (uint16)str2[i];
1057 info->dependentfiles[len] = '\0';
1063 static NTSTATUS cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, char **argv)
1067 PRINTER_DRIVER_CTR ctr;
1068 DRIVER_INFO_3 info3;
1070 fstring driver_name;
1071 TALLOC_CTX *mem_ctx = NULL;
1073 /* parse the command arguements */
1076 printf ("Usage: %s <Environment>\\\n", argv[0]);
1077 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1078 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1079 printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
1081 return NT_STATUS_OK;
1084 if (!(mem_ctx=talloc_init()))
1086 DEBUG(0,("cmd_spoolss_addprinterdriver: talloc_init returned NULL!\n"));
1087 return NT_STATUS_NO_MEMORY;
1090 /* Initialise RPC connection */
1091 if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
1093 fprintf (stderr, "Could not initialize spoolss pipe!\n");
1094 talloc_destroy(mem_ctx);
1095 return NT_STATUS_UNSUCCESSFUL;
1099 /* Fill in the DRIVER_INFO_3 struct */
1101 if (!get_short_archi(arch, argv[1]))
1103 printf ("Error Unknown architechture [%s]\n", argv[1]);
1104 return NT_STATUS_INVALID_PARAMETER;
1107 set_drv_info_3_env(&info3, arch);
1109 if (!init_drv_info_3_members(mem_ctx, &info3, argv[2]))
1111 printf ("Error Invalid parameter list - %s.\n", argv[2]);
1112 return NT_STATUS_INVALID_PARAMETER;
1117 result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr);
1118 if (!NT_STATUS_IS_OK(result)) {
1122 rpcstr_pull(driver_name, info3.name.buffer, sizeof(driver_name), 0, STR_TERMINATE);
1123 printf ("Printer Driver %s successfully installed.\n", driver_name);
1126 cli_nt_session_close (cli);
1127 talloc_destroy(mem_ctx);
1134 static NTSTATUS cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char **argv)
1138 PRINTER_INFO_CTR ctr;
1139 PRINTER_INFO_2 info2;
1141 TALLOC_CTX *mem_ctx = NULL;
1143 /* parse the command arguements */
1146 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
1147 return NT_STATUS_OK;
1150 if (!(mem_ctx=talloc_init()))
1152 DEBUG(0,("cmd_spoolss_addprinterex: talloc_init returned NULL!\n"));
1153 return NT_STATUS_NO_MEMORY;
1157 slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1158 strupper (servername);
1160 /* Initialise RPC connection */
1161 if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
1163 fprintf (stderr, "Could not initialize spoolss pipe!\n");
1164 talloc_destroy(mem_ctx);
1165 return NT_STATUS_UNSUCCESSFUL;
1169 /* Fill in the DRIVER_INFO_3 struct */
1172 init_unistr( &info2.servername, servername);
1174 init_unistr( &info2.printername, argv[1]);
1175 init_unistr( &info2.sharename, argv[2]);
1176 init_unistr( &info2.drivername, argv[3]);
1177 init_unistr( &info2.portname, argv[4]);
1178 init_unistr( &info2.comment, "Created by rpcclient");
1179 init_unistr( &info2.printprocessor, "winprint");
1180 init_unistr( &info2.datatype, "RAW");
1181 info2.devmode = NULL;
1182 info2.secdesc = NULL;
1183 info2.attributes = PRINTER_ATTRIBUTE_SHARED;
1185 info2.defaultpriority = 0;
1186 info2.starttime = 0;
1187 info2.untiltime = 0;
1189 /* These three fields must not be used by AddPrinter()
1190 as defined in the MS Platform SDK documentation..
1194 info2.averageppm = 0;
1197 ctr.printers_2 = &info2;
1198 result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr);
1199 if (!NT_STATUS_IS_OK(result)) {
1200 cli_nt_session_close (cli);
1204 printf ("Printer %s successfully installed.\n", argv[1]);
1207 cli_nt_session_close (cli);
1208 talloc_destroy(mem_ctx);
1214 static NTSTATUS cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **argv)
1219 BOOL opened_hnd = False;
1220 PRINTER_INFO_CTR ctr;
1221 PRINTER_INFO_2 info2;
1225 TALLOC_CTX *mem_ctx = NULL;
1227 /* parse the command arguements */
1230 printf ("Usage: %s <printer> <driver>\n", argv[0]);
1231 return NT_STATUS_OK;
1234 if (!(mem_ctx=talloc_init()))
1236 DEBUG(0,("cmd_spoolss_setdriver: talloc_init returned NULL!\n"));
1237 return NT_STATUS_NO_MEMORY;
1240 slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1241 strupper (servername);
1242 slprintf (printername, sizeof(fstring)-1, "%s\\%s", servername, argv[1]);
1243 fstrcpy (user, cli->user_name);
1245 /* Initialise RPC connection */
1246 if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
1248 fprintf (stderr, "Could not initialize spoolss pipe!\n");
1249 talloc_destroy(mem_ctx);
1250 return NT_STATUS_UNSUCCESSFUL;
1254 /* get a printer handle */
1255 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
1256 MAXIMUM_ALLOWED_ACCESS, servername, user, &pol);
1257 if (!NT_STATUS_IS_OK(result)) {
1263 /* Get printer info */
1264 ZERO_STRUCT (info2);
1265 ctr.printers_2 = &info2;
1266 result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr);
1267 if (!NT_STATUS_IS_OK(result)) {
1268 printf ("Unable to retrieve printer information!\n");
1272 /* set the printer driver */
1273 init_unistr(&ctr.printers_2->drivername, argv[2]);
1274 result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0);
1275 if (!NT_STATUS_IS_OK(result)) {
1276 printf ("SetPrinter call failed!\n");
1279 printf ("Succesfully set %s to driver %s.\n", argv[1], argv[2]);
1285 cli_spoolss_close_printer(cli, mem_ctx, &pol);
1286 cli_nt_session_close (cli);
1287 talloc_destroy(mem_ctx);
1293 static NTSTATUS cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **argv)
1295 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1297 TALLOC_CTX *mem_ctx = NULL;
1300 /* parse the command arguements */
1303 printf ("Usage: %s <driver>\n", argv[0]);
1304 return NT_STATUS_OK;
1307 if (!(mem_ctx=talloc_init()))
1309 DEBUG(0,("cmd_spoolss_deletedriver: talloc_init returned NULL!\n"));
1310 return NT_STATUS_UNSUCCESSFUL;
1313 slprintf (servername, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1314 strupper (servername);
1316 /* Initialise RPC connection */
1317 if (!cli_nt_session_open (cli, PIPE_SPOOLSS))
1319 fprintf (stderr, "Could not initialize spoolss pipe!\n");
1320 talloc_destroy(mem_ctx);
1321 return NT_STATUS_UNSUCCESSFUL;
1324 /* delete the driver for all architectures */
1325 for (i=0; archi_table[i].long_archi; i++)
1327 /* make the call to remove the driver */
1328 result = cli_spoolss_deleteprinterdriver(cli, mem_ctx,
1329 archi_table[i].long_archi, argv[1]);
1330 if (!NT_STATUS_IS_OK(result)) {
1331 printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
1332 argv[1], archi_table[i].long_archi, get_nt_error_msg(result));
1335 printf ("Driver %s removed for arch [%s].\n", argv[1], archi_table[i].long_archi);
1340 cli_nt_session_close (cli);
1341 talloc_destroy(mem_ctx);
1343 return NT_STATUS_OK;
1347 /* List of commands exported by this module */
1348 struct cmd_set spoolss_commands[] = {
1352 { "adddriver", cmd_spoolss_addprinterdriver, "Add a print driver", "" },
1353 { "addprinter", cmd_spoolss_addprinterex, "Add a printer", "" },
1354 { "deldriver", cmd_spoolss_deletedriver, "Delete a printer driver", "" },
1355 { "enumdata", cmd_spoolss_not_implemented, "Enumerate printer data (*)", "" },
1356 { "enumjobs", cmd_spoolss_not_implemented, "Enumerate print jobs (*)", "" },
1357 { "enumports", cmd_spoolss_enum_ports, "Enumerate printer ports", "" },
1358 { "enumdrivers", cmd_spoolss_enum_drivers, "Enumerate installed printer drivers", "" },
1359 { "enumprinters", cmd_spoolss_enum_printers, "Enumerate printers", "" },
1360 { "getdata", cmd_spoolss_not_implemented, "Get print driver data (*)", "" },
1361 { "getdriver", cmd_spoolss_getdriver, "Get print driver information", "" },
1362 { "getdriverdir", cmd_spoolss_getdriverdir, "Get print driver upload directory", "" },
1363 { "getprinter", cmd_spoolss_getprinter, "Get printer info", "" },
1364 { "openprinter", cmd_spoolss_open_printer_ex, "Open printer handle", "" },
1365 { "setdriver", cmd_spoolss_setdriver, "Set printer driver", "" },