More work on rpcclient...
[ira/wip.git] / source3 / rpcclient / cmd_spoolss.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
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
9    
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.
14    
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.
19    
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.
23 */
24
25 #include "includes.h"
26 #include "nterr.h"
27 #include "rpc_parse.h"
28 #include "rpc_client.h"
29 #include "rpcclient.h"
30
31 extern int DEBUGLEVEL;
32
33 #define DEBUG_TESTING
34
35 extern FILE* out_hnd;
36
37 extern struct user_creds *usr_creds;
38
39 /****************************************************************************
40 nt spoolss query
41 ****************************************************************************/
42 uint32 cmd_spoolss_enum_printers(struct client_info *info, int argc, char *argv[])
43 {
44         PRINTER_INFO_CTR ctr;
45         
46         uint32 flags;
47         uint32 level = 1;
48
49         fstring srv_name;
50         fstrcpy(srv_name, "\\\\");
51         fstrcat(srv_name, info->dest_host);
52         strupper(srv_name);
53         
54         flags=PRINTER_ENUM_LOCAL;
55
56         if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr))
57                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
58         else
59                 report(out_hnd, "FAILED\n");
60                 
61         flags=PRINTER_ENUM_NAME;
62
63         if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr))
64                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
65         else
66                 report(out_hnd, "FAILED\n");
67
68         flags=PRINTER_ENUM_SHARED|PRINTER_ENUM_NAME;
69
70         if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr))
71                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
72         else
73                 report(out_hnd, "FAILED\n");
74                 
75         flags=PRINTER_ENUM_CONNECTIONS;
76
77         if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr))
78                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
79         else
80                 report(out_hnd, "FAILED\n");
81                 
82         flags=PRINTER_ENUM_NETWORK;
83
84         if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr))
85                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
86         else
87                 report(out_hnd, "FAILED\n");
88                 
89         flags=PRINTER_ENUM_REMOTE;
90
91         if (msrpc_spoolss_enum_printers(srv_name, flags, level, ctr))
92                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
93         else
94                 report(out_hnd, "FAILED\n");
95                 
96         return NT_STATUS_NOPROBLEMO;
97 }
98
99 /****************************************************************************
100 nt spoolss query
101 ****************************************************************************/
102 uint32 cmd_spoolss_enum_ports(struct client_info *info, int argc, char *argv[])
103 {
104         PORT_INFO_CTR ctr;
105         uint32 level;
106         fstring srv_name;
107         
108         if (argc < 1)
109         {
110                 report (out_hnd, "spoolenumports <level>\n");
111                 return NT_STATUS_INVALID_PARAMETER;
112         }
113
114                 
115         fstrcpy(srv_name, "\\\\");
116         fstrcat(srv_name, info->dest_host);
117         strupper(srv_name);
118         
119         level = atoi(argv[1]);
120         
121         if (msrpc_spoolss_enum_ports(srv_name, level, &ctr))
122                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
123         else
124                 report(out_hnd, "FAILED\n");
125                 
126         return NT_STATUS_NOPROBLEMO;
127 }
128
129 /****************************************************************************
130 nt spoolss query
131 ****************************************************************************/
132 uint32 cmd_spoolss_enum_printerdata(struct client_info *info, int argc, char *argv[])
133 {
134         fstring srv_name;
135         fstring station;
136         char *printer_name;
137
138         if (argc < 1) {
139                 report(out_hnd, "spoolenumdata <printer name>\n");
140                 return NT_STATUS_INVALID_PARAMETER;
141         }
142
143         printer_name = argv[1];
144
145         fstrcpy(station, "\\\\");
146         fstrcat(station, info->myhostname);
147         strupper(station);
148
149         fstrcpy(srv_name, "\\\\");
150         fstrcat(srv_name, info->dest_host);
151         strupper(srv_name);
152
153         if (!strnequal("\\\\", printer_name, 2))
154         {
155                 fstrcat(srv_name, "\\");
156                 fstrcat(srv_name, printer_name);
157                 printer_name = srv_name;
158         }
159
160         DEBUG(0,("spoolenumdata - printer: %s station: %s user: %s\n", printer_name, station, usr_creds->ntc.user_name));
161
162         if (msrpc_spoolss_enum_printerdata( printer_name, station,
163                                 usr_creds->ntc.user_name))
164         {
165                 DEBUG(0,("cmd_spoolss_enum_printerdata: query succeeded\n"));
166                 return NT_STATUS_NOPROBLEMO;
167         }
168         report(out_hnd, "FAILED\n");
169         return NT_STATUS_UNSUCCESSFUL;
170 }
171
172 /****************************************************************************
173 nt spoolss query
174 ****************************************************************************/
175 uint32 cmd_spoolss_getprinter(struct client_info *info, int argc, char *argv[])
176 {
177         PRINTER_INFO_CTR ctr;
178         fstring srv_name;
179         fstring station;
180         char *printer_name;
181         uint32 level;
182
183         if (argc < 1) {
184                 report(out_hnd, "spoolgetprinter <printer name>\n");
185                 return NT_STATUS_INVALID_PARAMETER;
186         }
187
188         printer_name = argv[1];
189
190         fstrcpy(station, "\\\\");
191         fstrcat(station, info->myhostname);
192         strupper(station);
193
194         fstrcpy(srv_name, "\\\\");
195         fstrcat(srv_name, info->dest_host);
196         strupper(srv_name);
197
198         if (!strnequal("\\\\", printer_name, 2))
199         {
200                 fstrcat(srv_name, "\\");
201                 fstrcat(srv_name, printer_name);
202                 printer_name = srv_name;
203         }
204
205         if (argc < 3)
206                 level=2;
207         else
208                 level = atoi(argv[2]);
209
210         if (msrpc_spoolss_getprinter(printer_name, level, station, "Administrator", ctr))
211                 DEBUG(5,("cmd_spoolss_getprinter: query succeeded\n"));
212         else
213                 report(out_hnd, "FAILED\n");
214
215         return NT_STATUS_NOPROBLEMO;
216 }
217
218
219 static void display_spool_job_info_ctr( const char* printer_name,
220                                 const char* station,
221                                 uint32 level,
222                                 uint32 num, void *const *const ctr)
223 {
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);
227 }
228
229 /****************************************************************************
230 nt spoolss query
231 ****************************************************************************/
232 uint32 cmd_spoolss_enum_jobs(struct client_info *info, int argc, char *argv[])
233 {
234         fstring srv_name;
235         fstring station;
236         char *printer_name;
237
238         void **ctr = NULL;
239         uint32 level = 1;
240
241         if (argc < 1) {
242                 report(out_hnd, "spooljobs <printer name>\n");
243                 return NT_STATUS_INVALID_PARAMETER;
244         }
245
246         printer_name = argv[1];
247
248         fstrcpy(station, "\\\\");
249         fstrcat(station, info->myhostname);
250         strupper(station);
251
252         fstrcpy(srv_name, "\\\\");
253         fstrcat(srv_name, info->dest_host);
254         strupper(srv_name);
255
256         if (!strnequal("\\\\", printer_name, 2))
257         {
258                 fstrcat(srv_name, "\\");
259                 fstrcat(srv_name, printer_name);
260                 printer_name = srv_name;
261         }
262
263         DEBUG(4,("spoolopen - printer: %s station: %s user: %s\n", printer_name, 
264                   station, usr_creds->ntc.user_name));
265
266         if (msrpc_spoolss_enum_jobs( printer_name, station,
267                                 usr_creds->ntc.user_name,
268                                 level, &ctr, display_spool_job_info_ctr))
269         {
270                 DEBUG(5,("cmd_spoolss_enum_jobs: query succeeded\n"));
271                 return NT_STATUS_NOPROBLEMO;
272         }
273         report(out_hnd, "FAILED\n");
274         return NT_STATUS_UNSUCCESSFUL;
275 }
276
277 /****************************************************************************
278 nt spoolss query
279 ****************************************************************************/
280 uint32 cmd_spoolss_open_printer_ex(struct client_info *info, int argc, char *argv[])
281 {
282         fstring srv_name;
283         fstring station;
284         char *printer_name;
285         POLICY_HND hnd;
286
287         BOOL res = True;
288
289         if (argc < 1)
290         {
291                 report(out_hnd, "spoolopen <printer name>\n");
292                 return NT_STATUS_INVALID_PARAMETER;
293         }
294
295         printer_name = argv[1];
296
297         fstrcpy(station, "\\\\");
298         fstrcat(station, info->myhostname);
299         strupper(station);
300
301         fstrcpy(srv_name, "\\\\");
302         fstrcat(srv_name, info->dest_host);
303         strupper(srv_name);
304
305         if (!strnequal("\\\\", printer_name, 2))
306         {
307                 fstrcat(srv_name, "\\");
308                 fstrcat(srv_name, printer_name);
309                 printer_name = srv_name;
310         }
311
312         DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
313                 printer_name, station, usr_creds->ntc.user_name));
314
315         res = res ? spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS,
316                                 station, "Administrator", &hnd) : False;
317
318         res = res ? spoolss_closeprinter(&hnd) : False;
319
320         if (res)
321         {
322                 DEBUG(5,("cmd_spoolss_open_printer_ex: query succeeded\n"));
323                 report(out_hnd, "OK\n");
324                 return NT_STATUS_NOPROBLEMO;
325         }
326         DEBUG(5,("cmd_spoolss_open_printer_ex: query failed\n"));
327         return NT_STATUS_UNSUCCESSFUL;
328 }
329
330 /****************************************************************************
331 nt spoolss query
332 ****************************************************************************/
333 uint32 cmd_spoolss_getprinterdata(struct client_info *info, int argc, char *argv[])
334 {
335         fstring srv_name;
336         fstring station;
337         char *printer_name;
338         char *value_name;
339
340         NEW_BUFFER ctr;
341         uint32 status;
342         uint32 type = 1;
343
344         if (argc < 2) {
345                 report(out_hnd, "spoolgetdata <printer name> <value name>\n");
346                 return NT_STATUS_INVALID_PARAMETER;
347         }
348
349         printer_name = argv[1];
350         value_name = argv[2];
351
352         fstrcpy(station, "\\\\");
353         fstrcat(station, info->myhostname);
354         strupper(station);
355
356         fstrcpy(srv_name, "\\\\");
357         fstrcat(srv_name, info->dest_host);
358         strupper(srv_name);
359
360         if (!strnequal("\\\\", printer_name, 2))
361         {
362                 fstrcat(srv_name, "\\");
363                 fstrcat(srv_name, printer_name);
364                 printer_name = srv_name;
365         }
366
367         DEBUG(4,("spoolgetdata - printer: %s station: %s value: %s\n",
368                                 printer_name, station, value_name));
369
370         status = msrpc_spoolss_getprinterdata( printer_name, station,
371                                 /* "Administrateur", */
372                                 usr_creds->ntc.user_name,
373                                 value_name, &type,
374                                 &ctr, NULL);
375
376         if (status == NT_STATUS_NOPROBLEMO)
377         {
378                 DEBUG(5,("cmd_spoolss_getprinterdata: query succeeded\n"));
379         }
380         else
381         {
382                 report(out_hnd, "FAILED\n");
383         }
384
385         return status;
386 }
387
388 /****************************************************************************
389 nt spoolss query
390 ****************************************************************************/
391 uint32 cmd_spoolss_getprinterdriver(struct client_info *info, int argc, char *argv[])
392 {
393         PRINTER_DRIVER_CTR ctr;
394         fstring srv_name;
395         fstring station;
396         char *printer_name;
397         fstring environment;
398         uint32 level;
399
400         if (argc < 1) {
401                 report(out_hnd, "spoolgetprinterdriver <printer name>\n");
402                 return NT_STATUS_INVALID_PARAMETER;
403         }
404
405         printer_name = argv[1];
406
407         fstrcpy(station, "\\\\");
408         fstrcat(station, info->myhostname);
409         strupper(station);
410
411         fstrcpy(srv_name, "\\\\");
412         fstrcat(srv_name, info->dest_host);
413         strupper(srv_name);
414
415         if (!strnequal("\\\\", printer_name, 2))
416         {
417                 fstrcat(srv_name, "\\");
418                 fstrcat(srv_name, printer_name);
419                 printer_name = srv_name;
420         }
421
422         fstrcpy(environment, "Windows NT x86");
423         level=3;
424
425         if (msrpc_spoolss_getprinterdriver(printer_name, environment, level, station, "Administrator", ctr))
426                 DEBUG(5,("cmd_spoolss_getprinterdriver: query succeeded\n"));
427         else
428                 report(out_hnd, "FAILED\n");
429
430         return NT_STATUS_NOPROBLEMO;
431 }
432
433 /****************************************************************************
434 nt spoolss query
435 ****************************************************************************/
436 uint32 cmd_spoolss_enumprinterdrivers(struct client_info *info, int argc, char *argv[])
437 {
438         PRINTER_DRIVER_CTR ctr;
439         fstring srv_name;
440         fstring environment;
441         uint32 level;
442
443         fstrcpy(srv_name, "\\\\");
444         fstrcat(srv_name, info->dest_host);
445         strupper(srv_name);
446
447         fstrcpy(environment, "Windows NT x86");
448         level=3;
449
450         if (msrpc_spoolss_enumprinterdrivers(srv_name, environment, level, ctr))
451                 DEBUG(5,("cmd_spoolss_enumprinterdrivers: query succeeded\n"));
452         else
453                 report(out_hnd, "FAILED\n");
454
455         return NT_STATUS_NOPROBLEMO;
456 }
457
458 /****************************************************************************
459 nt spoolss query
460 ****************************************************************************/
461 uint32 cmd_spoolss_getprinterdriverdir(struct client_info *info, int argc, char *argv[])
462 {
463         DRIVER_DIRECTORY_CTR ctr;
464         int i;
465
466         uint32 level = 1;
467
468         fstring srv_name;
469         fstring env;
470
471         fstrcpy(srv_name, "\\\\");
472         fstrcat(srv_name, info->dest_host);
473         strupper(srv_name);
474
475         if (argc < 1) {
476                 report(out_hnd, "spoolgetprinterdriverdir <arch>\n");
477                 return NT_STATUS_NOPROBLEMO;
478         }
479
480         fstrcpy(env, argv[1]);
481
482         for (i=2; i<=argc; i++) {
483                 fstrcat(env, " ");
484                 fstrcat(env, argv[i]);
485         }
486
487         if (msrpc_spoolss_getprinterdriverdir(srv_name, env, level, ctr))
488                 DEBUG(5,("cmd_spoolss_getprinterdriverdir: query succeeded\n"));
489         else
490                 report(out_hnd, "FAILED\n");
491
492         return NT_STATUS_NOPROBLEMO;
493 }
494
495 /********************************************************************************
496  send an AddPrinterEx() request
497 ********************************************************************************/
498 uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[])
499 {
500         fstring         srv_name, 
501                         printer_name, 
502                         driver_name,
503                         port_name;
504         POLICY_HND hnd;
505         PRINTER_INFO_2  print_info_2;
506         PORT_INFO_1     *port_info_1 = NULL;
507         NEW_BUFFER      buffer;
508         uint32          status,
509                         needed,
510                         returned;
511         uint32          i;
512         fstring         srv_port_name;
513         BOOL            valid_port = False;
514         TALLOC_CTX      *mem_ctx = NULL;
515
516         fstrcpy(srv_name, "\\\\");
517         fstrcat(srv_name, info->dest_host);
518         strupper(srv_name);
519
520         /* check (and copy) the command line arguments */
521         if (argc < 3) {
522                 report(out_hnd, "spooladdprinterex <name> <driver> <port>\n");
523                 return NT_STATUS_NOPROBLEMO;
524         }
525         else
526         {
527                 fstrcpy(printer_name, argv[1]);
528                 fstrcpy(driver_name, argv[2]);
529                 fstrcpy(port_name, argv[3]);
530         }
531         
532         /* Verify that the specified port is ok; spoolss_enum_ports() should 
533            be a level 1 since all we need is the name */
534         if ((mem_ctx=talloc_init()) == NULL)
535         {
536                 DEBUG(0, ("cmd_spoolss_addprinterex: talloc_init() failed!\n"));
537                 return NT_STATUS_INVALID_PARAMETER;
538         }
539         init_buffer (&buffer, 0, mem_ctx);
540         
541         /* send a NULL buffer first */
542         status=spoolss_enum_ports(srv_name, 1, &buffer, 0, 
543                                      &needed, &returned);
544         
545         /* send the right amount of space this time */
546         if (status==ERROR_INSUFFICIENT_BUFFER) {
547                 init_buffer(&buffer, needed, mem_ctx);
548                 status=spoolss_enum_ports(srv_name, 1, &buffer, 
549                                           needed, &needed, &returned);
550                                           
551                 /* if the call succeeded, then decode the buffer into 
552                    an PRINTER_INFO_1 structre */
553                 if (status == NT_STATUS_NO_PROBLEMO)
554                 {
555                         decode_port_info_1(&buffer, returned, &port_info_1);
556                 }
557                 else
558                 {
559                         report (out_hnd, "cmd_spoolss_addprinterex: FAILED to enumerate ports\n");
560                         return NT_STATUS_NOPROBLEMO;
561                 }
562                                         
563         }
564         
565         /*
566          * now we have an array of port names and we can interate
567          * through it to verify port_name before actually attempting 
568          * to add the printer on the server.
569          */
570         for (i=0; i<returned; i++)
571         {
572                 /* compare port_info_1[i].port_name to the port_name specified */
573                 unistr_to_ascii(srv_port_name, port_info_1[i].port_name.buffer, 
574                                 sizeof(srv_port_name)-1);
575                 if (strequal(srv_port_name, port_name))
576                 {
577                         valid_port = True;
578                         break;
579                 }
580         }
581         if (!valid_port)
582         {
583                 report (out_hnd, "cmd_spoolss_addprinterex: Invalid port specified!\n");
584                 return NT_STATUS_NOPROBLEMO;
585         }
586         
587          
588         /*
589          * Need to build the PRINTER_INFO_2 struct here.
590          * I think it would be better only to deal with a PRINTER_INFO_2
591          * and the abstract the creation of a SPOOL_PRINTER_INFO_LEVEL_2
592          * from that rather than dealing with the struct passed dircetly 
593          * on the wire.  We don't need the extra *_ptr fields, etc... 
594          * here anyways.  --jerry
595          */
596         init_unistr( &print_info_2.servername,  srv_name);
597         init_unistr( &print_info_2.printername, printer_name);
598         init_unistr( &print_info_2.sharename,   printer_name);
599         init_unistr( &print_info_2.portname,    port_name);
600         init_unistr( &print_info_2.drivername,  driver_name);
601         init_unistr( &print_info_2.comment,     "Created by rpcclient");
602         init_unistr( &print_info_2.location,    "");
603         init_unistr (&print_info_2.sepfile,     "");
604         init_unistr( &print_info_2.printprocessor, "winprint");
605         init_unistr( &print_info_2.datatype,    "RAW");
606         init_unistr( &print_info_2.parameters,  "");
607         print_info_2.devmode = NULL;
608         print_info_2.secdesc = NULL;
609         print_info_2.attributes         = 0;
610         print_info_2.priority           = 0;
611         print_info_2.defaultpriority    = 0;
612         print_info_2.starttime          = 0;
613         print_info_2.untiltime          = 0;
614         print_info_2.status             = 0;
615         print_info_2.cjobs              = 0;
616         print_info_2.averageppm         = 0;
617
618
619         /* if successful, spoolss_addprinterex() should return True and hnd 
620            should be a valid handle to an open printer */
621         if (spoolss_addprinterex(&hnd, &print_info_2))
622         {
623                 if (!spoolss_closeprinter( &hnd ))
624                 {
625                         report (out_hnd, "cmd_spoolss_addprinterex: spoolss_closeprinter FAILED!\n");
626                 }
627         }
628         else
629         {
630                 report (out_hnd, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED!\n");
631         }
632
633         
634         return NT_STATUS_NOPROBLEMO;
635 }
636         
637 /********************************************************************************
638  send an AddPrinterDriver() request
639 ********************************************************************************/
640 uint32 cmd_spoolss_addprinterdriver(struct client_info *info, int argc, char *argv[])
641 {
642
643         return NT_STATUS_NOPROBLEMO;
644 }