Merge commit 'release-4-0-0alpha15' into master4-tmp
[kai/samba-autobuild/.git] / source3 / rpc_client / cli_spoolss.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) Gerald Carter                2001-2005,
6    Copyright (C) Tim Potter                   2000-2002,
7    Copyright (C) Andrew Tridgell              1994-2000,
8    Copyright (C) Jean-Francois Micouleau      1999-2000.
9    Copyright (C) Jeremy Allison                         2005.
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "rpc_client/rpc_client.h"
27 #include "../librpc/gen_ndr/ndr_spoolss_c.h"
28 #include "rpc_client/cli_spoolss.h"
29
30 /**********************************************************************
31  convencience wrapper around rpccli_spoolss_OpenPrinterEx
32 **********************************************************************/
33
34 WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
35                                      TALLOC_CTX *mem_ctx,
36                                      const char *printername,
37                                      uint32_t access_desired,
38                                      struct policy_handle *handle)
39 {
40         NTSTATUS status;
41         WERROR werror;
42         struct spoolss_DevmodeContainer devmode_ctr;
43         union spoolss_UserLevel userlevel;
44         struct spoolss_UserLevel1 level1;
45         struct dcerpc_binding_handle *b = cli->binding_handle;
46
47         ZERO_STRUCT(devmode_ctr);
48
49         level1.size     = 28;
50         level1.client   = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
51         W_ERROR_HAVE_NO_MEMORY(level1.client);
52         level1.user     = cli->auth->user_name;
53         level1.build    = 1381;
54         level1.major    = 2;
55         level1.minor    = 0;
56         level1.processor = 0;
57
58         userlevel.level1 = &level1;
59
60         status = dcerpc_spoolss_OpenPrinterEx(b, mem_ctx,
61                                               printername,
62                                               NULL,
63                                               devmode_ctr,
64                                               access_desired,
65                                               1, /* level */
66                                               userlevel,
67                                               handle,
68                                               &werror);
69
70         if (!NT_STATUS_IS_OK(status)) {
71                 return ntstatus_to_werror(status);
72         }
73
74         if (!W_ERROR_IS_OK(werror)) {
75                 return werror;
76         }
77
78         return WERR_OK;
79 }
80
81 /**********************************************************************
82  convencience wrapper around rpccli_spoolss_GetPrinterDriver
83 **********************************************************************/
84
85 WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli,
86                                        TALLOC_CTX *mem_ctx,
87                                        struct policy_handle *handle,
88                                        const char *architecture,
89                                        uint32_t level,
90                                        uint32_t offered,
91                                        union spoolss_DriverInfo *info)
92 {
93         NTSTATUS status;
94         WERROR werror;
95         uint32_t needed;
96         DATA_BLOB buffer;
97         struct dcerpc_binding_handle *b = cli->binding_handle;
98
99         if (offered > 0) {
100                 buffer = data_blob_talloc_zero(mem_ctx, offered);
101                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
102         }
103
104         status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx,
105                                                  handle,
106                                                  architecture,
107                                                  level,
108                                                  (offered > 0) ? &buffer : NULL,
109                                                  offered,
110                                                  info,
111                                                  &needed,
112                                                  &werror);
113         if (!NT_STATUS_IS_OK(status)) {
114                 return ntstatus_to_werror(status);
115         }
116         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
117                 offered = needed;
118                 buffer = data_blob_talloc_zero(mem_ctx, needed);
119                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
120
121                 status = dcerpc_spoolss_GetPrinterDriver(b, mem_ctx,
122                                                          handle,
123                                                          architecture,
124                                                          level,
125                                                          &buffer,
126                                                          offered,
127                                                          info,
128                                                          &needed,
129                                                          &werror);
130         }
131         if (!NT_STATUS_IS_OK(status)) {
132                 return ntstatus_to_werror(status);
133         }
134
135         return werror;
136 }
137
138 /**********************************************************************
139  convencience wrapper around rpccli_spoolss_GetPrinterDriver2
140 **********************************************************************/
141
142 WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
143                                         TALLOC_CTX *mem_ctx,
144                                         struct policy_handle *handle,
145                                         const char *architecture,
146                                         uint32_t level,
147                                         uint32_t offered,
148                                         uint32_t client_major_version,
149                                         uint32_t client_minor_version,
150                                         union spoolss_DriverInfo *info,
151                                         uint32_t *server_major_version,
152                                         uint32_t *server_minor_version)
153 {
154         NTSTATUS status;
155         WERROR werror;
156         uint32_t needed;
157         DATA_BLOB buffer;
158         struct dcerpc_binding_handle *b = cli->binding_handle;
159
160         if (offered > 0) {
161                 buffer = data_blob_talloc_zero(mem_ctx, offered);
162                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
163         }
164
165         status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx,
166                                                   handle,
167                                                   architecture,
168                                                   level,
169                                                   (offered > 0) ? &buffer : NULL,
170                                                   offered,
171                                                   client_major_version,
172                                                   client_minor_version,
173                                                   info,
174                                                   &needed,
175                                                   server_major_version,
176                                                   server_minor_version,
177                                                   &werror);
178         if (!NT_STATUS_IS_OK(status)) {
179                 return ntstatus_to_werror(status);
180         }
181
182         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
183                 offered = needed;
184                 buffer = data_blob_talloc_zero(mem_ctx, needed);
185                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
186
187                 status = dcerpc_spoolss_GetPrinterDriver2(b, mem_ctx,
188                                                           handle,
189                                                           architecture,
190                                                           level,
191                                                           &buffer,
192                                                           offered,
193                                                           client_major_version,
194                                                           client_minor_version,
195                                                           info,
196                                                           &needed,
197                                                           server_major_version,
198                                                           server_minor_version,
199                                                           &werror);
200         }
201         if (!NT_STATUS_IS_OK(status)) {
202                 return ntstatus_to_werror(status);
203         }
204
205         return werror;
206 }
207
208 /**********************************************************************
209  convencience wrapper around rpccli_spoolss_AddPrinterEx
210 **********************************************************************/
211
212 WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli,
213                                    TALLOC_CTX *mem_ctx,
214                                    struct spoolss_SetPrinterInfoCtr *info_ctr)
215 {
216         WERROR result;
217         NTSTATUS status;
218         struct spoolss_DevmodeContainer devmode_ctr;
219         struct sec_desc_buf secdesc_ctr;
220         struct spoolss_UserLevelCtr userlevel_ctr;
221         struct spoolss_UserLevel1 level1;
222         struct policy_handle handle;
223         struct dcerpc_binding_handle *b = cli->binding_handle;
224
225         ZERO_STRUCT(devmode_ctr);
226         ZERO_STRUCT(secdesc_ctr);
227
228         level1.size             = 28;
229         level1.build            = 1381;
230         level1.major            = 2;
231         level1.minor            = 0;
232         level1.processor        = 0;
233         level1.client           = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
234         W_ERROR_HAVE_NO_MEMORY(level1.client);
235         level1.user             = cli->auth->user_name;
236
237         userlevel_ctr.level = 1;
238         userlevel_ctr.user_info.level1 = &level1;
239
240         status = dcerpc_spoolss_AddPrinterEx(b, mem_ctx,
241                                              cli->srv_name_slash,
242                                              info_ctr,
243                                              &devmode_ctr,
244                                              &secdesc_ctr,
245                                              &userlevel_ctr,
246                                              &handle,
247                                              &result);
248         if (!NT_STATUS_IS_OK(status)) {
249                 return ntstatus_to_werror(status);
250         }
251
252         return result;
253 }
254
255 /**********************************************************************
256  convencience wrapper around rpccli_spoolss_GetPrinter
257 **********************************************************************/
258
259 WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli,
260                                  TALLOC_CTX *mem_ctx,
261                                  struct policy_handle *handle,
262                                  uint32_t level,
263                                  uint32_t offered,
264                                  union spoolss_PrinterInfo *info)
265 {
266         NTSTATUS status;
267         WERROR werror;
268         DATA_BLOB buffer;
269         uint32_t needed;
270         struct dcerpc_binding_handle *b = cli->binding_handle;
271
272         if (offered > 0) {
273                 buffer = data_blob_talloc_zero(mem_ctx, offered);
274                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
275         }
276
277         status = dcerpc_spoolss_GetPrinter(b, mem_ctx,
278                                            handle,
279                                            level,
280                                            (offered > 0) ? &buffer : NULL,
281                                            offered,
282                                            info,
283                                            &needed,
284                                            &werror);
285         if (!NT_STATUS_IS_OK(status)) {
286                 return ntstatus_to_werror(status);
287         }
288
289         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
290
291                 offered = needed;
292                 buffer = data_blob_talloc_zero(mem_ctx, offered);
293                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
294
295                 status = dcerpc_spoolss_GetPrinter(b, mem_ctx,
296                                                    handle,
297                                                    level,
298                                                    &buffer,
299                                                    offered,
300                                                    info,
301                                                    &needed,
302                                                    &werror);
303         }
304         if (!NT_STATUS_IS_OK(status)) {
305                 return ntstatus_to_werror(status);
306         }
307
308         return werror;
309 }
310
311 /**********************************************************************
312  convencience wrapper around rpccli_spoolss_GetJob
313 **********************************************************************/
314
315 WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
316                              TALLOC_CTX *mem_ctx,
317                              struct policy_handle *handle,
318                              uint32_t job_id,
319                              uint32_t level,
320                              uint32_t offered,
321                              union spoolss_JobInfo *info)
322 {
323         NTSTATUS status;
324         WERROR werror;
325         uint32_t needed;
326         DATA_BLOB buffer;
327         struct dcerpc_binding_handle *b = cli->binding_handle;
328
329         if (offered > 0) {
330                 buffer = data_blob_talloc_zero(mem_ctx, offered);
331                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
332         }
333
334         status = dcerpc_spoolss_GetJob(b, mem_ctx,
335                                        handle,
336                                        job_id,
337                                        level,
338                                        (offered > 0) ? &buffer : NULL,
339                                        offered,
340                                        info,
341                                        &needed,
342                                        &werror);
343         if (!NT_STATUS_IS_OK(status)) {
344                 return ntstatus_to_werror(status);
345         }
346
347         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
348                 offered = needed;
349                 buffer = data_blob_talloc_zero(mem_ctx, needed);
350                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
351
352                 status = dcerpc_spoolss_GetJob(b, mem_ctx,
353                                                handle,
354                                                job_id,
355                                                level,
356                                                &buffer,
357                                                offered,
358                                                info,
359                                                &needed,
360                                                &werror);
361         }
362         if (!NT_STATUS_IS_OK(status)) {
363                 return ntstatus_to_werror(status);
364         }
365
366         return werror;
367 }
368
369 /**********************************************************************
370  convencience wrapper around rpccli_spoolss_EnumForms
371 **********************************************************************/
372
373 WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli,
374                                 TALLOC_CTX *mem_ctx,
375                                 struct policy_handle *handle,
376                                 uint32_t level,
377                                 uint32_t offered,
378                                 uint32_t *count,
379                                 union spoolss_FormInfo **info)
380 {
381         NTSTATUS status;
382         WERROR werror;
383         uint32_t needed;
384         DATA_BLOB buffer;
385         struct dcerpc_binding_handle *b = cli->binding_handle;
386
387         if (offered > 0) {
388                 buffer = data_blob_talloc_zero(mem_ctx, offered);
389                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
390         }
391
392         status = dcerpc_spoolss_EnumForms(b, mem_ctx,
393                                           handle,
394                                           level,
395                                           (offered > 0) ? &buffer : NULL,
396                                           offered,
397                                           count,
398                                           info,
399                                           &needed,
400                                           &werror);
401         if (!NT_STATUS_IS_OK(status)) {
402                 return ntstatus_to_werror(status);
403         }
404
405         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
406                 offered = needed;
407                 buffer = data_blob_talloc_zero(mem_ctx, needed);
408                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
409
410                 status = dcerpc_spoolss_EnumForms(b, mem_ctx,
411                                                   handle,
412                                                   level,
413                                                   (offered > 0) ? &buffer : NULL,
414                                                   offered,
415                                                   count,
416                                                   info,
417                                                   &needed,
418                                                   &werror);
419         }
420         if (!NT_STATUS_IS_OK(status)) {
421                 return ntstatus_to_werror(status);
422         }
423
424         return werror;
425 }
426
427 /**********************************************************************
428  convencience wrapper around rpccli_spoolss_EnumPrintProcessors
429 **********************************************************************/
430
431 WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli,
432                                           TALLOC_CTX *mem_ctx,
433                                           const char *servername,
434                                           const char *environment,
435                                           uint32_t level,
436                                           uint32_t offered,
437                                           uint32_t *count,
438                                           union spoolss_PrintProcessorInfo **info)
439 {
440         NTSTATUS status;
441         WERROR werror;
442         uint32_t needed;
443         DATA_BLOB buffer;
444         struct dcerpc_binding_handle *b = cli->binding_handle;
445
446         if (offered > 0) {
447                 buffer = data_blob_talloc_zero(mem_ctx, offered);
448                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
449         }
450
451         status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx,
452                                                     servername,
453                                                     environment,
454                                                     level,
455                                                     (offered > 0) ? &buffer : NULL,
456                                                     offered,
457                                                     count,
458                                                     info,
459                                                     &needed,
460                                                     &werror);
461         if (!NT_STATUS_IS_OK(status)) {
462                 return ntstatus_to_werror(status);
463         }
464
465         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
466                 offered = needed;
467                 buffer = data_blob_talloc_zero(mem_ctx, needed);
468                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
469
470                 status = dcerpc_spoolss_EnumPrintProcessors(b, mem_ctx,
471                                                             servername,
472                                                             environment,
473                                                             level,
474                                                             (offered > 0) ? &buffer : NULL,
475                                                             offered,
476                                                             count,
477                                                             info,
478                                                             &needed,
479                                                             &werror);
480         }
481         if (!NT_STATUS_IS_OK(status)) {
482                 return ntstatus_to_werror(status);
483         }
484
485         return werror;
486 }
487
488 /**********************************************************************
489  convencience wrapper around rpccli_spoolss_EnumPrintProcDataTypes
490 **********************************************************************/
491
492 WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli,
493                                                   TALLOC_CTX *mem_ctx,
494                                                   const char *servername,
495                                                   const char *print_processor_name,
496                                                   uint32_t level,
497                                                   uint32_t offered,
498                                                   uint32_t *count,
499                                                   union spoolss_PrintProcDataTypesInfo **info)
500 {
501         NTSTATUS status;
502         WERROR werror;
503         uint32_t needed;
504         DATA_BLOB buffer;
505         struct dcerpc_binding_handle *b = cli->binding_handle;
506
507         if (offered > 0) {
508                 buffer = data_blob_talloc_zero(mem_ctx, offered);
509                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
510         }
511
512         status = dcerpc_spoolss_EnumPrintProcDataTypes(b, mem_ctx,
513                                                        servername,
514                                                        print_processor_name,
515                                                        level,
516                                                        (offered > 0) ? &buffer : NULL,
517                                                        offered,
518                                                        count,
519                                                        info,
520                                                        &needed,
521                                                        &werror);
522         if (!NT_STATUS_IS_OK(status)) {
523                 return ntstatus_to_werror(status);
524         }
525
526         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
527                 offered = needed;
528                 buffer = data_blob_talloc_zero(mem_ctx, needed);
529                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
530
531                 status = dcerpc_spoolss_EnumPrintProcDataTypes(b, mem_ctx,
532                                                                servername,
533                                                                print_processor_name,
534                                                                level,
535                                                                (offered > 0) ? &buffer : NULL,
536                                                                offered,
537                                                                count,
538                                                                info,
539                                                                &needed,
540                                                                &werror);
541         }
542         if (!NT_STATUS_IS_OK(status)) {
543                 return ntstatus_to_werror(status);
544         }
545
546         return werror;
547 }
548
549 /**********************************************************************
550  convencience wrapper around rpccli_spoolss_EnumPorts
551 **********************************************************************/
552
553 WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli,
554                                 TALLOC_CTX *mem_ctx,
555                                 const char *servername,
556                                 uint32_t level,
557                                 uint32_t offered,
558                                 uint32_t *count,
559                                 union spoolss_PortInfo **info)
560 {
561         NTSTATUS status;
562         WERROR werror;
563         uint32_t needed;
564         DATA_BLOB buffer;
565         struct dcerpc_binding_handle *b = cli->binding_handle;
566
567         if (offered > 0) {
568                 buffer = data_blob_talloc_zero(mem_ctx, offered);
569                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
570         }
571
572         status = dcerpc_spoolss_EnumPorts(b, mem_ctx,
573                                           servername,
574                                           level,
575                                           (offered > 0) ? &buffer : NULL,
576                                           offered,
577                                           count,
578                                           info,
579                                           &needed,
580                                           &werror);
581         if (!NT_STATUS_IS_OK(status)) {
582                 return ntstatus_to_werror(status);
583         }
584
585         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
586                 offered = needed;
587                 buffer = data_blob_talloc_zero(mem_ctx, needed);
588                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
589
590                 status = dcerpc_spoolss_EnumPorts(b, mem_ctx,
591                                                   servername,
592                                                   level,
593                                                   (offered > 0) ? &buffer : NULL,
594                                                   offered,
595                                                   count,
596                                                   info,
597                                                   &needed,
598                                                   &werror);
599         }
600         if (!NT_STATUS_IS_OK(status)) {
601                 return ntstatus_to_werror(status);
602         }
603
604         return werror;
605 }
606
607 /**********************************************************************
608  convencience wrapper around rpccli_spoolss_EnumMonitors
609 **********************************************************************/
610
611 WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
612                                    TALLOC_CTX *mem_ctx,
613                                    const char *servername,
614                                    uint32_t level,
615                                    uint32_t offered,
616                                    uint32_t *count,
617                                    union spoolss_MonitorInfo **info)
618 {
619         NTSTATUS status;
620         WERROR werror;
621         uint32_t needed;
622         DATA_BLOB buffer;
623         struct dcerpc_binding_handle *b = cli->binding_handle;
624
625         if (offered > 0) {
626                 buffer = data_blob_talloc_zero(mem_ctx, offered);
627                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
628         }
629
630         status = dcerpc_spoolss_EnumMonitors(b, mem_ctx,
631                                              servername,
632                                              level,
633                                              (offered > 0) ? &buffer : NULL,
634                                              offered,
635                                              count,
636                                              info,
637                                              &needed,
638                                              &werror);
639         if (!NT_STATUS_IS_OK(status)) {
640                 return ntstatus_to_werror(status);
641         }
642
643         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
644                 offered = needed;
645                 buffer = data_blob_talloc_zero(mem_ctx, needed);
646                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
647
648                 status = dcerpc_spoolss_EnumMonitors(b, mem_ctx,
649                                                      servername,
650                                                      level,
651                                                      (offered > 0) ? &buffer : NULL,
652                                                      offered,
653                                                      count,
654                                                      info,
655                                                      &needed,
656                                                      &werror);
657         }
658         if (!NT_STATUS_IS_OK(status)) {
659                 return ntstatus_to_werror(status);
660         }
661
662         return werror;
663 }
664
665 /**********************************************************************
666  convencience wrapper around rpccli_spoolss_EnumJobs
667 **********************************************************************/
668
669 WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli,
670                                TALLOC_CTX *mem_ctx,
671                                struct policy_handle *handle,
672                                uint32_t firstjob,
673                                uint32_t numjobs,
674                                uint32_t level,
675                                uint32_t offered,
676                                uint32_t *count,
677                                union spoolss_JobInfo **info)
678 {
679         NTSTATUS status;
680         WERROR werror;
681         uint32_t needed;
682         DATA_BLOB buffer;
683         struct dcerpc_binding_handle *b = cli->binding_handle;
684
685         if (offered > 0) {
686                 buffer = data_blob_talloc_zero(mem_ctx, offered);
687                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
688         }
689
690         status = dcerpc_spoolss_EnumJobs(b, mem_ctx,
691                                          handle,
692                                          firstjob,
693                                          numjobs,
694                                          level,
695                                          (offered > 0) ? &buffer : NULL,
696                                          offered,
697                                          count,
698                                          info,
699                                          &needed,
700                                          &werror);
701         if (!NT_STATUS_IS_OK(status)) {
702                 return ntstatus_to_werror(status);
703         }
704
705         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
706                 offered = needed;
707                 buffer = data_blob_talloc_zero(mem_ctx, needed);
708                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
709
710                 status = dcerpc_spoolss_EnumJobs(b, mem_ctx,
711                                                  handle,
712                                                  firstjob,
713                                                  numjobs,
714                                                  level,
715                                                  (offered > 0) ? &buffer : NULL,
716                                                  offered,
717                                                  count,
718                                                  info,
719                                                  &needed,
720                                                  &werror);
721         }
722         if (!NT_STATUS_IS_OK(status)) {
723                 return ntstatus_to_werror(status);
724         }
725
726         return werror;
727 }
728
729 /**********************************************************************
730  convencience wrapper around rpccli_spoolss_EnumPrinterDrivers
731 **********************************************************************/
732
733 WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli,
734                                          TALLOC_CTX *mem_ctx,
735                                          const char *server,
736                                          const char *environment,
737                                          uint32_t level,
738                                          uint32_t offered,
739                                          uint32_t *count,
740                                          union spoolss_DriverInfo **info)
741 {
742         NTSTATUS status;
743         WERROR werror;
744         uint32_t needed;
745         DATA_BLOB buffer;
746         struct dcerpc_binding_handle *b = cli->binding_handle;
747
748         if (offered > 0) {
749                 buffer = data_blob_talloc_zero(mem_ctx, offered);
750                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
751         }
752
753         status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
754                                                    server,
755                                                    environment,
756                                                    level,
757                                                    (offered > 0) ? &buffer : NULL,
758                                                    offered,
759                                                    count,
760                                                    info,
761                                                    &needed,
762                                                    &werror);
763         if (!NT_STATUS_IS_OK(status)) {
764                 return ntstatus_to_werror(status);
765         }
766
767         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
768                 offered = needed;
769                 buffer = data_blob_talloc_zero(mem_ctx, needed);
770                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
771
772                 status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
773                                                    server,
774                                                    environment,
775                                                    level,
776                                                    (offered > 0) ? &buffer : NULL,
777                                                    offered,
778                                                    count,
779                                                    info,
780                                                    &needed,
781                                                    &werror);
782         }
783         if (!NT_STATUS_IS_OK(status)) {
784                 return ntstatus_to_werror(status);
785         }
786
787         return werror;
788 }
789
790 /**********************************************************************
791  convencience wrapper around rpccli_spoolss_EnumPrinters
792 **********************************************************************/
793
794 WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
795                                    TALLOC_CTX *mem_ctx,
796                                    uint32_t flags,
797                                    const char *server,
798                                    uint32_t level,
799                                    uint32_t offered,
800                                    uint32_t *count,
801                                    union spoolss_PrinterInfo **info)
802 {
803         NTSTATUS status;
804         WERROR werror;
805         uint32_t needed;
806         DATA_BLOB buffer;
807         struct dcerpc_binding_handle *b = cli->binding_handle;
808
809         if (offered > 0) {
810                 buffer = data_blob_talloc_zero(mem_ctx, offered);
811                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
812         }
813
814         status = dcerpc_spoolss_EnumPrinters(b, mem_ctx,
815                                              flags,
816                                              server,
817                                              level,
818                                              (offered > 0) ? &buffer : NULL,
819                                              offered,
820                                              count,
821                                              info,
822                                              &needed,
823                                              &werror);
824         if (!NT_STATUS_IS_OK(status)) {
825                 return ntstatus_to_werror(status);
826         }
827
828         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
829                 offered = needed;
830                 buffer = data_blob_talloc_zero(mem_ctx, needed);
831                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
832
833                 status = dcerpc_spoolss_EnumPrinters(b, mem_ctx,
834                                                      flags,
835                                                      server,
836                                                      level,
837                                                      (offered > 0) ? &buffer : NULL,
838                                                      offered,
839                                                      count,
840                                                      info,
841                                                      &needed,
842                                                      &werror);
843         }
844         if (!NT_STATUS_IS_OK(status)) {
845                 return ntstatus_to_werror(status);
846         }
847
848         return werror;
849 }
850
851 /**********************************************************************
852  convencience wrapper around rpccli_spoolss_GetPrinterData
853 **********************************************************************/
854
855 WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli,
856                                      TALLOC_CTX *mem_ctx,
857                                      struct policy_handle *handle,
858                                      const char *value_name,
859                                      uint32_t offered,
860                                      enum winreg_Type *type,
861                                      uint32_t *needed_p,
862                                      uint8_t **data_p)
863 {
864         NTSTATUS status;
865         WERROR werror;
866         uint32_t needed;
867         uint8_t *data;
868         struct dcerpc_binding_handle *b = cli->binding_handle;
869
870         data = talloc_zero_array(mem_ctx, uint8_t, offered);
871         W_ERROR_HAVE_NO_MEMORY(data);
872
873         status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
874                                                handle,
875                                                value_name,
876                                                type,
877                                                data,
878                                                offered,
879                                                &needed,
880                                                &werror);
881         if (!NT_STATUS_IS_OK(status)) {
882                 return ntstatus_to_werror(status);
883         }
884
885         if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
886                 offered = needed;
887                 data = talloc_zero_array(mem_ctx, uint8_t, offered);
888                 W_ERROR_HAVE_NO_MEMORY(data);
889
890                 status = dcerpc_spoolss_GetPrinterData(b, mem_ctx,
891                                                        handle,
892                                                        value_name,
893                                                        type,
894                                                        data,
895                                                        offered,
896                                                        &needed,
897                                                        &werror);
898         }
899         if (!NT_STATUS_IS_OK(status)) {
900                 return ntstatus_to_werror(status);
901         }
902
903         *data_p = data;
904         *needed_p = needed;
905
906         return werror;
907 }
908
909 /**********************************************************************
910  convencience wrapper around rpccli_spoolss_EnumPrinterKey
911 **********************************************************************/
912
913 WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli,
914                                      TALLOC_CTX *mem_ctx,
915                                      struct policy_handle *handle,
916                                      const char *key_name,
917                                      const char ***key_buffer,
918                                      uint32_t offered)
919 {
920         NTSTATUS status;
921         WERROR werror;
922         uint32_t needed;
923         union spoolss_KeyNames _key_buffer;
924         uint32_t _ndr_size;
925         struct dcerpc_binding_handle *b = cli->binding_handle;
926
927         status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx,
928                                                handle,
929                                                key_name,
930                                                &_ndr_size,
931                                                &_key_buffer,
932                                                offered,
933                                                &needed,
934                                                &werror);
935         if (!NT_STATUS_IS_OK(status)) {
936                 return ntstatus_to_werror(status);
937         }
938
939         if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
940                 offered = needed;
941                 status = dcerpc_spoolss_EnumPrinterKey(b, mem_ctx,
942                                                        handle,
943                                                        key_name,
944                                                        &_ndr_size,
945                                                        &_key_buffer,
946                                                        offered,
947                                                        &needed,
948                                                        &werror);
949         }
950         if (!NT_STATUS_IS_OK(status)) {
951                 return ntstatus_to_werror(status);
952         }
953
954         *key_buffer = _key_buffer.string_array;
955
956         return werror;
957 }
958
959 /**********************************************************************
960  convencience wrapper around rpccli_spoolss_EnumPrinterDataEx
961 **********************************************************************/
962
963 WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli,
964                                         TALLOC_CTX *mem_ctx,
965                                         struct policy_handle *handle,
966                                         const char *key_name,
967                                         uint32_t offered,
968                                         uint32_t *count,
969                                         struct spoolss_PrinterEnumValues **info)
970 {
971         NTSTATUS status;
972         WERROR werror;
973         uint32_t needed;
974         struct dcerpc_binding_handle *b = cli->binding_handle;
975
976         status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx,
977                                                   handle,
978                                                   key_name,
979                                                   offered,
980                                                   count,
981                                                   info,
982                                                   &needed,
983                                                   &werror);
984         if (!NT_STATUS_IS_OK(status)) {
985                 return ntstatus_to_werror(status);
986         }
987
988         if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
989                 offered = needed;
990
991                 status = dcerpc_spoolss_EnumPrinterDataEx(b, mem_ctx,
992                                                           handle,
993                                                           key_name,
994                                                           offered,
995                                                           count,
996                                                           info,
997                                                           &needed,
998                                                           &werror);
999         }
1000         if (!NT_STATUS_IS_OK(status)) {
1001                 return ntstatus_to_werror(status);
1002         }
1003
1004         return werror;
1005 }