some initial code for AddPrinterEx() project. Most is ifdef'd out
[samba.git] / source / 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         
106         uint32 level = 2;
107
108         fstring srv_name;
109         fstrcpy(srv_name, "\\\\");
110         fstrcat(srv_name, info->dest_host);
111         strupper(srv_name);
112         
113         if (msrpc_spoolss_enum_ports(srv_name, level, &ctr))
114                 DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
115         else
116                 report(out_hnd, "FAILED\n");
117                 
118         return NT_STATUS_NOPROBLEMO;
119 }
120
121 /****************************************************************************
122 nt spoolss query
123 ****************************************************************************/
124 uint32 cmd_spoolss_enum_printerdata(struct client_info *info, int argc, char *argv[])
125 {
126         fstring srv_name;
127         fstring station;
128         char *printer_name;
129
130         if (argc < 1) {
131                 report(out_hnd, "spoolenumdata <printer name>\n");
132                 return NT_STATUS_INVALID_PARAMETER;
133         }
134
135         printer_name = argv[1];
136
137         fstrcpy(station, "\\\\");
138         fstrcat(station, info->myhostname);
139         strupper(station);
140
141         fstrcpy(srv_name, "\\\\");
142         fstrcat(srv_name, info->dest_host);
143         strupper(srv_name);
144
145         if (!strnequal("\\\\", printer_name, 2))
146         {
147                 fstrcat(srv_name, "\\");
148                 fstrcat(srv_name, printer_name);
149                 printer_name = srv_name;
150         }
151
152         DEBUG(4,("spoolopen - printer: %s station: %s user: %s\n", printer_name, station, usr_creds->ntc.user_name));
153
154         if (msrpc_spoolss_enum_printerdata( printer_name, station,
155                                 usr_creds->ntc.user_name))
156         {
157                 DEBUG(5,("cmd_spoolss_enum_printerdata: query succeeded\n"));
158                 return NT_STATUS_NOPROBLEMO;
159         }
160         report(out_hnd, "FAILED\n");
161         return NT_STATUS_UNSUCCESSFUL;
162 }
163
164 /****************************************************************************
165 nt spoolss query
166 ****************************************************************************/
167 uint32 cmd_spoolss_getprinter(struct client_info *info, int argc, char *argv[])
168 {
169         PRINTER_INFO_CTR ctr;
170         fstring srv_name;
171         fstring station;
172         char *printer_name;
173         uint32 level;
174
175         if (argc < 1) {
176                 report(out_hnd, "spoolgetprinter <printer name>\n");
177                 return NT_STATUS_INVALID_PARAMETER;
178         }
179
180         printer_name = argv[1];
181
182         fstrcpy(station, "\\\\");
183         fstrcat(station, info->myhostname);
184         strupper(station);
185
186         fstrcpy(srv_name, "\\\\");
187         fstrcat(srv_name, info->dest_host);
188         strupper(srv_name);
189
190         if (!strnequal("\\\\", printer_name, 2))
191         {
192                 fstrcat(srv_name, "\\");
193                 fstrcat(srv_name, printer_name);
194                 printer_name = srv_name;
195         }
196
197         if (argc < 3)
198                 level=2;
199         else
200                 level = atoi(argv[2]);
201
202         if (msrpc_spoolss_getprinter(printer_name, level, station, "Administrator", ctr))
203                 DEBUG(5,("cmd_spoolss_getprinter: query succeeded\n"));
204         else
205                 report(out_hnd, "FAILED\n");
206
207         return NT_STATUS_NOPROBLEMO;
208 }
209
210
211 static void display_spool_job_info_ctr( const char* printer_name,
212                                 const char* station,
213                                 uint32 level,
214                                 uint32 num, void *const *const ctr)
215 {
216         display_job_info_ctr(out_hnd, ACTION_HEADER   , level, num, ctr);
217         display_job_info_ctr(out_hnd, ACTION_ENUMERATE, level, num, ctr);
218         display_job_info_ctr(out_hnd, ACTION_FOOTER   , level, num, ctr);
219 }
220
221 /****************************************************************************
222 nt spoolss query
223 ****************************************************************************/
224 uint32 cmd_spoolss_enum_jobs(struct client_info *info, int argc, char *argv[])
225 {
226         fstring srv_name;
227         fstring station;
228         char *printer_name;
229
230         void **ctr = NULL;
231         uint32 level = 1;
232
233         if (argc < 1) {
234                 report(out_hnd, "spooljobs <printer name>\n");
235                 return NT_STATUS_INVALID_PARAMETER;
236         }
237
238         printer_name = argv[1];
239
240         fstrcpy(station, "\\\\");
241         fstrcat(station, info->myhostname);
242         strupper(station);
243
244         fstrcpy(srv_name, "\\\\");
245         fstrcat(srv_name, info->dest_host);
246         strupper(srv_name);
247
248         if (!strnequal("\\\\", printer_name, 2))
249         {
250                 fstrcat(srv_name, "\\");
251                 fstrcat(srv_name, printer_name);
252                 printer_name = srv_name;
253         }
254
255         DEBUG(4,("spoolopen - printer: %s station: %s user: %s\n", printer_name, 
256                   station, usr_creds->ntc.user_name));
257
258         if (msrpc_spoolss_enum_jobs( printer_name, station,
259                                 usr_creds->ntc.user_name,
260                                 level, &ctr, display_spool_job_info_ctr))
261         {
262                 DEBUG(5,("cmd_spoolss_enum_jobs: query succeeded\n"));
263                 return NT_STATUS_NOPROBLEMO;
264         }
265         report(out_hnd, "FAILED\n");
266         return NT_STATUS_UNSUCCESSFUL;
267 }
268
269 /****************************************************************************
270 nt spoolss query
271 ****************************************************************************/
272 uint32 cmd_spoolss_open_printer_ex(struct client_info *info, int argc, char *argv[])
273 {
274         fstring srv_name;
275         fstring station;
276         char *printer_name;
277         POLICY_HND hnd;
278
279         BOOL res = True;
280
281         if (argc < 1)
282         {
283                 report(out_hnd, "spoolopen <printer name>\n");
284                 return NT_STATUS_INVALID_PARAMETER;
285         }
286
287         printer_name = argv[1];
288
289         fstrcpy(station, "\\\\");
290         fstrcat(station, info->myhostname);
291         strupper(station);
292
293         fstrcpy(srv_name, "\\\\");
294         fstrcat(srv_name, info->dest_host);
295         strupper(srv_name);
296
297         if (!strnequal("\\\\", printer_name, 2))
298         {
299                 fstrcat(srv_name, "\\");
300                 fstrcat(srv_name, printer_name);
301                 printer_name = srv_name;
302         }
303
304         DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
305                 printer_name, station, usr_creds->ntc.user_name));
306
307         res = res ? spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS,
308                                 station, "Administrator", &hnd) : False;
309
310         res = res ? spoolss_closeprinter(&hnd) : False;
311
312         if (res)
313         {
314                 DEBUG(5,("cmd_spoolss_open_printer_ex: query succeeded\n"));
315                 report(out_hnd, "OK\n");
316                 return NT_STATUS_NOPROBLEMO;
317         }
318         DEBUG(5,("cmd_spoolss_open_printer_ex: query failed\n"));
319         return NT_STATUS_UNSUCCESSFUL;
320 }
321
322 /****************************************************************************
323 nt spoolss query
324 ****************************************************************************/
325 uint32 cmd_spoolss_getprinterdata(struct client_info *info, int argc, char *argv[])
326 {
327         fstring srv_name;
328         fstring station;
329         char *printer_name;
330         char *value_name;
331
332         NEW_BUFFER ctr;
333         uint32 status;
334         uint32 type = 1;
335
336         if (argc < 2) {
337                 report(out_hnd, "spoolgetdata <printer name> <value name>\n");
338                 return NT_STATUS_INVALID_PARAMETER;
339         }
340
341         printer_name = argv[1];
342         value_name = argv[2];
343
344         fstrcpy(station, "\\\\");
345         fstrcat(station, info->myhostname);
346         strupper(station);
347
348         fstrcpy(srv_name, "\\\\");
349         fstrcat(srv_name, info->dest_host);
350         strupper(srv_name);
351
352         if (!strnequal("\\\\", printer_name, 2))
353         {
354                 fstrcat(srv_name, "\\");
355                 fstrcat(srv_name, printer_name);
356                 printer_name = srv_name;
357         }
358
359         DEBUG(4,("spoolgetdata - printer: %s station: %s value: %s\n",
360                                 printer_name, station, value_name));
361
362         status = msrpc_spoolss_getprinterdata( printer_name, station,
363                                 /* "Administrateur", */
364                                 usr_creds->ntc.user_name,
365                                 value_name, &type,
366                                 &ctr, NULL);
367
368         if (status == NT_STATUS_NOPROBLEMO)
369         {
370                 DEBUG(5,("cmd_spoolss_getprinterdata: query succeeded\n"));
371         }
372         else
373         {
374                 report(out_hnd, "FAILED\n");
375         }
376
377         return status;
378 }
379
380 /****************************************************************************
381 nt spoolss query
382 ****************************************************************************/
383 uint32 cmd_spoolss_getprinterdriver(struct client_info *info, int argc, char *argv[])
384 {
385         PRINTER_DRIVER_CTR ctr;
386         fstring srv_name;
387         fstring station;
388         char *printer_name;
389         fstring environment;
390         uint32 level;
391
392         if (argc < 1) {
393                 report(out_hnd, "spoolgetprinterdriver <printer name>\n");
394                 return NT_STATUS_INVALID_PARAMETER;
395         }
396
397         printer_name = argv[1];
398
399         fstrcpy(station, "\\\\");
400         fstrcat(station, info->myhostname);
401         strupper(station);
402
403         fstrcpy(srv_name, "\\\\");
404         fstrcat(srv_name, info->dest_host);
405         strupper(srv_name);
406
407         if (!strnequal("\\\\", printer_name, 2))
408         {
409                 fstrcat(srv_name, "\\");
410                 fstrcat(srv_name, printer_name);
411                 printer_name = srv_name;
412         }
413
414         fstrcpy(environment, "Windows NT x86");
415         level=3;
416
417         if (msrpc_spoolss_getprinterdriver(printer_name, environment, level, station, "Administrator", ctr))
418                 DEBUG(5,("cmd_spoolss_getprinterdriver: query succeeded\n"));
419         else
420                 report(out_hnd, "FAILED\n");
421
422         return NT_STATUS_NOPROBLEMO;
423 }
424
425 /****************************************************************************
426 nt spoolss query
427 ****************************************************************************/
428 uint32 cmd_spoolss_enumprinterdrivers(struct client_info *info, int argc, char *argv[])
429 {
430         PRINTER_DRIVER_CTR ctr;
431         fstring srv_name;
432         fstring environment;
433         uint32 level;
434
435         fstrcpy(srv_name, "\\\\");
436         fstrcat(srv_name, info->dest_host);
437         strupper(srv_name);
438
439         fstrcpy(environment, "Windows NT x86");
440         level=3;
441
442         if (msrpc_spoolss_enumprinterdrivers(srv_name, environment, level, ctr))
443                 DEBUG(5,("cmd_spoolss_enumprinterdrivers: query succeeded\n"));
444         else
445                 report(out_hnd, "FAILED\n");
446
447         return NT_STATUS_NOPROBLEMO;
448 }
449
450 /****************************************************************************
451 nt spoolss query
452 ****************************************************************************/
453 uint32 cmd_spoolss_getprinterdriverdir(struct client_info *info, int argc, char *argv[])
454 {
455         DRIVER_DIRECTORY_CTR ctr;
456         int i;
457
458         uint32 level = 1;
459
460         fstring srv_name;
461         fstring env;
462
463         fstrcpy(srv_name, "\\\\");
464         fstrcat(srv_name, info->dest_host);
465         strupper(srv_name);
466
467         if (argc < 1) {
468                 report(out_hnd, "spoolgetprinterdriverdir <arch>\n");
469                 return NT_STATUS_NOPROBLEMO;
470         }
471
472         fstrcpy(env, argv[1]);
473
474         for (i=2; i<=argc; i++) {
475                 fstrcat(env, " ");
476                 fstrcat(env, argv[i]);
477         }
478
479         if (msrpc_spoolss_getprinterdriverdir(srv_name, env, level, ctr))
480                 DEBUG(5,("cmd_spoolss_getprinterdriverdir: query succeeded\n"));
481         else
482                 report(out_hnd, "FAILED\n");
483
484         return NT_STATUS_NOPROBLEMO;
485 }
486
487 /********************************************************************************
488  send an AddPrinterEx() request
489 ********************************************************************************/
490 uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[])
491 {
492 #if 0
493         PRINTER_INFO_CTR ctr;
494         uint32 level = 2;
495         fstring         srv_name, 
496                         printer_name, 
497                         driver_name,
498                         port_name;
499         POLICY_HND hnd;
500         PRINTER_INFO_2  print_info_2;
501         PORT_INFO_1     *port_info_1 = NULL;
502         NEW_BUFFER      buffer;
503         uint32          status,
504                         needed,
505                         returned;
506         uint32          i;
507         fstring         srv_port_name;
508         BOOL            valid_port = False;
509
510         fstrcpy(srv_name, "\\\\");
511         fstrcat(srv_name, info->dest_host);
512         strupper(srv_name);
513
514         /* check (and copy) the command line arguments */
515         if (argc < 2) {
516                 report(out_hnd, "spooladdprinterex <name> <driver>\n");
517                 return NT_STATUS_NOPROBLEMO;
518         }
519
520         fstrcpy(printer_name, argv[1]);
521         fstrcpy(driver_name, argv[2]);
522         fstrcpy(port_name, argv[3]);
523         
524         
525         /* Verify that the specified port is ok; spoolss_enum_ports() should 
526            be a level 1 since all we need is the name */
527         init_buffer (&buffer, 0);
528         
529         /* send a NULL buffer first */
530         status=spoolss_enum_ports(srv_name, 1, &buffer, 0, 
531                                      &needed, &returned);
532         
533         /* send the right amount of space this time */
534         if (status==ERROR_INSUFFICIENT_BUFFER) {
535                 init_buffer(&buffer, needed);
536                 status=spoolss_enum_ports(srv_name, 1, &buffer, 
537                                           needed, &needed, &returned);
538                                           
539                 /* if the call succeeded, then decode the buffer into 
540                    an PRINTER_INFO_1 structre */
541                 if (status == NT_STATUS_NO_PROBLEMO)
542                 {
543                         decode_port_info_1 (&buffer, returned, &port_info_1);
544                 }
545                 else
546                 {
547                         report (out_hnd, "cmd_spoolss_addprinterex: FAILED to enumerate ports\n"));
548                         return NT_STATUS_NOPROBLEMO;
549                 }
550                                         
551         }
552         
553         /*
554          * now we have an array of port names and we can interate
555          * through it to verify port_name before actually attempting 
556          * to add the printer on the server.
557          */
558         for (i=0; i<returned; i++)
559         {
560                 /* compare port_info_1[i].port_name to the port_name specified */
561                 unistr_to_ascii(srv_port_name, port_info_1[i].port_name, sizeof(srv_port_name)-1);
562                 if (strequal(srv_port_name, port_name))
563                 {
564                         valid_port = True;
565                         break;
566                 }
567         }
568         if (!valid_port)
569         {
570                 report (out_hnd, "cmd_spoolss_addprinterex: Invalid port specified!\n");
571                 return NT_STATUS_NOPROBLEMO;
572         }
573         
574          
575         /*
576          * Need to build the PRINTER_INFO_2 struct here 
577          */
578         ;;
579         
580         /* if successful, spoolss_addprinterex() should return True and hnd 
581            should be a valid handle to an open printer */
582         if (spoolss_addprinterex(&hnd, 2, &print_info_2))
583         {
584                 if (!spoolss_closeprinter( &hnd ))
585                 {
586                         report (out_hnd, "cmd_spoolss_addprinterex: spoolss_closeprinter FAILED!\n");
587                 }
588         }
589         else
590         {
591                 report (out_hnd, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED!\n");
592         }
593
594         
595 #endif          
596         return NT_STATUS_NOPROBLEMO;
597 }
598         
599