Fixed unitilized secdesc pointer which was causing spoolgetprinter
[Samba.git] / source / rpc_client / msrpc_spoolss.c
blob10582c01be7e754b8e4b56cb5d510d7b1ce67323
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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
25 #include "nterr.h"
26 #include "rpc_parse.h"
27 #include "rpc_client.h"
28 #include "rpcclient.h"
30 extern int DEBUGLEVEL;
32 #define DEBUG_TESTING
34 extern FILE* out_hnd;
36 extern struct user_creds *usr_creds;
38 /********************************************************************
39 initialize a spoolss NEW_BUFFER.
40 ********************************************************************/
41 static void init_buffer(NEW_BUFFER *buffer, uint32 size)
43 buffer->ptr = (size!=0)? 1:0;
44 buffer->size=size;
45 buffer->string_at_end=size;
46 prs_init(&buffer->prs, size, 4, MARSHALL);
47 buffer->struct_start = prs_offset(&buffer->prs);
50 static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned,
51 PRINTER_INFO_0 **info)
53 uint32 i;
54 PRINTER_INFO_0 *inf;
56 inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
58 buffer->prs.data_offset=0;
60 for (i=0; i<returned; i++) {
61 new_smb_io_printer_info_0("", buffer, &(inf[i]), 0);
64 *info=inf;
67 static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned,
68 PRINTER_INFO_1 **info)
70 uint32 i;
71 PRINTER_INFO_1 *inf;
73 inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1));
75 buffer->prs.data_offset=0;
77 for (i=0; i<returned; i++) {
78 new_smb_io_printer_info_1("", buffer, &(inf[i]), 0);
81 *info=inf;
84 static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned,
85 PRINTER_INFO_2 **info)
87 uint32 i;
88 PRINTER_INFO_2 *inf;
90 inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2));
92 buffer->prs.data_offset=0;
94 for (i=0; i<returned; i++) {
95 /* a little initialization as we go */
96 inf[i].secdesc = NULL;
97 new_smb_io_printer_info_2("", buffer, &(inf[i]), 0);
100 *info=inf;
103 static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned,
104 PRINTER_INFO_3 **info)
106 uint32 i;
107 PRINTER_INFO_3 *inf;
109 inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3));
111 buffer->prs.data_offset=0;
113 for (i=0; i<returned; i++) {
114 new_smb_io_printer_info_3("", buffer, &(inf[i]), 0);
117 *info=inf;
120 static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned,
121 DRIVER_INFO_1 **info)
123 uint32 i;
124 DRIVER_INFO_1 *inf;
126 inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1));
128 buffer->prs.data_offset=0;
130 for (i=0; i<returned; i++) {
131 new_smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
134 *info=inf;
137 static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned,
138 DRIVER_INFO_2 **info)
140 uint32 i;
141 DRIVER_INFO_2 *inf;
143 inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2));
145 buffer->prs.data_offset=0;
147 for (i=0; i<returned; i++) {
148 new_smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
151 *info=inf;
154 static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned,
155 DRIVER_INFO_3 **info)
157 uint32 i;
158 DRIVER_INFO_3 *inf;
160 inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3));
162 buffer->prs.data_offset=0;
164 for (i=0; i<returned; i++) {
165 new_smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
168 *info=inf;
171 static void decode_printerdriverdir_info_1(NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info)
173 /* DRIVER_DIRECTORY_1 *inf;
175 inf=(DRIVER_DIRECTORY_1 *)malloc(returned*sizeof(DRIVER_DIRECTORY_1));
177 prs_set_offset(&buffer->prs, 0);
179 new_smb_io_driverdir_1("", buffer, info, 0);
181 /* *info=inf;*/
186 /****************************************************************************
187 nt spoolss query
188 ****************************************************************************/
189 BOOL msrpc_spoolss_enum_printers(char* srv_name, uint32 flags,
190 uint32 level, PRINTER_INFO_CTR ctr)
192 uint32 status;
193 NEW_BUFFER buffer;
194 uint32 needed;
195 uint32 returned;
197 init_buffer(&buffer, 0);
199 /* send a NULL buffer first */
200 status=spoolss_enum_printers(flags, srv_name, level, &buffer, 0,
201 &needed, &returned);
203 if (status==ERROR_INSUFFICIENT_BUFFER) {
204 init_buffer(&buffer, needed);
205 status=spoolss_enum_printers(flags, srv_name, level, &buffer,
206 needed, &needed, &returned);
209 report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
211 if (status!=NT_STATUS_NO_PROBLEMO)
212 return False;
214 /* is there anything to process? */
215 if (returned != 0)
217 switch (level) {
218 case 1:
219 decode_printer_info_1(&buffer, returned, &(ctr.printers_1));
220 break;
221 case 2:
222 decode_printer_info_2(&buffer, returned, &(ctr.printers_2));
223 break;
224 case 3:
225 decode_printer_info_3(&buffer, returned, &(ctr.printers_3));
226 break;
229 display_printer_info_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
230 display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
231 display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
234 return True;
237 /****************************************************************************
238 nt spoolss query
239 ****************************************************************************/
240 uint32 msrpc_spoolss_getprinterdata( const char* printer_name,
241 const char* station,
242 const char* user_name,
243 const char* value_name,
244 uint32 *type,
245 NEW_BUFFER *buffer,
246 void *fn)
248 POLICY_HND hnd;
249 uint32 status;
250 uint32 needed;
251 uint32 size;
252 char *data;
253 UNISTR2 uni_val_name;
255 DEBUG(4,("spoolgetdata - printer: %s server: %s user: %s value: %s\n",
256 printer_name, station, user_name, value_name));
258 if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name,
259 &hnd))
261 return NT_STATUS_ACCESS_DENIED;
264 init_unistr2(&uni_val_name, value_name, 0);
265 size = 0;
266 init_buffer(buffer, size);
267 data = NULL;
268 status = spoolss_getprinterdata(&hnd, &uni_val_name, size, type, &size,
269 data, &needed);
271 if (status == ERROR_INSUFFICIENT_BUFFER)
273 size = needed;
274 init_buffer(buffer, size);
275 data = prs_data_p(&buffer->prs);
276 status = spoolss_getprinterdata(&hnd, &uni_val_name,
277 size, type, &size,
278 data, &needed);
281 if (status != NT_STATUS_NO_PROBLEMO) {
282 if (!spoolss_closeprinter(&hnd))
283 return NT_STATUS_ACCESS_DENIED;
284 return status;
287 #if 0
288 if (fn != NULL)
289 fn(printer_name, station, level, returned, *ctr);
290 #endif
292 return status;
295 /****************************************************************************
296 nt spoolss query
297 ****************************************************************************/
298 BOOL msrpc_spoolss_enum_jobs( const char* printer_name,
299 const char* station, const char* user_name,
300 uint32 level,
301 void ***ctr, JOB_INFO_FN(fn))
303 POLICY_HND hnd;
304 uint32 status;
305 NEW_BUFFER buffer;
306 uint32 needed;
307 uint32 returned;
308 uint32 firstjob=0;
309 uint32 numofjobs=0xffff;
311 DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
312 printer_name, station, user_name));
314 if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
315 return False;
317 init_buffer(&buffer, 0);
318 status = spoolss_enum_jobs(&hnd, firstjob, numofjobs, level, &buffer, 0, &needed, &returned);
320 if (status == ERROR_INSUFFICIENT_BUFFER)
322 init_buffer(&buffer, needed);
323 status = spoolss_enum_jobs( &hnd, firstjob, numofjobs, level, &buffer, needed, &needed, &returned);
326 if (status!=NT_STATUS_NO_PROBLEMO) {
327 if (!spoolss_closeprinter(&hnd))
328 return False;
329 return False;
332 if (fn != NULL)
333 fn(printer_name, station, level, returned, *ctr);
335 return True;
339 /****************************************************************************
340 nt spoolss query
341 ****************************************************************************/
342 BOOL msrpc_spoolss_enum_printerdata( const char* printer_name,
343 const char* station, const char* user_name )
345 POLICY_HND hnd;
346 uint32 status;
347 uint32 idx;
348 uint32 valuelen;
349 uint16 *value;
350 uint32 rvaluelen;
351 uint32 type;
352 uint32 datalen;
353 uint8 *data;
354 uint32 rdatalen;
356 DEBUG(4,("spoolenum_printerdata - printer: %s\n", printer_name));
358 if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
359 return False;
361 /* FIXME!!!! --jerry
362 something is severly buggy about the use of
363 data, datalen, value, & valuelen */
364 status = spoolss_enum_printerdata(&hnd, 0, &valuelen, value,
365 &rvaluelen, &type, &datalen,
366 data, &rdatalen);
368 valuelen=rvaluelen;
369 datalen=rdatalen;
371 value=(uint16 *)malloc(valuelen*sizeof(uint16));
372 data=(uint8 *)malloc(datalen*sizeof(uint8));
374 display_printer_enumdata(out_hnd, ACTION_HEADER, idx, valuelen,
375 value, rvaluelen, type, datalen, data, rdatalen);
377 do {
379 status = spoolss_enum_printerdata(&hnd, idx, &valuelen,
380 value, &rvaluelen, &type,
381 &datalen, data, &rdatalen);
382 display_printer_enumdata(out_hnd, ACTION_ENUMERATE, idx,
383 valuelen, value, rvaluelen, type,
384 datalen, data, rdatalen);
385 idx++;
387 } while (status != 0x0103); /* NO_MORE_ITEMS */
389 display_printer_enumdata(out_hnd, ACTION_FOOTER, idx, valuelen,
390 value, rvaluelen, type, datalen, data, rdatalen);
393 if (status!=NT_STATUS_NO_PROBLEMO) {
395 * the check on this if statement is redundant
396 * since is the status is bad we're going to
397 * return False anyways. The caller will be
398 * unable to determine if there really was a problem
399 * with the spoolss_closeprinter() call --jerry
401 spoolss_closeprinter(&hnd);
402 return False;
405 return True;
408 /****************************************************************************
409 nt spoolss query
410 ****************************************************************************/
411 BOOL msrpc_spoolss_getprinter( const char* printer_name, const uint32 level,
412 const char* station, const char* user_name,
413 PRINTER_INFO_CTR ctr)
415 POLICY_HND hnd;
416 uint32 status=0;
417 NEW_BUFFER buffer;
418 uint32 needed;
420 DEBUG(4,("spoolenum_getprinter - printer: %s\n", printer_name));
422 if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
423 return False;
425 init_buffer(&buffer, 0);
427 status = spoolss_getprinter(&hnd, level, &buffer, 0, &needed);
429 if (status==ERROR_INSUFFICIENT_BUFFER) {
430 init_buffer(&buffer, needed);
431 status = spoolss_getprinter(&hnd, level, &buffer, needed, &needed);
434 report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
436 if (status!=NT_STATUS_NO_PROBLEMO)
437 return False;
439 switch (level) {
440 case 0:
441 decode_printer_info_0(&buffer, 1, &(ctr.printers_0));
442 break;
443 case 1:
444 decode_printer_info_1(&buffer, 1, &(ctr.printers_1));
445 break;
446 case 2:
447 decode_printer_info_2(&buffer, 1, &(ctr.printers_2));
448 break;
449 case 3:
450 decode_printer_info_3(&buffer, 1, &(ctr.printers_3));
451 break;
454 display_printer_info_ctr(out_hnd, ACTION_HEADER , level, 1, ctr);
455 display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
456 display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, 1, ctr);
458 if (status!=NT_STATUS_NO_PROBLEMO) {
459 if (!spoolss_closeprinter(&hnd))
460 return False;
461 return False;
464 return True;
467 /****************************************************************************
468 nt spoolss query
469 ****************************************************************************/
470 BOOL msrpc_spoolss_getprinterdriver( const char* printer_name,
471 const char *environment, const uint32 level,
472 const char* station, const char* user_name,
473 PRINTER_DRIVER_CTR ctr)
475 POLICY_HND hnd;
476 uint32 status=0;
477 NEW_BUFFER buffer;
478 uint32 needed;
480 DEBUG(4,("spoolenum_getprinterdriver - printer: %s\n", printer_name));
482 if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
483 return False;
485 init_buffer(&buffer, 0);
487 status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, 0, &needed);
489 if (status==ERROR_INSUFFICIENT_BUFFER) {
490 init_buffer(&buffer, needed);
491 status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, needed, &needed);
494 report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
496 if (status!=NT_STATUS_NO_PROBLEMO)
497 return False;
499 switch (level) {
500 case 1:
501 decode_printer_driver_1(&buffer, 1, &(ctr.info1));
502 break;
503 case 2:
504 decode_printer_driver_2(&buffer, 1, &(ctr.info2));
505 break;
506 case 3:
507 decode_printer_driver_3(&buffer, 1, &(ctr.info3));
508 break;
511 display_printer_driver_ctr(out_hnd, ACTION_HEADER , level, 1, ctr);
512 display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
513 display_printer_driver_ctr(out_hnd, ACTION_FOOTER , level, 1, ctr);
515 if (status!=NT_STATUS_NO_PROBLEMO) {
516 if (!spoolss_closeprinter(&hnd))
517 return False;
518 return False;
521 return True;
524 /****************************************************************************
525 nt spoolss query
526 ****************************************************************************/
527 BOOL msrpc_spoolss_enumprinterdrivers( const char* srv_name,
528 const char *environment, const uint32 level,
529 PRINTER_DRIVER_CTR ctr)
531 uint32 status=0;
532 NEW_BUFFER buffer;
533 uint32 needed;
534 uint32 returned;
536 DEBUG(4,("spoolenum_enumprinterdrivers - server: %s\n", srv_name));
538 init_buffer(&buffer, 0);
540 status = spoolss_enum_printerdrivers(srv_name, environment,
541 level, &buffer, 0, &needed, &returned);
543 if (status == ERROR_INSUFFICIENT_BUFFER)
545 init_buffer(&buffer, needed);
546 status = spoolss_enum_printerdrivers( srv_name, environment,
547 level, &buffer, needed, &needed, &returned);
550 report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
552 if (status!=NT_STATUS_NO_PROBLEMO)
553 return False;
555 switch (level)
557 case 1:
559 decode_printer_driver_1(&buffer, returned, &(ctr.info1));
560 break;
562 case 2:
564 decode_printer_driver_2(&buffer, returned, &(ctr.info2));
565 break;
567 case 3:
569 decode_printer_driver_3(&buffer, returned, &(ctr.info3));
570 break;
574 display_printer_driver_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
575 display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
576 display_printer_driver_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
578 return True;
581 /****************************************************************************
582 nt spoolss query
583 ****************************************************************************/
584 BOOL msrpc_spoolss_getprinterdriverdir(char* srv_name, char* env_name, uint32 level, DRIVER_DIRECTORY_CTR ctr)
586 uint32 status;
587 NEW_BUFFER buffer;
588 uint32 needed;
590 init_buffer(&buffer, 0);
592 /* send a NULL buffer first */
593 status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, 0, &needed);
595 if (status==ERROR_INSUFFICIENT_BUFFER) {
596 init_buffer(&buffer, needed);
597 status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, needed, &needed);
600 report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
602 if (status!=NT_STATUS_NO_PROBLEMO)
603 return False;
605 switch (level) {
606 case 1:
607 decode_printerdriverdir_info_1(&buffer, &(ctr.driver.info_1));
608 break;
611 display_printerdriverdir_info_ctr(out_hnd, ACTION_HEADER , level, ctr);
612 display_printerdriverdir_info_ctr(out_hnd, ACTION_ENUMERATE, level, ctr);
613 display_printerdriverdir_info_ctr(out_hnd, ACTION_FOOTER , level, ctr);
614 return True;