3baec6c569bce615f004f9898ae8541e5f1e45b5
[kai/samba.git] / source3 / rpc_client / msrpc_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    
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.
13    
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.
18    
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.
22 */
23
24 #include "includes.h"
25 #include "nterr.h"
26 #include "rpc_parse.h"
27 #include "rpcclient.h"
28
29 #define DEBUG_TESTING
30
31 extern FILE* out_hnd;
32
33 extern struct user_creds *usr_creds;
34
35 /********************************************************************
36 initialize a spoolss NEW_BUFFER.
37 ********************************************************************/
38 void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
39 {
40         buffer->ptr = (size!=0)? 1:0;
41         buffer->size=size;
42         buffer->string_at_end=size;
43         prs_init(&buffer->prs, size, ctx, MARSHALL);
44         buffer->struct_start = prs_offset(&buffer->prs);
45 }
46
47 static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, 
48                                   PRINTER_INFO_0 **info)
49 {
50         uint32 i;
51         PRINTER_INFO_0  *inf;
52
53         inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
54
55         buffer->prs.data_offset=0;
56
57         for (i=0; i<returned; i++) {
58                 new_smb_io_printer_info_0("", buffer, &(inf[i]), 0);
59         }
60
61         *info=inf;
62 }
63
64 static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned, 
65                                   PRINTER_INFO_1 **info)
66 {
67         uint32 i;
68         PRINTER_INFO_1  *inf;
69
70         inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1));
71
72         buffer->prs.data_offset=0;
73
74         for (i=0; i<returned; i++) {
75                 new_smb_io_printer_info_1("", buffer, &(inf[i]), 0);
76         }
77
78         *info=inf;
79 }
80
81 static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned, 
82                                   PRINTER_INFO_2 **info)
83 {
84         uint32 i;
85         PRINTER_INFO_2  *inf;
86
87         inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2));
88
89         buffer->prs.data_offset=0;
90
91         for (i=0; i<returned; i++) {
92                 /* a little initialization as we go */
93                 inf[i].secdesc = NULL;
94                 new_smb_io_printer_info_2("", buffer, &(inf[i]), 0);
95         }
96
97         *info=inf;
98 }
99
100 static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned, 
101                                   PRINTER_INFO_3 **info)
102 {
103         uint32 i;
104         PRINTER_INFO_3  *inf;
105
106         inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3));
107
108         buffer->prs.data_offset=0;
109
110         for (i=0; i<returned; i++) {
111                 new_smb_io_printer_info_3("", buffer, &(inf[i]), 0);
112         }
113
114         *info=inf;
115 }
116
117 static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, 
118                                     DRIVER_INFO_1 **info)
119 {
120         uint32 i;
121         DRIVER_INFO_1 *inf;
122
123         inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1));
124
125         buffer->prs.data_offset=0;
126
127         for (i=0; i<returned; i++) {
128                 new_smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
129         }
130
131         *info=inf;
132 }
133
134 static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, 
135                                     DRIVER_INFO_2 **info)
136 {
137         uint32 i;
138         DRIVER_INFO_2 *inf;
139
140         inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2));
141
142         buffer->prs.data_offset=0;
143
144         for (i=0; i<returned; i++) {
145                 new_smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
146         }
147
148         *info=inf;
149 }
150
151 static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned, 
152                                     DRIVER_INFO_3 **info)
153 {
154         uint32 i;
155         DRIVER_INFO_3 *inf;
156
157         inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3));
158
159         buffer->prs.data_offset=0;
160
161         for (i=0; i<returned; i++) {
162                 new_smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
163         }
164
165         *info=inf;
166 }
167
168 static void decode_printerdriverdir_info_1(NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info)
169 {
170 /*      DRIVER_DIRECTORY_1 *inf;
171
172         inf=(DRIVER_DIRECTORY_1 *)malloc(returned*sizeof(DRIVER_DIRECTORY_1));
173 */
174         prs_set_offset(&buffer->prs, 0);
175
176         new_smb_io_driverdir_1("", buffer, info, 0);
177
178 /*      *info=inf;*/
179 }
180
181 /**********************************************************************
182  Decode a PORT_INFO_1 struct from a NEW_BUFFER 
183 **********************************************************************/
184 void decode_port_info_1(NEW_BUFFER *buffer, uint32 returned, 
185                         PORT_INFO_1 **info)
186 {
187         uint32 i;
188         PORT_INFO_1 *inf;
189
190         inf=(PORT_INFO_1*)malloc(returned*sizeof(PORT_INFO_1));
191
192         prs_set_offset(&buffer->prs, 0);
193
194         for (i=0; i<returned; i++) {
195                 new_smb_io_port_info_1("", buffer, &(inf[i]), 0);
196         }
197
198         *info=inf;
199 }
200
201 /**********************************************************************
202  Decode a PORT_INFO_2 struct from a NEW_BUFFER 
203 **********************************************************************/
204 void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned, 
205                         PORT_INFO_2 **info)
206 {
207         uint32 i;
208         PORT_INFO_2 *inf;
209
210         inf=(PORT_INFO_2*)malloc(returned*sizeof(PORT_INFO_2));
211
212         prs_set_offset(&buffer->prs, 0);
213
214         for (i=0; i<returned; i++) {
215                 new_smb_io_port_info_2("", buffer, &(inf[i]), 0);
216         }
217
218         *info=inf;
219 }
220
221
222 /****************************************************************************
223 nt spoolss query
224 ****************************************************************************/
225 BOOL msrpc_spoolss_enum_printers(char* srv_name, uint32 flags, 
226                                  uint32 level, PRINTER_INFO_CTR ctr)
227 {
228         NTSTATUS status;
229         NEW_BUFFER buffer;
230         uint32 needed;
231         uint32 returned;
232         TALLOC_CTX *mem_ctx = NULL;
233         
234         if ((mem_ctx=talloc_init()) == NULL)
235         {
236                 DEBUG(0,("msrpc_spoolss_enum_printers: talloc_init failed!\n"));
237                 return False;
238         }
239         init_buffer(&buffer, 0, mem_ctx);
240         
241         /* send a NULL buffer first */
242         status=spoolss_enum_printers(flags, srv_name, level, &buffer, 0, 
243                                      &needed, &returned);
244         
245         if (status==ERROR_INSUFFICIENT_BUFFER) {
246                 init_buffer(&buffer, needed, mem_ctx);
247                 status=spoolss_enum_printers(flags, srv_name, level, &buffer, 
248                                              needed, &needed, &returned);
249         }
250         
251         if (status!=NT_STATUS_OK)
252         {
253                 DEBUG(0,("spoolss_enum_printers: %s\n", get_nt_error_msg(status)));
254                 if (mem_ctx)
255                         talloc_destroy(mem_ctx);
256                 return False;
257         }
258                 
259         /* is there anything to process? */
260         if (returned != 0)
261         {
262                 switch (level) {
263                 case 1:
264                         decode_printer_info_1(&buffer, returned, &(ctr.printers_1));
265                         break;
266                 case 2:
267                         decode_printer_info_2(&buffer, returned, &(ctr.printers_2));
268                         break;
269                 case 3:
270                         decode_printer_info_3(&buffer, returned, &(ctr.printers_3));
271                         break;
272                 }               
273
274                 display_printer_info_ctr(out_hnd, ACTION_HEADER   , level, returned, ctr);
275                 display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
276                 display_printer_info_ctr(out_hnd, ACTION_FOOTER   , level, returned, ctr);
277         }
278
279         if (mem_ctx)
280                 talloc_destroy(mem_ctx);
281                 
282         return True;
283 }
284
285 /****************************************************************************
286 nt spoolss query
287 ****************************************************************************/
288 BOOL msrpc_spoolss_enum_ports(char* srv_name, 
289                                  uint32 level, PORT_INFO_CTR *ctr)
290 {
291         NTSTATUS status;
292         NEW_BUFFER buffer;
293         uint32 needed;
294         uint32 returned;
295         TALLOC_CTX *mem_ctx = NULL;
296         
297         if ((mem_ctx=talloc_init()) == NULL)
298         {
299                 DEBUG(0,("msrpc_spoolss_enum_ports: talloc_init failed!\n"));
300                 return False;
301         }
302         
303         init_buffer(&buffer, 0, mem_ctx);
304         
305         /* send a NULL buffer first */
306         status=spoolss_enum_ports(srv_name, level, &buffer, 0, 
307                                      &needed, &returned);
308         
309         if (status==ERROR_INSUFFICIENT_BUFFER) {
310                 init_buffer(&buffer, needed, mem_ctx);
311                 status=spoolss_enum_ports(srv_name, level, &buffer, 
312                                           needed, &needed, &returned);
313         }
314         
315         report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
316         
317         if (status!=NT_STATUS_OK)
318         {
319                 if (mem_ctx)
320                         talloc_destroy(mem_ctx);
321                 return False;
322         }
323                 
324         /* is there anything to process? */
325         if (returned != 0)
326         {
327                 switch (level) {
328                 case 1:
329                         decode_port_info_1(&buffer, returned, &ctr->port.info_1);
330                         break;
331                 case 2:
332                         decode_port_info_2(&buffer, returned, &ctr->port.info_2);
333                         break;
334                 default:
335                         DEBUG(0,("Unable to decode unknown PORT_INFO_%d\n", level));
336                         break;
337                 }               
338
339                 display_port_info_ctr(out_hnd, ACTION_HEADER   , level, returned, ctr);
340                 display_port_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
341                 display_port_info_ctr(out_hnd, ACTION_FOOTER   , level, returned, ctr);
342         }
343         if (mem_ctx)
344                 talloc_destroy(mem_ctx);
345
346
347
348         return True;
349 }
350
351 /****************************************************************************
352 nt spoolss query
353 ****************************************************************************/
354 uint32 msrpc_spoolss_getprinterdata( const char* printer_name,
355                                 const char* station,
356                                 const char* user_name,
357                                 const char* value_name,
358                                 uint32 *type,
359                                 NEW_BUFFER *buffer,
360                                 void *fn)
361 {
362         POLICY_HND hnd;
363         NTSTATUS status;
364         uint32 needed;
365         uint32 size;
366         char *data;
367         UNISTR2 uni_val_name;
368         TALLOC_CTX *mem_ctx = NULL;
369         
370         DEBUG(4,("spoolgetdata - printer: %s server: %s user: %s value: %s\n",
371                 printer_name, station, user_name, value_name));
372
373         if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name,
374                                 &hnd))
375         {
376                 return NT_STATUS_ACCESS_DENIED;
377         }
378
379         init_unistr2(&uni_val_name, value_name, 0);
380         size = 0;
381         data = NULL;
382
383         if ((mem_ctx=talloc_init()) == NULL)
384         {
385                 DEBUG(0,("msrpc_spoolss_getprinterdata: talloc_init failed!\n"));
386                 return False;
387         }
388         init_buffer(buffer, size, mem_ctx);
389
390         status = spoolss_getprinterdata(&hnd, &uni_val_name, size, type, &size,
391                         (unsigned char *)data, &needed);
392
393         if (status == ERROR_INSUFFICIENT_BUFFER)
394         {
395                 size = needed;
396                 init_buffer(buffer, size, mem_ctx);
397                 data = prs_data_p(&buffer->prs);
398                 status = spoolss_getprinterdata(&hnd, &uni_val_name,
399                                 size, type, &size,
400                                 (unsigned char *)data, &needed);
401         }
402         
403         if (mem_ctx)
404                 talloc_destroy(mem_ctx);
405
406         if (status != NT_STATUS_OK) 
407         {
408                 if (!spoolss_closeprinter(&hnd))
409                         return NT_STATUS_ACCESS_DENIED;
410                 return status;
411         }
412
413 #if  0
414         if (fn != NULL)
415                 fn(printer_name, station, level, returned, *ctr);
416 #endif
417
418         return status;
419 }
420
421 /****************************************************************************
422 nt spoolss query
423 ****************************************************************************/
424 BOOL msrpc_spoolss_enum_jobs( const char* printer_name,
425                                 const char* station, const char* user_name,
426                                 uint32 level,
427                                 void ***ctr, JOB_INFO_FN(fn))
428 {
429         POLICY_HND hnd;
430         NTSTATUS status;
431         NEW_BUFFER buffer;
432         uint32 needed;
433         uint32 returned;
434         uint32 firstjob=0;
435         uint32 numofjobs=0xffff;
436         TALLOC_CTX *mem_ctx = NULL;
437         
438         DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
439                 printer_name, station, user_name));
440
441         if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
442                 return False;
443
444         if ((mem_ctx=talloc_init()) == NULL)
445         {
446                 DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
447                 return False;
448         }
449         init_buffer(&buffer, 0, mem_ctx);
450         status = spoolss_enum_jobs(&hnd, firstjob, numofjobs, level, 
451                                    &buffer, 0, &needed, &returned);
452
453         if (status == ERROR_INSUFFICIENT_BUFFER)
454         {
455                 init_buffer(&buffer, needed, mem_ctx);
456                 status = spoolss_enum_jobs( &hnd, firstjob, numofjobs, level, 
457                                             &buffer, needed, &needed, &returned);
458         }
459
460         if (mem_ctx)
461                 talloc_destroy(mem_ctx);
462                 
463         if (status!=NT_STATUS_OK) {
464                 if (!spoolss_closeprinter(&hnd))
465                         return False;
466                 return False;
467         }
468
469         if (fn != NULL)
470                 fn(printer_name, station, level, returned, *ctr);
471
472         return True;
473 }
474
475
476 /****************************************************************************
477 nt spoolss query
478 ****************************************************************************/
479 BOOL msrpc_spoolss_enum_printerdata( const char* printer_name, 
480                 const char* station, const char* user_name )
481 {
482         POLICY_HND hnd;
483         NTSTATUS status;
484         uint32 idx;
485         uint32 valuelen;
486         uint16 *value;
487         uint32 rvaluelen;
488         uint32 type;
489         uint32 datalen;
490         uint8  *data;
491         uint32 rdatalen;
492         uint32 maxvaluelen;
493         uint32 maxdatalen;
494         
495         DEBUG(4,("msrpc_spoolss_enum_printerdata - printer: %s\n", printer_name));
496
497         if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
498                 return False;
499
500         
501         idx=0;
502         valuelen=0;
503         rvaluelen=0;
504         type=0;
505         datalen=0;
506         rdatalen=0;
507         
508         status = spoolss_enum_printerdata(&hnd, idx, &valuelen, value, 
509                                           &rvaluelen, &type, &datalen, 
510                                           data, &rdatalen);
511
512         DEBUG(4,("spoolenum_printerdata - got size: biggest value:[%d], biggest data:[%d]\n", rvaluelen, rdatalen));
513
514         maxvaluelen=valuelen=rvaluelen;
515         maxdatalen=datalen=rdatalen;
516
517         value=(uint16 *)malloc(valuelen*sizeof(uint16));
518         data=(uint8 *)malloc(datalen*sizeof(uint8));
519
520         display_printer_enumdata(out_hnd, ACTION_HEADER, idx, valuelen, 
521                                  value, rvaluelen, type, datalen, data, rdatalen);
522         
523         do {
524                 valuelen=maxvaluelen;
525                 datalen=maxdatalen;
526
527                 status = spoolss_enum_printerdata(&hnd, idx, &valuelen, 
528                                                   value, &rvaluelen, &type, 
529                                                   &datalen, data, &rdatalen);
530                 display_printer_enumdata(out_hnd, ACTION_ENUMERATE, idx, 
531                                          valuelen, value, rvaluelen, type, 
532                                          datalen, data, rdatalen);
533                 idx++;
534
535         } while (status != 0x0103); /* NO_MORE_ITEMS */
536
537         display_printer_enumdata(out_hnd, ACTION_FOOTER, idx, valuelen, 
538                                  value, rvaluelen, type, datalen, data, rdatalen);
539
540         
541         if (status!=NT_STATUS_OK) {
542                 /* 
543                  * the check on this if statement is redundant
544                  * since is the status is bad we're going to 
545                  * return False anyways.  The caller will be 
546                  * unable to determine if there really was a problem
547                  * with the spoolss_closeprinter() call  --jerry
548                  */
549                 spoolss_closeprinter(&hnd);
550                 return False;
551         }
552         
553         return True;
554 }
555
556 /****************************************************************************
557 nt spoolss query
558 ****************************************************************************/
559 BOOL msrpc_spoolss_getprinter( const char* printer_name, const uint32 level,
560                 const char* station, const char* user_name,
561                 PRINTER_INFO_CTR ctr)
562 {
563         POLICY_HND hnd;
564         NTSTATUS status=0;
565         NEW_BUFFER buffer;
566         uint32 needed=1000;
567         TALLOC_CTX *mem_ctx = NULL;
568         
569         DEBUG(4,("spoolenum_getprinter - printer: %s\n", printer_name));
570
571         if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
572                 return False;
573
574         if ((mem_ctx=talloc_init()) == NULL)
575         {
576                 DEBUG(0,("msrpc_spoolss_getprinter: talloc_init failed!\n"));
577                 return False;
578         }
579         init_buffer(&buffer, needed, mem_ctx);
580
581         status = spoolss_getprinter(&hnd, level, &buffer, needed, &needed);
582
583         if (status==ERROR_INSUFFICIENT_BUFFER) {
584                 init_buffer(&buffer, needed, mem_ctx);
585                 status = spoolss_getprinter(&hnd, level, &buffer, needed, &needed);
586         }
587
588         report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
589
590         if (status!=NT_STATUS_OK)
591         {
592                 if (mem_ctx)
593                         talloc_destroy(mem_ctx);
594                 return False;
595         }
596
597         switch (level) {
598         case 0:
599                 decode_printer_info_0(&buffer, 1, &(ctr.printers_0));
600                 break;
601         case 1:
602                 decode_printer_info_1(&buffer, 1, &(ctr.printers_1));
603                 break;
604         case 2:
605                 decode_printer_info_2(&buffer, 1, &(ctr.printers_2));
606                 break;
607         case 3:
608                 decode_printer_info_3(&buffer, 1, &(ctr.printers_3));
609                 break;
610         }
611
612         display_printer_info_ctr(out_hnd, ACTION_HEADER   , level, 1, ctr);
613         display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
614         display_printer_info_ctr(out_hnd, ACTION_FOOTER   , level, 1, ctr);
615
616         if (mem_ctx)
617                 talloc_destroy(mem_ctx);
618
619         if (status!=NT_STATUS_OK) {
620                 if (!spoolss_closeprinter(&hnd))
621                         return False;
622                 return False;
623         }
624
625         return True;
626 }
627
628 /****************************************************************************
629 nt spoolss query
630 ****************************************************************************/
631 BOOL msrpc_spoolss_getprinterdriver( const char* printer_name,
632                 const char *environment, const uint32 level,
633                 const char* station, const char* user_name,
634                 PRINTER_DRIVER_CTR ctr)
635 {
636         POLICY_HND hnd;
637         NTSTATUS status=0;
638         NEW_BUFFER buffer;
639         uint32 needed;
640         TALLOC_CTX *mem_ctx = NULL;
641         
642         DEBUG(4,("msrpc_spoolss_enum_getprinterdriver - printer: %s\n", printer_name));
643
644         if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
645                 return False;
646
647         if ((mem_ctx=talloc_init()) == NULL)
648         {
649                 DEBUG(0,("msrpc_spoolss_getprinterdriver: talloc_init failed!\n"));
650                 return False;
651         }
652         init_buffer(&buffer, 0, mem_ctx);
653
654         status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, 0, &needed);
655
656         if (status==ERROR_INSUFFICIENT_BUFFER) {
657                 init_buffer(&buffer, needed, mem_ctx);
658                 status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, needed, &needed);
659         }
660
661         /* report(out_hnd, "\tstatus:[%d (%x)]\n", status, status); */
662
663         if (status!=NT_STATUS_OK)
664         {
665                 if (mem_ctx)
666                         talloc_destroy(mem_ctx);
667                 return False;
668         }
669
670         switch (level) {
671                 case 1:
672                         decode_printer_driver_1(&buffer, 1, &(ctr.info1));
673                         break;
674                 case 2:
675                         decode_printer_driver_2(&buffer, 1, &(ctr.info2));
676                         break;
677                 case 3:
678                         decode_printer_driver_3(&buffer, 1, &(ctr.info3));
679                         break;
680         }
681
682         display_printer_driver_ctr(out_hnd, ACTION_HEADER   , level, 1, ctr);
683         display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
684         display_printer_driver_ctr(out_hnd, ACTION_FOOTER   , level, 1, ctr);
685
686         if (mem_ctx)
687                 talloc_destroy(mem_ctx);
688                 
689         if (status!=NT_STATUS_OK) {
690                 if (!spoolss_closeprinter(&hnd))
691                         return False;
692                 return False;
693         }
694
695         return True;
696 }
697
698 /****************************************************************************
699 nt spoolss query
700 ****************************************************************************/
701 BOOL msrpc_spoolss_enumprinterdrivers( const char* srv_name,
702                 const char *environment, const uint32 level,
703                 PRINTER_DRIVER_CTR ctr)
704 {
705         NTSTATUS status=0;
706         NEW_BUFFER buffer;
707         uint32 needed;
708         uint32 returned;
709         TALLOC_CTX *mem_ctx = NULL;
710         
711         DEBUG(4,("msrpc_spoolss_enum_enumprinterdrivers - server: %s\n", srv_name));
712
713         if ((mem_ctx=talloc_init()) == NULL)
714         {
715                 DEBUG(0,("msrpc_spoolss_enumprinterdrivers: talloc_init failed!\n"));
716                 return False;
717         }
718         init_buffer(&buffer, 0, mem_ctx);
719
720         status = spoolss_enum_printerdrivers(srv_name, environment,
721                                 level, &buffer, 0, &needed, &returned);
722
723         if (status == ERROR_INSUFFICIENT_BUFFER)
724         {
725                 init_buffer(&buffer, needed, mem_ctx);
726                 status = spoolss_enum_printerdrivers( srv_name, environment,
727                                 level, &buffer, needed, &needed, &returned);
728         }
729
730         report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
731
732         if (status!=NT_STATUS_OK)
733         {
734                 if (mem_ctx)
735                         talloc_destroy(mem_ctx);
736                 return False;
737         }
738
739         switch (level)
740         {
741                 case 1:
742                         decode_printer_driver_1(&buffer, returned, &(ctr.info1));
743                         break;
744                 case 2:
745                         decode_printer_driver_2(&buffer, returned, &(ctr.info2));
746                         break;
747                 case 3:
748                         decode_printer_driver_3(&buffer, returned, &(ctr.info3));
749                         break;
750         }
751
752         display_printer_driver_ctr(out_hnd, ACTION_HEADER   , level, returned, ctr);
753         display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
754         display_printer_driver_ctr(out_hnd, ACTION_FOOTER   , level, returned, ctr);
755
756         if (mem_ctx)
757                 talloc_destroy(mem_ctx);
758                 
759         return True;
760 }
761
762 /****************************************************************************
763 nt spoolss query
764 ****************************************************************************/
765 BOOL msrpc_spoolss_getprinterdriverdir(char* srv_name, char* env_name, uint32 level, DRIVER_DIRECTORY_CTR ctr)
766 {
767         NTSTATUS status;
768         NEW_BUFFER buffer;
769         uint32 needed;
770         TALLOC_CTX *mem_ctx = NULL;
771         
772         if ((mem_ctx=talloc_init()) == NULL)
773         {
774                 DEBUG(0,("msrpc_spoolss_getprinterdriverdir: talloc_init failed!\n"));
775                 return False;
776         }
777         init_buffer(&buffer, 0, mem_ctx);
778
779         /* send a NULL buffer first */
780         status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, 0, &needed);
781
782         if (status==ERROR_INSUFFICIENT_BUFFER) {
783                 init_buffer(&buffer, needed, mem_ctx);
784                 status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, needed, &needed);
785         }
786
787         report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
788
789         if (status!=NT_STATUS_OK)
790         {
791                 if (mem_ctx)
792                         talloc_destroy(mem_ctx);
793                 return False;
794         }
795
796         switch (level) {
797         case 1:
798                 decode_printerdriverdir_info_1(&buffer, &(ctr.driver.info_1));
799                 break;
800         }
801
802         display_printerdriverdir_info_ctr(out_hnd, ACTION_HEADER   , level, ctr);
803         display_printerdriverdir_info_ctr(out_hnd, ACTION_ENUMERATE, level, ctr);
804         display_printerdriverdir_info_ctr(out_hnd, ACTION_FOOTER   , level, ctr);
805         
806         if (mem_ctx)
807                 talloc_destroy(mem_ctx);
808
809         return True;
810 }