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 int DEBUGLEVEL
;
30 extern pstring server
;
31 extern pstring global_myname
;
32 extern pstring username
, password
;
33 extern pstring workgroup
;
41 struct table_node archi_table
[]= {
43 {"Windows 4.0", "WIN40", 0 },
44 {"Windows NT x86", "W32X86", 2 },
45 {"Windows NT R4000", "W32MIPS", 2 },
46 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
47 {"Windows NT PowerPC", "W32PPC", 2 },
51 /****************************************************************************
52 function to do the mapping between the long architecture name and
54 ****************************************************************************/
55 BOOL
get_short_archi(char *short_archi
, char *long_archi
)
59 DEBUG(107,("Getting architecture dependant directory\n"));
62 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
63 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
65 if (archi_table
[i
].long_archi
==NULL
) {
66 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi
));
70 StrnCpy (short_archi
, archi_table
[i
].short_archi
, strlen(archi_table
[i
].short_archi
));
72 DEBUGADD(108,("index: [%d]\n", i
));
73 DEBUGADD(108,("long architecture: [%s]\n", long_archi
));
74 DEBUGADD(108,("short architecture: [%s]\n", short_archi
));
80 /**********************************************************************
81 * dummy function -- placeholder
83 static uint32
cmd_spoolss_not_implemented (struct cli_state
*cli
,
84 int argc
, char **argv
)
86 printf ("(*) This command is not currently implemented.\n");
87 return NT_STATUS_NO_PROBLEMO
;
90 /****************************************************************************
91 display sec_ace structure
92 ****************************************************************************/
93 static void display_sec_ace(SEC_ACE
*ace
)
97 sid_to_string(sid_str
, &ace
->sid
);
98 printf("\t\tSID: %s\n", sid_str
);
100 printf("\t\ttype:[%d], flags:[0x%02x], mask:[0x%08x]\n",
101 ace
->type
, ace
->flags
, ace
->info
.mask
);
104 /****************************************************************************
105 display sec_acl structure
106 ****************************************************************************/
107 static void display_sec_acl(SEC_ACL
*acl
)
109 if (acl
->size
!= 0 && acl
->num_aces
!= 0) {
112 printf("\t\tRevision:[%d]\n", acl
->revision
);
113 for (i
= 0; i
< acl
->num_aces
; i
++) {
114 display_sec_ace(&acl
->ace
[i
]);
119 /****************************************************************************
120 display sec_desc structure
121 ****************************************************************************/
122 static void display_sec_desc(SEC_DESC
*sec
)
126 printf("\tRevision:[%d]\n", sec
->revision
);
128 if (sec
->off_owner_sid
) {
129 sid_to_string(sid_str
, sec
->owner_sid
);
130 printf("\tOwner SID: %s\n", sid_str
);
133 if (sec
->off_grp_sid
) {
134 sid_to_string(sid_str
, sec
->grp_sid
);
135 printf("\tGroup SID: %s\n", sid_str
);
138 if (sec
->off_sacl
) display_sec_acl(sec
->sacl
);
139 if (sec
->off_dacl
) display_sec_acl(sec
->dacl
);
142 /***********************************************************************
143 * Get printer information
145 static uint32
cmd_spoolss_open_printer_ex(struct cli_state
*cli
, int argc
, char **argv
)
147 uint32 result
= NT_STATUS_UNSUCCESSFUL
;
149 fstring servername
, user
;
154 printf("Usage: %s <printername>\n", argv
[0]);
155 return NT_STATUS_NOPROBLEMO
;
159 return NT_STATUS_UNSUCCESSFUL
;
161 if (!(mem_ctx
=talloc_init()))
163 DEBUG(0,("cmd_spoolss_open_printer_ex: talloc_init returned NULL!\n"));
164 return NT_STATUS_UNSUCCESSFUL
;
168 slprintf (servername
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
169 strupper (servername
);
170 fstrcpy (user
, cli
->user_name
);
171 fstrcpy (printername
, argv
[1]);
174 /* Initialise RPC connection */
175 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
)) {
176 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
177 return NT_STATUS_UNSUCCESSFUL
;
180 /* Open the printer handle */
181 result
= cli_spoolss_open_printer_ex (cli
, mem_ctx
, printername
, "",
182 MAXIMUM_ALLOWED_ACCESS
, servername
, user
, &hnd
);
184 if (result
== NT_STATUS_NOPROBLEMO
) {
185 printf ("Printer %s opened successfully\n", printername
);
186 result
= cli_spoolss_close_printer (cli
, mem_ctx
, &hnd
);
187 if (result
!= NT_STATUS_NOPROBLEMO
) {
188 printf ("Error closing printer handle! (%s)\n", get_nt_error_msg(result
));
192 cli_nt_session_close(cli
);
193 talloc_destroy(mem_ctx
);
199 /****************************************************************************
200 printer info level 0 display function
201 ****************************************************************************/
202 static void display_print_info_0(PRINTER_INFO_0
*i1
)
207 unistr_to_ascii(name
, i1
->printername
.buffer
, sizeof(name
) - 1);
208 unistr_to_ascii(servername
, i1
->servername
.buffer
, sizeof(servername
) - 1);
210 printf("\tprintername:[%s]\n", name
);
211 printf("\tservername:[%s]\n", servername
);
212 printf("\tcjobs:[0x%x]\n", i1
->cjobs
);
213 printf("\ttotal_jobs:[0x%x]\n", i1
->total_jobs
);
215 printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i1
->year
, i1
->month
,
216 i1
->day
, i1
->dayofweek
);
217 printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i1
->hour
, i1
->minute
,
218 i1
->second
, i1
->milliseconds
);
220 printf("\tglobal_counter:[0x%x]\n", i1
->global_counter
);
221 printf("\ttotal_pages:[0x%x]\n", i1
->total_pages
);
223 printf("\tmajorversion:[0x%x]\n", i1
->major_version
);
224 printf("\tbuildversion:[0x%x]\n", i1
->build_version
);
226 printf("\tunknown7:[0x%x]\n", i1
->unknown7
);
227 printf("\tunknown8:[0x%x]\n", i1
->unknown8
);
228 printf("\tunknown9:[0x%x]\n", i1
->unknown9
);
229 printf("\tsession_counter:[0x%x]\n", i1
->session_counter
);
230 printf("\tunknown11:[0x%x]\n", i1
->unknown11
);
231 printf("\tprinter_errors:[0x%x]\n", i1
->printer_errors
);
232 printf("\tunknown13:[0x%x]\n", i1
->unknown13
);
233 printf("\tunknown14:[0x%x]\n", i1
->unknown14
);
234 printf("\tunknown15:[0x%x]\n", i1
->unknown15
);
235 printf("\tunknown16:[0x%x]\n", i1
->unknown16
);
236 printf("\tchange_id:[0x%x]\n", i1
->change_id
);
237 printf("\tunknown18:[0x%x]\n", i1
->unknown18
);
238 printf("\tstatus:[0x%x]\n", i1
->status
);
239 printf("\tunknown20:[0x%x]\n", i1
->unknown20
);
240 printf("\tc_setprinter:[0x%x]\n", i1
->c_setprinter
);
241 printf("\tunknown22:[0x%x]\n", i1
->unknown22
);
242 printf("\tunknown23:[0x%x]\n", i1
->unknown23
);
243 printf("\tunknown24:[0x%x]\n", i1
->unknown24
);
244 printf("\tunknown25:[0x%x]\n", i1
->unknown25
);
245 printf("\tunknown26:[0x%x]\n", i1
->unknown26
);
246 printf("\tunknown27:[0x%x]\n", i1
->unknown27
);
247 printf("\tunknown28:[0x%x]\n", i1
->unknown28
);
248 printf("\tunknown29:[0x%x]\n", i1
->unknown29
);
251 /****************************************************************************
252 printer info level 1 display function
253 ****************************************************************************/
254 static void display_print_info_1(PRINTER_INFO_1
*i1
)
260 unistr_to_ascii(desc
, i1
->description
.buffer
, sizeof(desc
) - 1);
261 unistr_to_ascii(name
, i1
->name
.buffer
, sizeof(name
) - 1);
262 unistr_to_ascii(comm
, i1
->comment
.buffer
, sizeof(comm
) - 1);
264 printf("\tflags:[0x%x]\n", i1
->flags
);
265 printf("\tname:[%s]\n", name
);
266 printf("\tdescription:[%s]\n", desc
);
267 printf("\tcomment:[%s]\n\n", comm
);
270 /****************************************************************************
271 printer info level 2 display function
272 ****************************************************************************/
273 static void display_print_info_2(PRINTER_INFO_2
*i2
)
283 fstring printprocessor
;
287 unistr_to_ascii(servername
, i2
->servername
.buffer
,
288 sizeof(servername
) - 1);
289 unistr_to_ascii(printername
, i2
->printername
.buffer
,
290 sizeof(printername
) - 1);
291 unistr_to_ascii(sharename
, i2
->sharename
.buffer
,
292 sizeof(sharename
) - 1);
293 unistr_to_ascii(portname
, i2
->portname
.buffer
, sizeof(portname
) - 1);
294 unistr_to_ascii(drivername
, i2
->drivername
.buffer
,
295 sizeof(drivername
) - 1);
296 unistr_to_ascii(comment
, i2
->comment
.buffer
, sizeof(comment
) - 1);
297 unistr_to_ascii(location
, i2
->location
.buffer
, sizeof(location
) - 1);
298 unistr_to_ascii(sepfile
, i2
->sepfile
.buffer
, sizeof(sepfile
) - 1);
299 unistr_to_ascii(printprocessor
, i2
->printprocessor
.buffer
,
300 sizeof(printprocessor
) - 1);
301 unistr_to_ascii(datatype
, i2
->datatype
.buffer
, sizeof(datatype
) - 1);
302 unistr_to_ascii(parameters
, i2
->parameters
.buffer
,
303 sizeof(parameters
) - 1);
305 printf("\tservername:[%s]\n", servername
);
306 printf("\tprintername:[%s]\n", printername
);
307 printf("\tsharename:[%s]\n", sharename
);
308 printf("\tportname:[%s]\n", portname
);
309 printf("\tdrivername:[%s]\n", drivername
);
310 printf("\tcomment:[%s]\n", comment
);
311 printf("\tlocation:[%s]\n", location
);
312 printf("\tsepfile:[%s]\n", sepfile
);
313 printf("\tprintprocessor:[%s]\n", printprocessor
);
314 printf("\tdatatype:[%s]\n", datatype
);
315 printf("\tparameters:[%s]\n", parameters
);
316 printf("\tattributes:[0x%x]\n", i2
->attributes
);
317 printf("\tpriority:[0x%x]\n", i2
->priority
);
318 printf("\tdefaultpriority:[0x%x]\n", i2
->defaultpriority
);
319 printf("\tstarttime:[0x%x]\n", i2
->starttime
);
320 printf("\tuntiltime:[0x%x]\n", i2
->untiltime
);
321 printf("\tstatus:[0x%x]\n", i2
->status
);
322 printf("\tcjobs:[0x%x]\n", i2
->cjobs
);
323 printf("\taverageppm:[0x%x]\n", i2
->averageppm
);
325 if (i2
->secdesc
) display_sec_desc(i2
->secdesc
);
328 /****************************************************************************
329 printer info level 3 display function
330 ****************************************************************************/
331 static void display_print_info_3(PRINTER_INFO_3
*i3
)
333 printf("\tflags:[0x%x]\n", i3
->flags
);
335 display_sec_desc(i3
->secdesc
);
338 /* Enumerate printers */
340 static uint32
cmd_spoolss_enum_printers(struct cli_state
*cli
, int argc
, char **argv
)
342 uint32 result
= NT_STATUS_UNSUCCESSFUL
,
344 PRINTER_INFO_CTR ctr
;
351 printf("Usage: %s [level]\n", argv
[0]);
352 return NT_STATUS_NOPROBLEMO
;
355 if (!(mem_ctx
=talloc_init()))
357 DEBUG(0,("cmd_spoolss_enum_printers: talloc_init returned NULL!\n"));
358 return NT_STATUS_UNSUCCESSFUL
;
363 info_level
= atoi(argv
[1]);
366 /* Initialise RPC connection */
367 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
)) {
368 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
369 return NT_STATUS_UNSUCCESSFUL
;
372 /* Enumerate printers -- Should we enumerate types other
373 than PRINTER_ENUM_LOCAL? Maybe accept as a parameter? --jerry */
375 result
= cli_spoolss_enum_printers(cli
, mem_ctx
, PRINTER_ENUM_LOCAL
,
376 info_level
, &returned
, &ctr
);
378 if (result
== NT_STATUS_NOPROBLEMO
)
381 printf ("No Printers printers returned.\n");
385 for (i
=0; i
<returned
; i
++) {
386 display_print_info_0(&(ctr
.printers_0
[i
]));
390 for (i
=0; i
<returned
; i
++) {
391 display_print_info_1(&(ctr
.printers_1
[i
]));
395 for (i
=0; i
<returned
; i
++) {
396 display_print_info_2(&(ctr
.printers_2
[i
]));
400 for (i
=0; i
<returned
; i
++) {
401 display_print_info_3(&(ctr
.printers_3
[i
]));
405 printf("unknown info level %d\n", info_level
);
410 cli_nt_session_close(cli
);
411 talloc_destroy(mem_ctx
);
416 /****************************************************************************
417 port info level 1 display function
418 ****************************************************************************/
419 static void display_port_info_1(PORT_INFO_1
*i1
)
423 unistr_to_ascii(buffer
, i1
->port_name
.buffer
, sizeof(buffer
)-1);
424 printf("\tPort Name:\t[%s]\n", buffer
);
427 /****************************************************************************
428 port info level 2 display function
429 ****************************************************************************/
430 static void display_port_info_2(PORT_INFO_2
*i2
)
434 unistr_to_ascii(buffer
, i2
->port_name
.buffer
, sizeof(buffer
) - 1);
435 printf("\tPort Name:\t[%s]\n", buffer
);
436 unistr_to_ascii(buffer
, i2
->monitor_name
.buffer
, sizeof(buffer
) - 1);
437 printf("\tMonitor Name:\t[%s]\n", buffer
);
438 unistr_to_ascii(buffer
, i2
->description
.buffer
, sizeof(buffer
) - 1);
439 printf("\tDescription:\t[%s]\n", buffer
);
440 printf("\tPort Type:\t[%d]\n", i2
->port_type
);
441 printf("\tReserved:\t[%d]\n", i2
->reserved
);
445 /* Enumerate ports */
447 static uint32
cmd_spoolss_enum_ports(struct cli_state
*cli
, int argc
, char **argv
)
449 uint32 result
= NT_STATUS_UNSUCCESSFUL
,
456 printf("Usage: %s [level]\n", argv
[0]);
457 return NT_STATUS_NOPROBLEMO
;
460 if (!(mem_ctx
=talloc_init()))
462 DEBUG(0,("cmd_spoolss_enum_ports: talloc_init returned NULL!\n"));
463 return NT_STATUS_UNSUCCESSFUL
;
468 info_level
= atoi(argv
[1]);
471 /* Initialise RPC connection */
472 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
)) {
473 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
474 return NT_STATUS_UNSUCCESSFUL
;
477 /* Enumerate ports */
480 result
= cli_spoolss_enum_ports(cli
, mem_ctx
, info_level
, &returned
, &ctr
);
482 if (result
== NT_STATUS_NOPROBLEMO
) {
485 for (i
= 0; i
< returned
; i
++) {
486 switch (info_level
) {
488 display_port_info_1(&ctr
.port
.info_1
[i
]);
491 display_port_info_2(&ctr
.port
.info_2
[i
]);
494 printf("unknown info level %d\n", info_level
);
500 cli_nt_session_close(cli
);
501 talloc_destroy(mem_ctx
);
506 /***********************************************************************
507 * Get printer information
509 static uint32
cmd_spoolss_getprinter(struct cli_state
*cli
, int argc
, char **argv
)
514 BOOL opened_hnd
= False
;
515 PRINTER_INFO_CTR ctr
;
521 if (argc
== 1 || argc
> 3) {
522 printf("Usage: %s <printername> [level]\n", argv
[0]);
523 return NT_STATUS_NOPROBLEMO
;
526 if (!(mem_ctx
=talloc_init()))
528 DEBUG(0,("cmd_spoolss_getprinter: talloc_init returned NULL!\n"));
529 return NT_STATUS_UNSUCCESSFUL
;
533 /* Initialise RPC connection */
534 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
)) {
535 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
536 return NT_STATUS_UNSUCCESSFUL
;
539 /* Open a printer handle */
541 info_level
= atoi(argv
[2]);
544 slprintf (servername
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
545 strupper (servername
);
546 slprintf (printername
, sizeof(fstring
)-1, "%s\\%s", servername
, argv
[1]);
547 fstrcpy (user
, cli
->user_name
);
549 /* get a printer handle */
550 if ((result
= cli_spoolss_open_printer_ex(
551 cli
, mem_ctx
, printername
, "", MAXIMUM_ALLOWED_ACCESS
, servername
,
552 user
, &pol
)) != NT_STATUS_NOPROBLEMO
) {
558 /* Get printer info */
559 if ((result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, info_level
, &ctr
))
560 != NT_STATUS_NOPROBLEMO
) {
564 /* Display printer info */
566 switch (info_level
) {
568 display_print_info_0(ctr
.printers_0
);
571 display_print_info_1(ctr
.printers_1
);
574 display_print_info_2(ctr
.printers_2
);
577 display_print_info_3(ctr
.printers_3
);
580 printf("unknown info level %d\n", info_level
);
586 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
588 cli_nt_session_close(cli
);
589 talloc_destroy(mem_ctx
);
594 /****************************************************************************
595 printer info level 0 display function
596 ****************************************************************************/
597 static void display_print_driver_1(DRIVER_INFO_1
*i1
)
603 unistr_to_ascii(name
, i1
->name
.buffer
, sizeof(name
)-1);
605 printf ("Printer Driver Info 1:\n");
606 printf ("\tDriver Name: [%s]\n\n", name
);
611 /****************************************************************************
612 printer info level 1 display function
613 ****************************************************************************/
614 static void display_print_driver_2(DRIVER_INFO_2
*i1
)
617 fstring architecture
;
624 unistr_to_ascii(name
, i1
->name
.buffer
, sizeof(name
)-1);
625 unistr_to_ascii(architecture
, i1
->architecture
.buffer
, sizeof(architecture
)-1);
626 unistr_to_ascii(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
)-1);
627 unistr_to_ascii(datafile
, i1
->datafile
.buffer
, sizeof(datafile
)-1);
628 unistr_to_ascii(configfile
, i1
->configfile
.buffer
, sizeof(configfile
)-1);
630 printf ("Printer Driver Info 2:\n");
631 printf ("\tVersion: [%x]\n", i1
->version
);
632 printf ("\tDriver Name: [%s]\n", name
);
633 printf ("\tArchitecture: [%s]\n", architecture
);
634 printf ("\tDriver Path: [%s]\n", driverpath
);
635 printf ("\tDatafile: [%s]\n", datafile
);
636 printf ("\tConfigfile: [%s]\n\n", configfile
);
641 /****************************************************************************
642 printer info level 2 display function
643 ****************************************************************************/
644 static void display_print_driver_3(DRIVER_INFO_3
*i1
)
647 fstring architecture
;
652 fstring dependentfiles
;
654 fstring defaultdatatype
;
662 unistr_to_ascii(name
, i1
->name
.buffer
, sizeof(name
)-1);
663 unistr_to_ascii(architecture
, i1
->architecture
.buffer
, sizeof(architecture
)-1);
664 unistr_to_ascii(driverpath
, i1
->driverpath
.buffer
, sizeof(driverpath
)-1);
665 unistr_to_ascii(datafile
, i1
->datafile
.buffer
, sizeof(datafile
)-1);
666 unistr_to_ascii(configfile
, i1
->configfile
.buffer
, sizeof(configfile
)-1);
667 unistr_to_ascii(helpfile
, i1
->helpfile
.buffer
, sizeof(helpfile
)-1);
669 unistr_to_ascii(monitorname
, i1
->monitorname
.buffer
, sizeof(monitorname
)-1);
670 unistr_to_ascii(defaultdatatype
, i1
->defaultdatatype
.buffer
, sizeof(defaultdatatype
)-1);
672 printf ("Printer Driver Info 3:\n");
673 printf ("\tVersion: [%x]\n", i1
->version
);
674 printf ("\tDriver Name: [%s]\n",name
);
675 printf ("\tArchitecture: [%s]\n", architecture
);
676 printf ("\tDriver Path: [%s]\n", driverpath
);
677 printf ("\tDatafile: [%s]\n", datafile
);
678 printf ("\tConfigfile: [%s]\n", configfile
);
679 printf ("\tHelpfile: [%s]\n\n", helpfile
);
683 unistr_to_ascii(dependentfiles
, i1
->dependentfiles
+length
, sizeof(dependentfiles
)-1);
684 length
+=strlen(dependentfiles
)+1;
686 if (strlen(dependentfiles
) > 0)
688 printf ("\tDependentfiles: [%s]\n", dependentfiles
);
698 printf ("\tMonitorname: [%s]\n", monitorname
);
699 printf ("\tDefaultdatatype: [%s]\n\n", defaultdatatype
);
704 /***********************************************************************
705 * Get printer information
707 static uint32
cmd_spoolss_getdriver(struct cli_state
*cli
, int argc
, char **argv
)
712 BOOL opened_hnd
= False
;
713 PRINTER_DRIVER_CTR ctr
;
720 if ((argc
== 1) || (argc
> 3))
722 printf("Usage: %s <printername> [level]\n", argv
[0]);
723 return NT_STATUS_NOPROBLEMO
;
726 if (!(mem_ctx
=talloc_init()))
728 DEBUG(0,("cmd_spoolss_getdriver: talloc_init returned NULL!\n"));
729 return NT_STATUS_UNSUCCESSFUL
;
732 /* Initialise RPC connection */
733 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
))
735 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
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 if ((result
=cli_spoolss_open_printer_ex (cli
, mem_ctx
, printername
, "",
749 MAXIMUM_ALLOWED_ACCESS
, servername
, user
, &pol
)) != NT_STATUS_NO_PROBLEMO
)
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
);
765 case NT_STATUS_NO_PROBLEMO
:
768 case ERROR_UNKNOWN_PRINTER_DRIVER
:
772 printf ("Error getting driver for %s [%s] - %s\n", printername
,
773 archi_table
[i
].long_archi
, get_nt_error_msg(result
));
778 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
783 display_print_driver_1 (ctr
.info1
);
786 display_print_driver_2 (ctr
.info2
);
789 display_print_driver_3 (ctr
.info3
);
792 printf("unknown info level %d\n", info_level
);
802 cli_spoolss_close_printer (cli
, mem_ctx
, &pol
);
803 cli_nt_session_close (cli
);
804 talloc_destroy(mem_ctx
);
806 if (result
==ERROR_UNKNOWN_PRINTER_DRIVER
)
807 return NT_STATUS_NO_PROBLEMO
;
813 /***********************************************************************
814 * Get printer information
816 static uint32
cmd_spoolss_enum_drivers(struct cli_state
*cli
, int argc
, char **argv
)
820 PRINTER_DRIVER_CTR ctr
;
828 printf("Usage: enumdrivers [level]\n");
829 return NT_STATUS_NOPROBLEMO
;
832 if (!(mem_ctx
=talloc_init()))
834 DEBUG(0,("cmd_spoolss_enum_drivers: talloc_init returned NULL!\n"));
835 return NT_STATUS_UNSUCCESSFUL
;
838 /* Initialise RPC connection */
839 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
))
841 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
842 return NT_STATUS_UNSUCCESSFUL
;
845 /* get the arguments need to open the printer handle */
846 slprintf (servername
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
847 strupper (servername
);
849 info_level
= atoi(argv
[1]);
852 /* loop through and print driver info level for each architecture */
853 for (i
=0; archi_table
[i
].long_archi
!=NULL
; i
++)
856 result
= cli_spoolss_enumprinterdrivers (cli
, mem_ctx
, info_level
,
857 archi_table
[i
].long_archi
, &returned
, &ctr
);
863 if (result
!= NT_STATUS_NO_PROBLEMO
)
865 printf ("Error getting driver for environment [%s] - %s\n",
866 archi_table
[i
].long_archi
, get_nt_error_msg(result
));
870 printf ("\n[%s]\n", archi_table
[i
].long_archi
);
875 for (j
=0; j
< returned
; j
++) {
876 display_print_driver_1 (&(ctr
.info1
[j
]));
880 for (j
=0; j
< returned
; j
++) {
881 display_print_driver_2 (&(ctr
.info2
[j
]));
885 for (j
=0; j
< returned
; j
++) {
886 display_print_driver_3 (&(ctr
.info3
[j
]));
890 printf("unknown info level %d\n", info_level
);
897 cli_nt_session_close (cli
);
898 talloc_destroy(mem_ctx
);
900 if (result
==ERROR_UNKNOWN_PRINTER_DRIVER
)
901 return NT_STATUS_NO_PROBLEMO
;
907 /****************************************************************************
908 printer info level 1 display function
909 ****************************************************************************/
910 static void display_printdriverdir_1(DRIVER_DIRECTORY_1
*i1
)
916 unistr_to_ascii(name
, i1
->name
.buffer
, sizeof(name
)-1);
918 printf ("\tDirectory Name:[%s]\n", name
);
921 /***********************************************************************
922 * Get printer driver directory information
924 static uint32
cmd_spoolss_getdriverdir(struct cli_state
*cli
, int argc
, char **argv
)
928 DRIVER_DIRECTORY_CTR ctr
;
933 printf("Usage: %s [environment]\n", argv
[0]);
934 return NT_STATUS_NOPROBLEMO
;
937 /* Initialise RPC connection */
938 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
))
940 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
941 return NT_STATUS_UNSUCCESSFUL
;
944 if (!(mem_ctx
=talloc_init()))
946 DEBUG(0,("cmd_spoolss_getdriverdir: talloc_init returned NULL!\n"));
947 return NT_STATUS_UNSUCCESSFUL
;
951 /* get the arguments need to open the printer handle */
953 fstrcpy (env
, argv
[1]);
955 fstrcpy (env
, "Windows NT x86");
957 /* Get the directory. Only use Info level 1 */
958 if ((result
= cli_spoolss_getprinterdriverdir (cli
, mem_ctx
, 1, env
, &ctr
))
959 != NT_STATUS_NO_PROBLEMO
)
965 display_printdriverdir_1 (ctr
.info1
);
968 cli_nt_session_close (cli
);
969 talloc_destroy(mem_ctx
);
975 /*******************************************************************************
976 set the version and environment fields of a DRIVER_INFO_3 struct
977 ******************************************************************************/
978 void set_drv_info_3_env (DRIVER_INFO_3
*info
, const char *arch
)
983 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
985 if (strcmp(arch
, archi_table
[i
].short_archi
) == 0)
987 info
->version
= archi_table
[i
].version
;
988 init_unistr (&info
->architecture
, archi_table
[i
].long_archi
);
993 if (archi_table
[i
].long_archi
== NULL
)
995 DEBUG(0, ("set_drv_info_3_env: Unknown arch [%s]\n", arch
));
1002 /**************************************************************************
1003 wrapper for strtok to get the next parameter from a delimited list.
1004 Needed to handle the empty parameter string denoted by "NULL"
1005 *************************************************************************/
1006 static char* get_driver_3_param (char* str
, char* delim
, UNISTR
* dest
)
1010 /* get the next token */
1011 ptr
= strtok(str
, delim
);
1013 /* a string of 'NULL' is used to represent an empty
1014 parameter because two consecutive delimiters
1015 will not return an empty string. See man strtok(3)
1017 if (StrCaseCmp(ptr
, "NULL") == 0)
1021 init_unistr(dest
, ptr
);
1026 /********************************************************************************
1027 fill in the members of a DRIVER_INFO_3 struct using a character
1028 string in the form of
1029 <Long Printer Name>:<Driver File Name>:<Data File Name>:\
1030 <Config File Name>:<Help File Name>:<Language Monitor Name>:\
1031 <Default Data Type>:<Comma Separated list of Files>
1032 *******************************************************************************/
1033 static BOOL
init_drv_info_3_members (
1034 TALLOC_CTX
*mem_ctx
,
1035 DRIVER_INFO_3
*info
,
1042 /* fill in the UNISTR fields */
1043 str
= get_driver_3_param (args
, ":", &info
->name
);
1044 str
= get_driver_3_param (NULL
, ":", &info
->driverpath
);
1045 str
= get_driver_3_param (NULL
, ":", &info
->datafile
);
1046 str
= get_driver_3_param (NULL
, ":", &info
->configfile
);
1047 str
= get_driver_3_param (NULL
, ":", &info
->helpfile
);
1048 str
= get_driver_3_param (NULL
, ":", &info
->monitorname
);
1049 str
= get_driver_3_param (NULL
, ":", &info
->defaultdatatype
);
1051 /* <Comma Separated List of Dependent Files> */
1052 str2
= get_driver_3_param (NULL
, ":", NULL
); /* save the beginning of the string */
1055 /* begin to strip out each filename */
1056 str
= strtok(str
, ",");
1060 /* keep a cumlative count of the str lengths */
1061 len
+= strlen(str
)+1;
1062 str
= strtok(NULL
, ",");
1065 /* allocate the space; add one extra slot for a terminating NULL.
1066 Each filename is NULL terminated and the end contains a double
1068 if ((info
->dependentfiles
=(uint16
*)talloc(mem_ctx
, (len
+1)*sizeof(uint16
))) == NULL
)
1070 DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n"));
1073 for (i
=0; i
<len
; i
++)
1075 info
->dependentfiles
[i
] = (uint16
)str2
[i
];
1077 info
->dependentfiles
[len
] = '\0';
1083 static uint32
cmd_spoolss_addprinterdriver (struct cli_state
*cli
, int argc
, char **argv
)
1087 PRINTER_DRIVER_CTR ctr
;
1088 DRIVER_INFO_3 info3
;
1090 fstring driver_name
;
1091 TALLOC_CTX
*mem_ctx
= NULL
;
1093 /* parse the command arguements */
1096 printf ("Usage: %s <Environment>\\\n", argv
[0]);
1097 printf ("\t<Long Printer Name>:<Driver File Name>:<Data File Name>:\\\n");
1098 printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
1099 printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
1101 return NT_STATUS_NOPROBLEMO
;
1104 if (!(mem_ctx
=talloc_init()))
1106 DEBUG(0,("cmd_spoolss_addprinterdriver: talloc_init returned NULL!\n"));
1107 return NT_STATUS_UNSUCCESSFUL
;
1110 /* Initialise RPC connection */
1111 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
))
1113 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
1114 return NT_STATUS_UNSUCCESSFUL
;
1118 /* Fill in the DRIVER_INFO_3 struct */
1120 if (!get_short_archi(arch
, argv
[1]))
1122 printf ("Error Unknown architechture [%s]\n", argv
[1]);
1123 return NT_STATUS_INVALID_PARAMETER
;
1126 set_drv_info_3_env(&info3
, arch
);
1128 if (!init_drv_info_3_members(mem_ctx
, &info3
, argv
[2]))
1130 printf ("Error Invalid parameter list - %s.\n", argv
[2]);
1131 return NT_STATUS_INVALID_PARAMETER
;
1136 if ((result
= cli_spoolss_addprinterdriver (cli
, mem_ctx
, level
, &ctr
))
1137 != NT_STATUS_NO_PROBLEMO
)
1142 unistr_to_ascii (driver_name
, info3
.name
.buffer
, sizeof(driver_name
)-1);
1143 printf ("Printer Driver %s successfully installed.\n", driver_name
);
1146 cli_nt_session_close (cli
);
1147 talloc_destroy(mem_ctx
);
1154 static uint32
cmd_spoolss_addprinterex (struct cli_state
*cli
, int argc
, char **argv
)
1158 PRINTER_INFO_CTR ctr
;
1159 PRINTER_INFO_2 info2
;
1161 TALLOC_CTX
*mem_ctx
= NULL
;
1163 /* parse the command arguements */
1166 printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv
[0]);
1167 return NT_STATUS_NOPROBLEMO
;
1170 if (!(mem_ctx
=talloc_init()))
1172 DEBUG(0,("cmd_spoolss_addprinterex: talloc_init returned NULL!\n"));
1173 return NT_STATUS_UNSUCCESSFUL
;
1177 slprintf (servername
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
1178 strupper (servername
);
1180 /* Initialise RPC connection */
1181 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
))
1183 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
1184 return NT_STATUS_UNSUCCESSFUL
;
1188 /* Fill in the DRIVER_INFO_3 struct */
1191 init_unistr( &info2
.servername
, servername
);
1193 init_unistr( &info2
.printername
, argv
[1]);
1194 init_unistr( &info2
.sharename
, argv
[2]);
1195 init_unistr( &info2
.drivername
, argv
[3]);
1196 init_unistr( &info2
.portname
, argv
[4]);
1197 init_unistr( &info2
.comment
, "Created by rpcclient");
1198 init_unistr( &info2
.printprocessor
, "winprint");
1199 init_unistr( &info2
.datatype
, "RAW");
1200 info2
.devmode
= NULL
;
1201 info2
.secdesc
= NULL
;
1202 info2
.attributes
= PRINTER_ATTRIBUTE_SHARED
;
1204 info2
.defaultpriority
= 0;
1205 info2
.starttime
= 0;
1206 info2
.untiltime
= 0;
1208 /* These three fields must not be used by AddPrinter()
1209 as defined in the MS Platform SDK documentation..
1213 info2.averageppm = 0;
1216 ctr
.printers_2
= &info2
;
1217 if ((result
= cli_spoolss_addprinterex (cli
, mem_ctx
, level
, &ctr
))
1218 != NT_STATUS_NO_PROBLEMO
)
1220 cli_nt_session_close (cli
);
1224 printf ("Printer %s successfully installed.\n", argv
[1]);
1227 cli_nt_session_close (cli
);
1228 talloc_destroy(mem_ctx
);
1234 static uint32
cmd_spoolss_setdriver (struct cli_state
*cli
, int argc
, char **argv
)
1239 BOOL opened_hnd
= False
;
1240 PRINTER_INFO_CTR ctr
;
1241 PRINTER_INFO_2 info2
;
1245 TALLOC_CTX
*mem_ctx
= NULL
;
1247 /* parse the command arguements */
1250 printf ("Usage: %s <printer> <driver>\n", argv
[0]);
1251 return NT_STATUS_NOPROBLEMO
;
1254 if (!(mem_ctx
=talloc_init()))
1256 DEBUG(0,("cmd_spoolss_setdriver: talloc_init returned NULL!\n"));
1257 return NT_STATUS_UNSUCCESSFUL
;
1260 slprintf (servername
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
1261 strupper (servername
);
1262 slprintf (printername
, sizeof(fstring
)-1, "%s\\%s", servername
, argv
[1]);
1263 fstrcpy (user
, cli
->user_name
);
1265 /* Initialise RPC connection */
1266 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
))
1268 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
1269 return NT_STATUS_UNSUCCESSFUL
;
1273 /* get a printer handle */
1274 if ((result
= cli_spoolss_open_printer_ex(cli
, mem_ctx
, printername
, "",
1275 MAXIMUM_ALLOWED_ACCESS
, servername
, user
, &pol
))
1276 != NT_STATUS_NOPROBLEMO
)
1283 /* Get printer info */
1284 ZERO_STRUCT (info2
);
1285 ctr
.printers_2
= &info2
;
1286 if ((result
= cli_spoolss_getprinter(cli
, mem_ctx
, &pol
, level
, &ctr
)) != NT_STATUS_NOPROBLEMO
)
1288 printf ("Unable to retreive printer information!\n");
1292 /* set the printer driver */
1293 init_unistr(&ctr
.printers_2
->drivername
, argv
[2]);
1294 if ((result
= cli_spoolss_setprinter(cli
, mem_ctx
, &pol
, level
, &ctr
, 0)) != NT_STATUS_NO_PROBLEMO
)
1296 printf ("SetPrinter call failed!\n");
1299 printf ("Succesfully set %s to driver %s.\n", argv
[1], argv
[2]);
1305 cli_spoolss_close_printer(cli
, mem_ctx
, &pol
);
1306 cli_nt_session_close (cli
);
1307 talloc_destroy(mem_ctx
);
1313 static uint32
cmd_spoolss_deletedriver (struct cli_state
*cli
, int argc
, char **argv
)
1315 uint32 result
= NT_STATUS_UNSUCCESSFUL
;
1317 TALLOC_CTX
*mem_ctx
= NULL
;
1320 /* parse the command arguements */
1323 printf ("Usage: %s <driver>\n", argv
[0]);
1324 return NT_STATUS_NOPROBLEMO
;
1327 if (!(mem_ctx
=talloc_init()))
1329 DEBUG(0,("cmd_spoolss_deletedriver: talloc_init returned NULL!\n"));
1330 return NT_STATUS_UNSUCCESSFUL
;
1333 slprintf (servername
, sizeof(fstring
)-1, "\\\\%s", cli
->desthost
);
1334 strupper (servername
);
1336 /* Initialise RPC connection */
1337 if (!cli_nt_session_open (cli
, PIPE_SPOOLSS
))
1339 fprintf (stderr
, "Could not initialize spoolss pipe!\n");
1340 return NT_STATUS_UNSUCCESSFUL
;
1343 /* delete the driver for all architectures */
1344 for (i
=0; archi_table
[i
].long_archi
; i
++)
1346 /* make the call to remove the driver */
1347 if ((result
= cli_spoolss_deleteprinterdriver(cli
, mem_ctx
,
1348 archi_table
[i
].long_archi
, argv
[1])) != NT_STATUS_NO_PROBLEMO
)
1350 printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
1351 argv
[1], archi_table
[i
].long_archi
, get_nt_error_msg(result
));
1354 printf ("Driver %s removed for arch [%s].\n", argv
[1], archi_table
[i
].long_archi
);
1360 cli_nt_session_close (cli
);
1361 talloc_destroy(mem_ctx
);
1363 return NT_STATUS_NO_PROBLEMO
;
1367 /* List of commands exported by this module */
1368 struct cmd_set spoolss_commands
[] = {
1370 { "SPOOLSS", NULL
, "" },
1371 { "adddriver", cmd_spoolss_addprinterdriver
, "Add a print driver" },
1372 { "addprinter", cmd_spoolss_addprinterex
, "Add a printer" },
1373 { "deldriver", cmd_spoolss_deletedriver
, "Delete a printer driver" },
1374 { "enumdata", cmd_spoolss_not_implemented
, "Enumerate printer data (*)" },
1375 { "enumjobs", cmd_spoolss_not_implemented
, "Enumerate print jobs (*)" },
1376 { "enumports", cmd_spoolss_enum_ports
, "Enumerate printer ports" },
1377 { "enumdrivers", cmd_spoolss_enum_drivers
, "Enumerate installed printer drivers" },
1378 { "enumprinters", cmd_spoolss_enum_printers
, "Enumerate printers" },
1379 { "getdata", cmd_spoolss_not_implemented
, "Get print driver data (*)" },
1380 { "getdriver", cmd_spoolss_getdriver
, "Get print driver information" },
1381 { "getdriverdir", cmd_spoolss_getdriverdir
, "Get print driver upload directory" },
1382 { "getprinter", cmd_spoolss_getprinter
, "Get printer info" },
1383 { "openprinter", cmd_spoolss_open_printer_ex
, "Open printer handle" },
1384 { "setdriver", cmd_spoolss_setdriver
, "Set printer driver" },
1385 { NULL
, NULL
, NULL
}