2 Unix SMB/Netbios implementation.
4 NT Domain Authentication SMB / MSRPC client
5 Copyright (C) Andrew Tridgell 1994-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
7 Copyright (C) Jean-Francois Micouleau 1999-2000
8 Copyright (C) Gerald Carter 2000
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "rpc_parse.h"
28 #include "rpc_client.h"
29 #include "rpcclient.h"
31 extern int DEBUGLEVEL
;
37 extern struct user_creds
*usr_creds
;
39 /****************************************************************************
41 ****************************************************************************/
42 uint32
cmd_spoolss_enum_printers(struct client_info
*info
, int argc
, char *argv
[])
50 fstrcpy(srv_name
, "\\\\");
51 fstrcat(srv_name
, info
->dest_host
);
54 flags
=PRINTER_ENUM_LOCAL
;
56 if (msrpc_spoolss_enum_printers(srv_name
, flags
, level
, ctr
))
57 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
59 report(out_hnd
, "FAILED\n");
61 flags
=PRINTER_ENUM_NAME
;
63 if (msrpc_spoolss_enum_printers(srv_name
, flags
, level
, ctr
))
64 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
66 report(out_hnd
, "FAILED\n");
68 flags
=PRINTER_ENUM_SHARED
|PRINTER_ENUM_NAME
;
70 if (msrpc_spoolss_enum_printers(srv_name
, flags
, level
, ctr
))
71 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
73 report(out_hnd
, "FAILED\n");
75 flags
=PRINTER_ENUM_CONNECTIONS
;
77 if (msrpc_spoolss_enum_printers(srv_name
, flags
, level
, ctr
))
78 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
80 report(out_hnd
, "FAILED\n");
82 flags
=PRINTER_ENUM_NETWORK
;
84 if (msrpc_spoolss_enum_printers(srv_name
, flags
, level
, ctr
))
85 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
87 report(out_hnd
, "FAILED\n");
89 flags
=PRINTER_ENUM_REMOTE
;
91 if (msrpc_spoolss_enum_printers(srv_name
, flags
, level
, ctr
))
92 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
94 report(out_hnd
, "FAILED\n");
96 return NT_STATUS_NOPROBLEMO
;
99 /****************************************************************************
101 ****************************************************************************/
102 uint32
cmd_spoolss_enum_ports(struct client_info
*info
, int argc
, char *argv
[])
110 report (out_hnd
, "spoolenumports <level>\n");
111 return NT_STATUS_INVALID_PARAMETER
;
115 fstrcpy(srv_name
, "\\\\");
116 fstrcat(srv_name
, info
->dest_host
);
119 level
= atoi(argv
[1]);
121 if (msrpc_spoolss_enum_ports(srv_name
, level
, &ctr
))
122 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
124 report(out_hnd
, "FAILED\n");
126 return NT_STATUS_NOPROBLEMO
;
129 /****************************************************************************
131 ****************************************************************************/
132 uint32
cmd_spoolss_enum_printerdata(struct client_info
*info
, int argc
, char *argv
[])
139 report(out_hnd
, "spoolenumdata <printer name>\n");
140 return NT_STATUS_INVALID_PARAMETER
;
143 printer_name
= argv
[1];
145 fstrcpy(station
, "\\\\");
146 fstrcat(station
, info
->myhostname
);
149 fstrcpy(srv_name
, "\\\\");
150 fstrcat(srv_name
, info
->dest_host
);
153 if (!strnequal("\\\\", printer_name
, 2))
155 fstrcat(srv_name
, "\\");
156 fstrcat(srv_name
, printer_name
);
157 printer_name
= srv_name
;
160 DEBUG(0,("spoolenumdata - printer: %s station: %s user: %s\n", printer_name
, station
, usr_creds
->ntc
.user_name
));
162 if (msrpc_spoolss_enum_printerdata( printer_name
, station
,
163 usr_creds
->ntc
.user_name
))
165 DEBUG(0,("cmd_spoolss_enum_printerdata: query succeeded\n"));
166 return NT_STATUS_NOPROBLEMO
;
168 report(out_hnd
, "FAILED\n");
169 return NT_STATUS_UNSUCCESSFUL
;
172 /****************************************************************************
174 ****************************************************************************/
175 uint32
cmd_spoolss_getprinter(struct client_info
*info
, int argc
, char *argv
[])
177 PRINTER_INFO_CTR ctr
;
184 report(out_hnd
, "spoolgetprinter <printer name>\n");
185 return NT_STATUS_INVALID_PARAMETER
;
188 printer_name
= argv
[1];
190 fstrcpy(station
, "\\\\");
191 fstrcat(station
, info
->myhostname
);
194 fstrcpy(srv_name
, "\\\\");
195 fstrcat(srv_name
, info
->dest_host
);
198 if (!strnequal("\\\\", printer_name
, 2))
200 fstrcat(srv_name
, "\\");
201 fstrcat(srv_name
, printer_name
);
202 printer_name
= srv_name
;
208 level
= atoi(argv
[2]);
210 if (msrpc_spoolss_getprinter(printer_name
, level
, station
, "Administrator", ctr
))
211 DEBUG(5,("cmd_spoolss_getprinter: query succeeded\n"));
213 report(out_hnd
, "FAILED\n");
215 return NT_STATUS_NOPROBLEMO
;
219 static void display_spool_job_info_ctr( const char* printer_name
,
222 uint32 num
, void *const *const ctr
)
224 display_job_info_ctr(out_hnd
, ACTION_HEADER
, level
, num
, ctr
);
225 display_job_info_ctr(out_hnd
, ACTION_ENUMERATE
, level
, num
, ctr
);
226 display_job_info_ctr(out_hnd
, ACTION_FOOTER
, level
, num
, ctr
);
229 /****************************************************************************
231 ****************************************************************************/
232 uint32
cmd_spoolss_enum_jobs(struct client_info
*info
, int argc
, char *argv
[])
242 report(out_hnd
, "spooljobs <printer name>\n");
243 return NT_STATUS_INVALID_PARAMETER
;
246 printer_name
= argv
[1];
248 fstrcpy(station
, "\\\\");
249 fstrcat(station
, info
->myhostname
);
252 fstrcpy(srv_name
, "\\\\");
253 fstrcat(srv_name
, info
->dest_host
);
256 if (!strnequal("\\\\", printer_name
, 2))
258 fstrcat(srv_name
, "\\");
259 fstrcat(srv_name
, printer_name
);
260 printer_name
= srv_name
;
263 DEBUG(4,("spoolopen - printer: %s station: %s user: %s\n", printer_name
,
264 station
, usr_creds
->ntc
.user_name
));
266 if (msrpc_spoolss_enum_jobs( printer_name
, station
,
267 usr_creds
->ntc
.user_name
,
268 level
, &ctr
, display_spool_job_info_ctr
))
270 DEBUG(5,("cmd_spoolss_enum_jobs: query succeeded\n"));
271 return NT_STATUS_NOPROBLEMO
;
273 report(out_hnd
, "FAILED\n");
274 return NT_STATUS_UNSUCCESSFUL
;
277 /****************************************************************************
279 ****************************************************************************/
280 uint32
cmd_spoolss_open_printer_ex(struct client_info
*info
, int argc
, char *argv
[])
291 report(out_hnd
, "spoolopen <printer name>\n");
292 return NT_STATUS_INVALID_PARAMETER
;
295 printer_name
= argv
[1];
297 fstrcpy(station
, "\\\\");
298 fstrcat(station
, info
->myhostname
);
301 fstrcpy(srv_name
, "\\\\");
302 fstrcat(srv_name
, info
->dest_host
);
305 if (!strnequal("\\\\", printer_name
, 2))
307 fstrcat(srv_name
, "\\");
308 fstrcat(srv_name
, printer_name
);
309 printer_name
= srv_name
;
312 DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
313 printer_name
, station
, usr_creds
->ntc
.user_name
));
315 res
= res
? spoolss_open_printer_ex( printer_name
, "", PRINTER_ALL_ACCESS
,
316 station
, "Administrator", &hnd
) : False
;
318 res
= res
? spoolss_closeprinter(&hnd
) : False
;
322 DEBUG(5,("cmd_spoolss_open_printer_ex: query succeeded\n"));
323 report(out_hnd
, "OK\n");
324 return NT_STATUS_NOPROBLEMO
;
326 DEBUG(5,("cmd_spoolss_open_printer_ex: query failed\n"));
327 return NT_STATUS_UNSUCCESSFUL
;
330 /****************************************************************************
332 ****************************************************************************/
333 uint32
cmd_spoolss_getprinterdata(struct client_info
*info
, int argc
, char *argv
[])
345 report(out_hnd
, "spoolgetdata <printer name> <value name>\n");
346 return NT_STATUS_INVALID_PARAMETER
;
349 printer_name
= argv
[1];
350 value_name
= argv
[2];
352 fstrcpy(station
, "\\\\");
353 fstrcat(station
, info
->myhostname
);
356 fstrcpy(srv_name
, "\\\\");
357 fstrcat(srv_name
, info
->dest_host
);
360 if (!strnequal("\\\\", printer_name
, 2))
362 fstrcat(srv_name
, "\\");
363 fstrcat(srv_name
, printer_name
);
364 printer_name
= srv_name
;
367 DEBUG(4,("spoolgetdata - printer: %s station: %s value: %s\n",
368 printer_name
, station
, value_name
));
370 status
= msrpc_spoolss_getprinterdata( printer_name
, station
,
371 /* "Administrateur", */
372 usr_creds
->ntc
.user_name
,
376 if (status
== NT_STATUS_NOPROBLEMO
)
378 DEBUG(5,("cmd_spoolss_getprinterdata: query succeeded\n"));
382 report(out_hnd
, "FAILED\n");
388 /****************************************************************************
390 ****************************************************************************/
391 uint32
cmd_spoolss_getprinterdriver(struct client_info
*info
, int argc
, char *argv
[])
393 PRINTER_DRIVER_CTR ctr
;
401 report(out_hnd
, "spoolgetprinterdriver <printer name>\n");
402 return NT_STATUS_INVALID_PARAMETER
;
405 printer_name
= argv
[1];
407 fstrcpy(station
, "\\\\");
408 fstrcat(station
, info
->myhostname
);
411 fstrcpy(srv_name
, "\\\\");
412 fstrcat(srv_name
, info
->dest_host
);
415 if (!strnequal("\\\\", printer_name
, 2))
417 fstrcat(srv_name
, "\\");
418 fstrcat(srv_name
, printer_name
);
419 printer_name
= srv_name
;
422 fstrcpy(environment
, "Windows NT x86");
425 if (msrpc_spoolss_getprinterdriver(printer_name
, environment
, level
, station
, "Administrator", ctr
))
426 DEBUG(5,("cmd_spoolss_getprinterdriver: query succeeded\n"));
428 report(out_hnd
, "FAILED\n");
430 return NT_STATUS_NOPROBLEMO
;
433 /****************************************************************************
435 ****************************************************************************/
436 uint32
cmd_spoolss_enumprinterdrivers(struct client_info
*info
, int argc
, char *argv
[])
438 PRINTER_DRIVER_CTR ctr
;
443 fstrcpy(srv_name
, "\\\\");
444 fstrcat(srv_name
, info
->dest_host
);
447 fstrcpy(environment
, "Windows NT x86");
450 if (msrpc_spoolss_enumprinterdrivers(srv_name
, environment
, level
, ctr
))
451 DEBUG(5,("cmd_spoolss_enumprinterdrivers: query succeeded\n"));
453 report(out_hnd
, "FAILED\n");
455 return NT_STATUS_NOPROBLEMO
;
458 /****************************************************************************
460 ****************************************************************************/
461 uint32
cmd_spoolss_getprinterdriverdir(struct client_info
*info
, int argc
, char *argv
[])
463 DRIVER_DIRECTORY_CTR ctr
;
471 fstrcpy(srv_name
, "\\\\");
472 fstrcat(srv_name
, info
->dest_host
);
476 report(out_hnd
, "spoolgetprinterdriverdir <arch>\n");
477 return NT_STATUS_NOPROBLEMO
;
480 fstrcpy(env
, argv
[1]);
482 for (i
=2; i
<=argc
; i
++) {
484 fstrcat(env
, argv
[i
]);
487 if (msrpc_spoolss_getprinterdriverdir(srv_name
, env
, level
, ctr
))
488 DEBUG(5,("cmd_spoolss_getprinterdriverdir: query succeeded\n"));
490 report(out_hnd
, "FAILED\n");
492 return NT_STATUS_NOPROBLEMO
;
495 /********************************************************************************
496 send an AddPrinterEx() request
497 ********************************************************************************/
498 uint32
cmd_spoolss_addprinterex(struct client_info
*info
, int argc
, char *argv
[])
505 PRINTER_INFO_2 print_info_2
;
506 PORT_INFO_1
*port_info_1
= NULL
;
512 fstring srv_port_name
;
513 BOOL valid_port
= False
;
514 TALLOC_CTX
*mem_ctx
= NULL
;
517 fstrcpy(srv_name
, "\\\\");
518 fstrcat(srv_name
, info
->dest_host
);
521 /* check (and copy) the command line arguments */
523 report(out_hnd
, "spooladdprinterex <name> <driver> <port>\n");
524 return NT_STATUS_NOPROBLEMO
;
528 fstrcpy(printer_name
, argv
[1]);
529 fstrcpy(driver_name
, argv
[2]);
530 fstrcpy(port_name
, argv
[3]);
533 /* Verify that the specified port is ok; spoolss_enum_ports() should
534 be a level 1 since all we need is the name */
535 if ((mem_ctx
=talloc_init()) == NULL
)
537 DEBUG(0, ("cmd_spoolss_addprinterex: talloc_init() failed!\n"));
538 return NT_STATUS_INVALID_PARAMETER
;
540 init_buffer (&buffer
, 0, mem_ctx
);
542 /* send a NULL buffer first */
543 status
=spoolss_enum_ports(srv_name
, 1, &buffer
, 0,
546 /* send the right amount of space this time */
547 if (status
==ERROR_INSUFFICIENT_BUFFER
) {
548 init_buffer(&buffer
, needed
, mem_ctx
);
549 status
=spoolss_enum_ports(srv_name
, 1, &buffer
,
550 needed
, &needed
, &returned
);
552 /* if the call succeeded, then decode the buffer into
553 an PRINTER_INFO_1 structre */
554 if (status
== NT_STATUS_NO_PROBLEMO
)
556 decode_port_info_1(&buffer
, returned
, &port_info_1
);
560 report (out_hnd
, "cmd_spoolss_addprinterex: FAILED to enumerate ports\n");
561 return NT_STATUS_NOPROBLEMO
;
567 * now we have an array of port names and we can interate
568 * through it to verify port_name before actually attempting
569 * to add the printer on the server.
571 for (i
=0; i
<returned
; i
++)
573 /* compare port_info_1[i].port_name to the port_name specified */
574 unistr_to_ascii(srv_port_name
, port_info_1
[i
].port_name
.buffer
,
575 sizeof(srv_port_name
)-1);
576 if (strequal(srv_port_name
, port_name
))
584 report (out_hnd
, "cmd_spoolss_addprinterex: Invalid port specified!\n");
585 return NT_STATUS_NOPROBLEMO
;
590 * Need to build the PRINTER_INFO_2 struct here.
591 * I think it would be better only to deal with a PRINTER_INFO_2
592 * and the abstract the creation of a SPOOL_PRINTER_INFO_LEVEL_2
593 * from that rather than dealing with the struct passed directly
594 * on the wire. We don't need the extra *_ptr fields, etc...
595 * here anyways. --jerry
597 ZERO_STRUCTP(&print_info_2
);
598 /* init_unistr( &print_info_2.servername, srv_name); */
599 init_unistr( &print_info_2
.printername
, printer_name
);
600 /* init_unistr( &print_info_2.sharename, share_name); */
601 init_unistr( &print_info_2
.portname
, port_name
);
602 init_unistr( &print_info_2
.drivername
, driver_name
);
603 init_unistr( &print_info_2
.comment
, "Created by rpcclient");
604 /* init_unistr( &print_info_2.location, "");
605 init_unistr( &print_info_2.sepfile, ""); */
606 init_unistr( &print_info_2
.printprocessor
, "winprint");
607 init_unistr( &print_info_2
.datatype
, "RAW");
608 /* init_unistr( &print_info_2.parameters, ""); */
609 print_info_2
.devmode
= NULL
;
610 print_info_2
.secdesc
= NULL
;
611 print_info_2
.attributes
= 0;
612 print_info_2
.priority
= 0;
613 print_info_2
.defaultpriority
= 0;
614 print_info_2
.starttime
= 0;
615 print_info_2
.untiltime
= 0;
616 print_info_2
.status
= 0;
617 print_info_2
.cjobs
= 0;
618 print_info_2
.averageppm
= 0;
621 /* if successful, spoolss_addprinterex() should return True and hnd
622 should be a valid handle to an open printer */
623 if ((result
= spoolss_addprinterex(&hnd
, srv_name
, &print_info_2
)) == NT_STATUS_NOPROBLEMO
)
625 if (!spoolss_closeprinter( &hnd
))
627 report (out_hnd
, "cmd_spoolss_addprinterex: spoolss_closeprinter FAILED!\n");
632 report (out_hnd
, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED! [%d]\n", result
);
636 return NT_STATUS_NOPROBLEMO
;
639 /********************************************************************************
640 send an AddPrinterDriver() request
641 ********************************************************************************/
642 uint32
cmd_spoolss_addprinterdriver(struct client_info
*info
, int argc
, char *argv
[])
645 return NT_STATUS_NOPROBLEMO
;