a312bc8889efd2be74b587fbf65979ff51906943
[kai/samba.git] / source3 / rpcclient / cmd_spoolss.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2
4    RPC pipe client
5
6    Copyright (C) Tim Potter                        2000
7    Copyright (C) Andrew Tridgell              1992-1999
8    Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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
27 extern int DEBUGLEVEL;
28
29 extern pstring server;
30 extern pstring global_myname;
31 extern pstring username, password;
32 extern pstring workgroup;
33
34 /****************************************************************************
35  display sec_ace structure
36  ****************************************************************************/
37 static void display_sec_ace(SEC_ACE *ace)
38 {
39         fstring sid_str;
40
41         sid_to_string(sid_str, &ace->sid);
42         printf("\t\tSID: %s\n", sid_str);
43
44         printf("\t\ttype:[%d], flags:[0x%02x], mask:[0x%08x]\n", 
45                ace->type, ace->flags, ace->info.mask);
46 }
47
48 /****************************************************************************
49  display sec_acl structure
50  ****************************************************************************/
51 static void display_sec_acl(SEC_ACL *acl)
52 {
53         if (acl->size != 0 && acl->num_aces != 0) {
54                 int i;
55
56                 printf("\t\tRevision:[%d]\n", acl->revision);
57                 for (i = 0; i < acl->num_aces; i++) {
58                         display_sec_ace(&acl->ace[i]);
59                 }
60         }
61 }
62
63 /****************************************************************************
64  display sec_desc structure
65  ****************************************************************************/
66 static void display_sec_desc(SEC_DESC *sec)
67 {
68         fstring sid_str;
69
70         printf("\tRevision:[%d]\n", sec->revision);
71
72         if (sec->off_owner_sid) {
73                 sid_to_string(sid_str, sec->owner_sid);
74                 printf("\tOwner SID: %s\n", sid_str);
75         }
76
77         if (sec->off_grp_sid) {
78                 sid_to_string(sid_str, sec->grp_sid);
79                 printf("\tGroup SID: %s\n", sid_str);
80         }
81
82         if (sec->off_sacl) display_sec_acl(sec->sacl);
83         if (sec->off_dacl) display_sec_acl(sec->dacl);
84 }
85
86 /****************************************************************************
87 printer info level 0 display function
88 ****************************************************************************/
89 static void display_print_info_0(PRINTER_INFO_0 *i1)
90 {
91         fstring name;
92         fstring the_server;
93
94         unistr_to_ascii(name, i1->printername.buffer, sizeof(name) - 1);
95         unistr_to_ascii(server, i1->servername.buffer, sizeof(the_server) - 1);
96
97         printf("\tprintername:[%s]\n", name);
98         printf("\tservername:[%s]\n", the_server);
99         printf("\tcjobs:[0x%x]\n", i1->cjobs);
100         printf("\ttotal_jobs:[0x%x]\n", i1->total_jobs);
101         
102         printf("\t:date: [%d]-[%d]-[%d] (%d)\n", i1->year, i1->month, 
103                i1->day, i1->dayofweek);
104         printf("\t:time: [%d]-[%d]-[%d]-[%d]\n", i1->hour, i1->minute, 
105                i1->second, i1->milliseconds);
106         
107         printf("\tglobal_counter:[0x%x]\n", i1->global_counter);
108         printf("\ttotal_pages:[0x%x]\n", i1->total_pages);
109         
110         printf("\tmajorversion:[0x%x]\n", i1->major_version);
111         printf("\tbuildversion:[0x%x]\n", i1->build_version);
112         
113         printf("\tunknown7:[0x%x]\n", i1->unknown7);
114         printf("\tunknown8:[0x%x]\n", i1->unknown8);
115         printf("\tunknown9:[0x%x]\n", i1->unknown9);
116         printf("\tsession_counter:[0x%x]\n", i1->session_counter);
117         printf("\tunknown11:[0x%x]\n", i1->unknown11);
118         printf("\tprinter_errors:[0x%x]\n", i1->printer_errors);
119         printf("\tunknown13:[0x%x]\n", i1->unknown13);
120         printf("\tunknown14:[0x%x]\n", i1->unknown14);
121         printf("\tunknown15:[0x%x]\n", i1->unknown15);
122         printf("\tunknown16:[0x%x]\n", i1->unknown16);
123         printf("\tchange_id:[0x%x]\n", i1->change_id);
124         printf("\tunknown18:[0x%x]\n", i1->unknown18);
125         printf("\tstatus:[0x%x]\n", i1->status);
126         printf("\tunknown20:[0x%x]\n", i1->unknown20);
127         printf("\tc_setprinter:[0x%x]\n", i1->c_setprinter);
128         printf("\tunknown22:[0x%x]\n", i1->unknown22);
129         printf("\tunknown23:[0x%x]\n", i1->unknown23);
130         printf("\tunknown24:[0x%x]\n", i1->unknown24);
131         printf("\tunknown25:[0x%x]\n", i1->unknown25);
132         printf("\tunknown26:[0x%x]\n", i1->unknown26);
133         printf("\tunknown27:[0x%x]\n", i1->unknown27);
134         printf("\tunknown28:[0x%x]\n", i1->unknown28);
135         printf("\tunknown29:[0x%x]\n", i1->unknown29);
136 }
137
138 /****************************************************************************
139 printer info level 1 display function
140 ****************************************************************************/
141 static void display_print_info_1(PRINTER_INFO_1 *i1)
142 {
143         fstring desc;
144         fstring name;
145         fstring comm;
146
147         unistr_to_ascii(desc, i1->description.buffer, sizeof(desc) - 1);
148         unistr_to_ascii(name, i1->name       .buffer, sizeof(name) - 1);
149         unistr_to_ascii(comm, i1->comment    .buffer, sizeof(comm) - 1);
150
151         printf("\tflags:[0x%x]\n", i1->flags);
152         printf("\tname:[%s]\n", name);
153         printf("\tdescription:[%s]\n", desc);
154         printf("\tcomment:[%s]\n\n", comm);
155 }
156
157 /****************************************************************************
158 printer info level 2 display function
159 ****************************************************************************/
160 static void display_print_info_2(PRINTER_INFO_2 *i2)
161 {
162         fstring servername;
163         fstring printername;
164         fstring sharename;
165         fstring portname;
166         fstring drivername;
167         fstring comment;
168         fstring location;
169         fstring sepfile;
170         fstring printprocessor;
171         fstring datatype;
172         fstring parameters;
173         
174         unistr_to_ascii(servername, i2->servername.buffer, 
175                         sizeof(servername) - 1);
176         unistr_to_ascii(printername, i2->printername.buffer, 
177                         sizeof(printername) - 1);
178         unistr_to_ascii(sharename, i2->sharename.buffer,
179                         sizeof(sharename) - 1);
180         unistr_to_ascii(portname, i2->portname.buffer, sizeof(portname) - 1);
181         unistr_to_ascii(drivername, i2->drivername.buffer, 
182                         sizeof(drivername) - 1);
183         unistr_to_ascii(comment, i2->comment.buffer, sizeof(comment) - 1);
184         unistr_to_ascii(location, i2->location.buffer, sizeof(location) - 1);
185         unistr_to_ascii(sepfile, i2->sepfile.buffer, sizeof(sepfile) - 1);
186         unistr_to_ascii(printprocessor, i2->printprocessor.buffer, 
187                         sizeof(printprocessor) - 1);
188         unistr_to_ascii(datatype, i2->datatype.buffer, sizeof(datatype) - 1);
189         unistr_to_ascii(parameters, i2->parameters.buffer, 
190                         sizeof(parameters) - 1);
191
192         printf("\tservername:[%s]\n", servername);
193         printf("\tprintername:[%s]\n", printername);
194         printf("\tsharename:[%s]\n", sharename);
195         printf("\tportname:[%s]\n", portname);
196         printf("\tdrivername:[%s]\n", drivername);
197         printf("\tcomment:[%s]\n", comment);
198         printf("\tlocation:[%s]\n", location);
199         printf("\tsepfile:[%s]\n", sepfile);
200         printf("\tprintprocessor:[%s]\n", printprocessor);
201         printf("\tdatatype:[%s]\n", datatype);
202         printf("\tparameters:[%s]\n", parameters);
203         printf("\tattributes:[0x%x]\n", i2->attributes);
204         printf("\tpriority:[0x%x]\n", i2->priority);
205         printf("\tdefaultpriority:[0x%x]\n", i2->defaultpriority);
206         printf("\tstarttime:[0x%x]\n", i2->starttime);
207         printf("\tuntiltime:[0x%x]\n", i2->untiltime);
208         printf("\tstatus:[0x%x]\n", i2->status);
209         printf("\tcjobs:[0x%x]\n", i2->cjobs);
210         printf("\taverageppm:[0x%x]\n", i2->averageppm);
211
212         if (i2->secdesc) display_sec_desc(i2->secdesc);
213 }
214
215 /****************************************************************************
216 printer info level 3 display function
217 ****************************************************************************/
218 static void display_print_info_3(PRINTER_INFO_3 *i3)
219 {
220         printf("\tflags:[0x%x]\n", i3->flags);
221
222         display_sec_desc(i3->secdesc);
223 }
224
225 /* Enumerate printers */
226
227 static uint32 cmd_spoolss_enum_printers(int argc, char **argv)
228 {
229         uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1;
230         struct cli_state cli;
231         struct ntuser_creds creds;
232         PRINTER_INFO_CTR ctr;
233         int returned;
234         
235         if (argc > 2) {
236                 printf("Usage: enumprinters\n");
237                 return NT_STATUS_NOPROBLEMO;
238         }
239
240         if (argc == 2) {
241                 info_level = atoi(argv[1]);
242         }
243
244         /* Initialise RPC connection */
245
246         ZERO_STRUCT(cli);
247         init_rpcclient_creds(&creds);
248
249         if (cli_spoolss_initialise(&cli, server, &creds) == NULL) {
250                 goto done;
251         }
252
253         /* Enumerate printers */
254
255         ZERO_STRUCT(ctr);
256
257         result = cli_spoolss_enum_printers(&cli, PRINTER_ENUM_LOCAL, 
258                                            info_level, &returned, &ctr);
259
260         if (result == NT_STATUS_NOPROBLEMO) {
261                 switch(info_level) {
262                 case 0:
263                         display_print_info_0(ctr.printers_0);
264                         break;
265                 case 1:
266                         display_print_info_1(ctr.printers_1);
267                         break;
268                 case 2:
269                         display_print_info_2(ctr.printers_2);
270                         break;
271                 case 3:
272                         display_print_info_3(ctr.printers_3);
273                         break;
274                 default:
275                         printf("unknown info level %d\n", info_level);
276                         break;
277                 }
278         }
279
280  done:
281         cli_spoolss_shutdown(&cli);
282
283         return result;
284 }
285
286 /****************************************************************************
287 port info level 1 display function
288 ****************************************************************************/
289 static void display_port_info_1(PORT_INFO_1 *i1)
290 {
291         fstring buffer;
292         
293         unistr_to_ascii(buffer, i1->port_name.buffer, sizeof(buffer)-1);
294         printf("\tPort Name:\t[%s]\n", buffer);
295 }
296
297 /****************************************************************************
298 port info level 2 display function
299 ****************************************************************************/
300 static void display_port_info_2(PORT_INFO_2 *i2)
301 {
302         fstring buffer;
303         
304         unistr_to_ascii(buffer, i2->port_name.buffer, sizeof(buffer) - 1);
305         printf("\tPort Name:\t[%s]\n", buffer);
306         unistr_to_ascii(buffer, i2->monitor_name.buffer, sizeof(buffer) - 1);
307         printf("\tMonitor Name:\t[%s]\n", buffer);
308         unistr_to_ascii(buffer, i2->description.buffer, sizeof(buffer) - 1);
309         printf("\tDescription:\t[%s]\n", buffer);
310         printf("\tPort Type:\t[%d]\n", i2->port_type);
311         printf("\tReserved:\t[%d]\n", i2->reserved);
312         printf("\n");
313 }
314
315 /* Enumerate ports */
316
317 static uint32 cmd_spoolss_enum_ports(int argc, char **argv)
318 {
319         uint32 result = NT_STATUS_UNSUCCESSFUL, info_level = 1;
320         struct cli_state cli;
321         struct ntuser_creds creds;
322         PORT_INFO_CTR ctr;
323         int returned;
324         
325         if (argc == 1 || argc < 2) {
326                 printf("Usage: enumports [level]\n");
327                 return NT_STATUS_NOPROBLEMO;
328         }
329
330         if (argc == 2) {
331                 info_level = atoi(argv[1]);
332         }
333
334         /* Initialise RPC connection */
335
336         ZERO_STRUCT(cli);
337         init_rpcclient_creds(&creds);
338
339         if (cli_spoolss_initialise(&cli, server, &creds) == NULL) {
340                 goto done;
341         }
342
343         /* Enumerate printers */
344
345         ZERO_STRUCT(ctr);
346
347         result = cli_spoolss_enum_ports(&cli, info_level, &returned, &ctr);
348
349         if (result == NT_STATUS_NOPROBLEMO) {
350                 int i;
351
352                 for (i = 0; i < returned; i++) {
353                         switch (info_level) {
354                         case 1:
355                                 display_port_info_1(&ctr.port.info_1[i]);
356                         break;
357                         case 2:
358                                 display_port_info_2(&ctr.port.info_2[i]);
359                                 break;
360                         default:
361                                 printf("unknown info level %d\n", info_level);
362                                 break;
363                         }
364                 }
365         }
366
367  done:
368         cli_spoolss_shutdown(&cli);
369
370         return result;
371 }
372
373 /* Get printer information */
374
375 static uint32 cmd_spoolss_getprinter(int argc, char **argv)
376 {
377         struct cli_state cli;
378         POLICY_HND pol;
379         uint32 result, info_level = 1;
380         BOOL opened_hnd = False;
381         struct ntuser_creds creds;
382         PRINTER_INFO_CTR ctr;
383         fstring printer_name, station_name;
384
385         if (argc == 1 || argc > 3) {
386                 printf("Usage: %s printername [level]\n", argv[0]);
387                 return NT_STATUS_NOPROBLEMO;
388         }
389
390         /* Initialise RPC connection */
391
392         ZERO_STRUCT(cli);
393         init_rpcclient_creds(&creds);
394
395         if (cli_spoolss_initialise(&cli, server, &creds) == NULL) {
396                 goto done;
397         }
398
399         /* Open a printer handle */
400
401         if (argc == 3) {
402                 info_level = atoi(argv[2]);
403         }
404
405         slprintf(printer_name, sizeof(fstring), "\\\\%s\\%s",
406                  server, argv[1]);
407
408         slprintf(station_name, sizeof(fstring), "\\\\%s", global_myname);
409
410         if ((result = cli_spoolss_open_printer_ex(
411                 &cli, printer_name, "", MAXIMUM_ALLOWED_ACCESS, station_name,
412                 username, &pol)) != NT_STATUS_NOPROBLEMO) {
413                 goto done;
414         }
415
416         opened_hnd = True;
417
418         /* Get printer info */
419
420         if ((result = cli_spoolss_getprinter(&cli, &pol, info_level, &ctr))
421             != NT_STATUS_NOPROBLEMO) {
422                 goto done;
423         }
424
425         /* Display printer info */
426
427         switch (info_level) {
428         case 0: 
429                 display_print_info_0(ctr.printers_0);
430                 break;
431         case 1:
432                 display_print_info_1(ctr.printers_1);
433                 break;
434         case 2:
435                 display_print_info_2(ctr.printers_2);
436                 break;
437         case 3:
438                 display_print_info_3(ctr.printers_3);
439                 break;
440         default:
441                 printf("unknown info level %d\n", info_level);
442                 break;
443         }
444
445  done: 
446         if (opened_hnd) cli_spoolss_closeprinter(&cli, &pol);
447
448         cli_spoolss_shutdown(&cli);
449
450         return result;
451 }
452
453 /* List of commands exported by this module */
454
455 struct cmd_set spoolss_commands[] = {
456
457         { "enumprinters", cmd_spoolss_enum_printers, "Enumerate printers" },
458         { "enumports", cmd_spoolss_enum_ports, "Enumerate printer ports" },
459         { "getprinter", cmd_spoolss_getprinter, "Get printer info" },
460
461         { NULL, NULL, NULL }
462 };