s3-dcerpc: Refactor calculate_data_len_tosend()
[samba.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 "../librpc/gen_ndr/cli_spoolss.h"
27 #include "rpc_client/cli_spoolss.h"
28
29 /**********************************************************************
30  convencience wrapper around rpccli_spoolss_OpenPrinterEx
31 **********************************************************************/
32
33 WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
34                                      TALLOC_CTX *mem_ctx,
35                                      const char *printername,
36                                      uint32_t access_desired,
37                                      struct policy_handle *handle)
38 {
39         NTSTATUS status;
40         WERROR werror;
41         struct spoolss_DevmodeContainer devmode_ctr;
42         union spoolss_UserLevel userlevel;
43         struct spoolss_UserLevel1 level1;
44
45         ZERO_STRUCT(devmode_ctr);
46
47         level1.size     = 28;
48         level1.client   = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
49         W_ERROR_HAVE_NO_MEMORY(level1.client);
50         level1.user     = cli->auth->user_name;
51         level1.build    = 1381;
52         level1.major    = 2;
53         level1.minor    = 0;
54         level1.processor = 0;
55
56         userlevel.level1 = &level1;
57
58         status = rpccli_spoolss_OpenPrinterEx(cli, mem_ctx,
59                                               printername,
60                                               NULL,
61                                               devmode_ctr,
62                                               access_desired,
63                                               1, /* level */
64                                               userlevel,
65                                               handle,
66                                               &werror);
67
68         if (!W_ERROR_IS_OK(werror)) {
69                 return werror;
70         }
71
72         if (!NT_STATUS_IS_OK(status)) {
73                 return ntstatus_to_werror(status);
74         }
75
76         return WERR_OK;
77 }
78
79 /**********************************************************************
80  convencience wrapper around rpccli_spoolss_GetPrinterDriver
81 **********************************************************************/
82
83 WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli,
84                                        TALLOC_CTX *mem_ctx,
85                                        struct policy_handle *handle,
86                                        const char *architecture,
87                                        uint32_t level,
88                                        uint32_t offered,
89                                        union spoolss_DriverInfo *info)
90 {
91         NTSTATUS status;
92         WERROR werror;
93         uint32_t needed;
94         DATA_BLOB buffer;
95
96         if (offered > 0) {
97                 buffer = data_blob_talloc_zero(mem_ctx, offered);
98                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
99         }
100
101         status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx,
102                                                  handle,
103                                                  architecture,
104                                                  level,
105                                                  (offered > 0) ? &buffer : NULL,
106                                                  offered,
107                                                  info,
108                                                  &needed,
109                                                  &werror);
110         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
111                 offered = needed;
112                 buffer = data_blob_talloc_zero(mem_ctx, needed);
113                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
114
115                 status = rpccli_spoolss_GetPrinterDriver(cli, mem_ctx,
116                                                          handle,
117                                                          architecture,
118                                                          level,
119                                                          &buffer,
120                                                          offered,
121                                                          info,
122                                                          &needed,
123                                                          &werror);
124         }
125
126         return werror;
127 }
128
129 /**********************************************************************
130  convencience wrapper around rpccli_spoolss_GetPrinterDriver2
131 **********************************************************************/
132
133 WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
134                                         TALLOC_CTX *mem_ctx,
135                                         struct policy_handle *handle,
136                                         const char *architecture,
137                                         uint32_t level,
138                                         uint32_t offered,
139                                         uint32_t client_major_version,
140                                         uint32_t client_minor_version,
141                                         union spoolss_DriverInfo *info,
142                                         uint32_t *server_major_version,
143                                         uint32_t *server_minor_version)
144 {
145         NTSTATUS status;
146         WERROR werror;
147         uint32_t needed;
148         DATA_BLOB buffer;
149
150         if (offered > 0) {
151                 buffer = data_blob_talloc_zero(mem_ctx, offered);
152                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
153         }
154
155         status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
156                                                   handle,
157                                                   architecture,
158                                                   level,
159                                                   (offered > 0) ? &buffer : NULL,
160                                                   offered,
161                                                   client_major_version,
162                                                   client_minor_version,
163                                                   info,
164                                                   &needed,
165                                                   server_major_version,
166                                                   server_minor_version,
167                                                   &werror);
168         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
169                 offered = needed;
170                 buffer = data_blob_talloc_zero(mem_ctx, needed);
171                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
172
173                 status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
174                                                           handle,
175                                                           architecture,
176                                                           level,
177                                                           &buffer,
178                                                           offered,
179                                                           client_major_version,
180                                                           client_minor_version,
181                                                           info,
182                                                           &needed,
183                                                           server_major_version,
184                                                           server_minor_version,
185                                                           &werror);
186         }
187
188         return werror;
189 }
190
191 /**********************************************************************
192  convencience wrapper around rpccli_spoolss_AddPrinterEx
193 **********************************************************************/
194
195 WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli,
196                                    TALLOC_CTX *mem_ctx,
197                                    struct spoolss_SetPrinterInfoCtr *info_ctr)
198 {
199         WERROR result;
200         NTSTATUS status;
201         struct spoolss_DevmodeContainer devmode_ctr;
202         struct sec_desc_buf secdesc_ctr;
203         struct spoolss_UserLevelCtr userlevel_ctr;
204         struct spoolss_UserLevel1 level1;
205         struct policy_handle handle;
206
207         ZERO_STRUCT(devmode_ctr);
208         ZERO_STRUCT(secdesc_ctr);
209
210         level1.size             = 28;
211         level1.build            = 1381;
212         level1.major            = 2;
213         level1.minor            = 0;
214         level1.processor        = 0;
215         level1.client           = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
216         W_ERROR_HAVE_NO_MEMORY(level1.client);
217         level1.user             = cli->auth->user_name;
218
219         userlevel_ctr.level = 1;
220         userlevel_ctr.user_info.level1 = &level1;
221
222         status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx,
223                                              cli->srv_name_slash,
224                                              info_ctr,
225                                              &devmode_ctr,
226                                              &secdesc_ctr,
227                                              &userlevel_ctr,
228                                              &handle,
229                                              &result);
230         return result;
231 }
232
233 /**********************************************************************
234  convencience wrapper around rpccli_spoolss_GetPrinter
235 **********************************************************************/
236
237 WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli,
238                                  TALLOC_CTX *mem_ctx,
239                                  struct policy_handle *handle,
240                                  uint32_t level,
241                                  uint32_t offered,
242                                  union spoolss_PrinterInfo *info)
243 {
244         NTSTATUS status;
245         WERROR werror;
246         DATA_BLOB buffer;
247         uint32_t needed;
248
249         if (offered > 0) {
250                 buffer = data_blob_talloc_zero(mem_ctx, offered);
251                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
252         }
253
254         status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
255                                            handle,
256                                            level,
257                                            (offered > 0) ? &buffer : NULL,
258                                            offered,
259                                            info,
260                                            &needed,
261                                            &werror);
262
263         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
264
265                 offered = needed;
266                 buffer = data_blob_talloc_zero(mem_ctx, offered);
267                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
268
269                 status = rpccli_spoolss_GetPrinter(cli, mem_ctx,
270                                                    handle,
271                                                    level,
272                                                    &buffer,
273                                                    offered,
274                                                    info,
275                                                    &needed,
276                                                    &werror);
277         }
278
279         return werror;
280 }
281
282 /**********************************************************************
283  convencience wrapper around rpccli_spoolss_GetJob
284 **********************************************************************/
285
286 WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
287                              TALLOC_CTX *mem_ctx,
288                              struct policy_handle *handle,
289                              uint32_t job_id,
290                              uint32_t level,
291                              uint32_t offered,
292                              union spoolss_JobInfo *info)
293 {
294         NTSTATUS status;
295         WERROR werror;
296         uint32_t needed;
297         DATA_BLOB buffer;
298
299         if (offered > 0) {
300                 buffer = data_blob_talloc_zero(mem_ctx, offered);
301                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
302         }
303
304         status = rpccli_spoolss_GetJob(cli, mem_ctx,
305                                        handle,
306                                        job_id,
307                                        level,
308                                        (offered > 0) ? &buffer : NULL,
309                                        offered,
310                                        info,
311                                        &needed,
312                                        &werror);
313
314         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
315                 offered = needed;
316                 buffer = data_blob_talloc_zero(mem_ctx, needed);
317                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
318
319                 status = rpccli_spoolss_GetJob(cli, mem_ctx,
320                                                handle,
321                                                job_id,
322                                                level,
323                                                &buffer,
324                                                offered,
325                                                info,
326                                                &needed,
327                                                &werror);
328         }
329
330         return werror;
331 }
332
333 /**********************************************************************
334  convencience wrapper around rpccli_spoolss_EnumForms
335 **********************************************************************/
336
337 WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli,
338                                 TALLOC_CTX *mem_ctx,
339                                 struct policy_handle *handle,
340                                 uint32_t level,
341                                 uint32_t offered,
342                                 uint32_t *count,
343                                 union spoolss_FormInfo **info)
344 {
345         NTSTATUS status;
346         WERROR werror;
347         uint32_t needed;
348         DATA_BLOB buffer;
349
350         if (offered > 0) {
351                 buffer = data_blob_talloc_zero(mem_ctx, offered);
352                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
353         }
354
355         status = rpccli_spoolss_EnumForms(cli, mem_ctx,
356                                           handle,
357                                           level,
358                                           (offered > 0) ? &buffer : NULL,
359                                           offered,
360                                           count,
361                                           info,
362                                           &needed,
363                                           &werror);
364
365         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
366                 offered = needed;
367                 buffer = data_blob_talloc_zero(mem_ctx, needed);
368                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
369
370                 status = rpccli_spoolss_EnumForms(cli, mem_ctx,
371                                                   handle,
372                                                   level,
373                                                   (offered > 0) ? &buffer : NULL,
374                                                   offered,
375                                                   count,
376                                                   info,
377                                                   &needed,
378                                                   &werror);
379         }
380
381         return werror;
382 }
383
384 /**********************************************************************
385  convencience wrapper around rpccli_spoolss_EnumPrintProcessors
386 **********************************************************************/
387
388 WERROR rpccli_spoolss_enumprintprocessors(struct rpc_pipe_client *cli,
389                                           TALLOC_CTX *mem_ctx,
390                                           const char *servername,
391                                           const char *environment,
392                                           uint32_t level,
393                                           uint32_t offered,
394                                           uint32_t *count,
395                                           union spoolss_PrintProcessorInfo **info)
396 {
397         NTSTATUS status;
398         WERROR werror;
399         uint32_t needed;
400         DATA_BLOB buffer;
401
402         if (offered > 0) {
403                 buffer = data_blob_talloc_zero(mem_ctx, offered);
404                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
405         }
406
407         status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
408                                                     servername,
409                                                     environment,
410                                                     level,
411                                                     (offered > 0) ? &buffer : NULL,
412                                                     offered,
413                                                     count,
414                                                     info,
415                                                     &needed,
416                                                     &werror);
417
418         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
419                 offered = needed;
420                 buffer = data_blob_talloc_zero(mem_ctx, needed);
421                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
422
423                 status = rpccli_spoolss_EnumPrintProcessors(cli, mem_ctx,
424                                                             servername,
425                                                             environment,
426                                                             level,
427                                                             (offered > 0) ? &buffer : NULL,
428                                                             offered,
429                                                             count,
430                                                             info,
431                                                             &needed,
432                                                             &werror);
433         }
434
435         return werror;
436 }
437
438 /**********************************************************************
439  convencience wrapper around rpccli_spoolss_EnumPrintProcDataTypes
440 **********************************************************************/
441
442 WERROR rpccli_spoolss_enumprintprocessordatatypes(struct rpc_pipe_client *cli,
443                                                   TALLOC_CTX *mem_ctx,
444                                                   const char *servername,
445                                                   const char *print_processor_name,
446                                                   uint32_t level,
447                                                   uint32_t offered,
448                                                   uint32_t *count,
449                                                   union spoolss_PrintProcDataTypesInfo **info)
450 {
451         NTSTATUS status;
452         WERROR werror;
453         uint32_t needed;
454         DATA_BLOB buffer;
455
456         if (offered > 0) {
457                 buffer = data_blob_talloc_zero(mem_ctx, offered);
458                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
459         }
460
461         status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
462                                                        servername,
463                                                        print_processor_name,
464                                                        level,
465                                                        (offered > 0) ? &buffer : NULL,
466                                                        offered,
467                                                        count,
468                                                        info,
469                                                        &needed,
470                                                        &werror);
471
472         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
473                 offered = needed;
474                 buffer = data_blob_talloc_zero(mem_ctx, needed);
475                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
476
477                 status = rpccli_spoolss_EnumPrintProcDataTypes(cli, mem_ctx,
478                                                                servername,
479                                                                print_processor_name,
480                                                                level,
481                                                                (offered > 0) ? &buffer : NULL,
482                                                                offered,
483                                                                count,
484                                                                info,
485                                                                &needed,
486                                                                &werror);
487         }
488
489         return werror;
490 }
491
492 /**********************************************************************
493  convencience wrapper around rpccli_spoolss_EnumPorts
494 **********************************************************************/
495
496 WERROR rpccli_spoolss_enumports(struct rpc_pipe_client *cli,
497                                 TALLOC_CTX *mem_ctx,
498                                 const char *servername,
499                                 uint32_t level,
500                                 uint32_t offered,
501                                 uint32_t *count,
502                                 union spoolss_PortInfo **info)
503 {
504         NTSTATUS status;
505         WERROR werror;
506         uint32_t needed;
507         DATA_BLOB buffer;
508
509         if (offered > 0) {
510                 buffer = data_blob_talloc_zero(mem_ctx, offered);
511                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
512         }
513
514         status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
515                                           servername,
516                                           level,
517                                           (offered > 0) ? &buffer : NULL,
518                                           offered,
519                                           count,
520                                           info,
521                                           &needed,
522                                           &werror);
523
524         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
525                 offered = needed;
526                 buffer = data_blob_talloc_zero(mem_ctx, needed);
527                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
528
529                 status = rpccli_spoolss_EnumPorts(cli, mem_ctx,
530                                                   servername,
531                                                   level,
532                                                   (offered > 0) ? &buffer : NULL,
533                                                   offered,
534                                                   count,
535                                                   info,
536                                                   &needed,
537                                                   &werror);
538         }
539
540         return werror;
541 }
542
543 /**********************************************************************
544  convencience wrapper around rpccli_spoolss_EnumMonitors
545 **********************************************************************/
546
547 WERROR rpccli_spoolss_enummonitors(struct rpc_pipe_client *cli,
548                                    TALLOC_CTX *mem_ctx,
549                                    const char *servername,
550                                    uint32_t level,
551                                    uint32_t offered,
552                                    uint32_t *count,
553                                    union spoolss_MonitorInfo **info)
554 {
555         NTSTATUS status;
556         WERROR werror;
557         uint32_t needed;
558         DATA_BLOB buffer;
559
560         if (offered > 0) {
561                 buffer = data_blob_talloc_zero(mem_ctx, offered);
562                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
563         }
564
565         status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
566                                              servername,
567                                              level,
568                                              (offered > 0) ? &buffer : NULL,
569                                              offered,
570                                              count,
571                                              info,
572                                              &needed,
573                                              &werror);
574
575         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
576                 offered = needed;
577                 buffer = data_blob_talloc_zero(mem_ctx, needed);
578                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
579
580                 status = rpccli_spoolss_EnumMonitors(cli, mem_ctx,
581                                                      servername,
582                                                      level,
583                                                      (offered > 0) ? &buffer : NULL,
584                                                      offered,
585                                                      count,
586                                                      info,
587                                                      &needed,
588                                                      &werror);
589         }
590
591         return werror;
592 }
593
594 /**********************************************************************
595  convencience wrapper around rpccli_spoolss_EnumJobs
596 **********************************************************************/
597
598 WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli,
599                                TALLOC_CTX *mem_ctx,
600                                struct policy_handle *handle,
601                                uint32_t firstjob,
602                                uint32_t numjobs,
603                                uint32_t level,
604                                uint32_t offered,
605                                uint32_t *count,
606                                union spoolss_JobInfo **info)
607 {
608         NTSTATUS status;
609         WERROR werror;
610         uint32_t needed;
611         DATA_BLOB buffer;
612
613         if (offered > 0) {
614                 buffer = data_blob_talloc_zero(mem_ctx, offered);
615                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
616         }
617
618         status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
619                                          handle,
620                                          firstjob,
621                                          numjobs,
622                                          level,
623                                          (offered > 0) ? &buffer : NULL,
624                                          offered,
625                                          count,
626                                          info,
627                                          &needed,
628                                          &werror);
629
630         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
631                 offered = needed;
632                 buffer = data_blob_talloc_zero(mem_ctx, needed);
633                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
634
635                 status = rpccli_spoolss_EnumJobs(cli, mem_ctx,
636                                                  handle,
637                                                  firstjob,
638                                                  numjobs,
639                                                  level,
640                                                  (offered > 0) ? &buffer : NULL,
641                                                  offered,
642                                                  count,
643                                                  info,
644                                                  &needed,
645                                                  &werror);
646         }
647
648         return werror;
649 }
650
651 /**********************************************************************
652  convencience wrapper around rpccli_spoolss_EnumPrinterDrivers
653 **********************************************************************/
654
655 WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli,
656                                          TALLOC_CTX *mem_ctx,
657                                          const char *server,
658                                          const char *environment,
659                                          uint32_t level,
660                                          uint32_t offered,
661                                          uint32_t *count,
662                                          union spoolss_DriverInfo **info)
663 {
664         NTSTATUS status;
665         WERROR werror;
666         uint32_t needed;
667         DATA_BLOB buffer;
668
669         if (offered > 0) {
670                 buffer = data_blob_talloc_zero(mem_ctx, offered);
671                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
672         }
673
674         status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
675                                                    server,
676                                                    environment,
677                                                    level,
678                                                    (offered > 0) ? &buffer : NULL,
679                                                    offered,
680                                                    count,
681                                                    info,
682                                                    &needed,
683                                                    &werror);
684
685         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
686                 offered = needed;
687                 buffer = data_blob_talloc_zero(mem_ctx, needed);
688                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
689
690                 status = rpccli_spoolss_EnumPrinterDrivers(cli, mem_ctx,
691                                                    server,
692                                                    environment,
693                                                    level,
694                                                    (offered > 0) ? &buffer : NULL,
695                                                    offered,
696                                                    count,
697                                                    info,
698                                                    &needed,
699                                                    &werror);
700         }
701
702         return werror;
703 }
704
705 /**********************************************************************
706  convencience wrapper around rpccli_spoolss_EnumPrinters
707 **********************************************************************/
708
709 WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
710                                    TALLOC_CTX *mem_ctx,
711                                    uint32_t flags,
712                                    const char *server,
713                                    uint32_t level,
714                                    uint32_t offered,
715                                    uint32_t *count,
716                                    union spoolss_PrinterInfo **info)
717 {
718         NTSTATUS status;
719         WERROR werror;
720         uint32_t needed;
721         DATA_BLOB buffer;
722
723         if (offered > 0) {
724                 buffer = data_blob_talloc_zero(mem_ctx, offered);
725                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
726         }
727
728         status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
729                                              flags,
730                                              server,
731                                              level,
732                                              (offered > 0) ? &buffer : NULL,
733                                              offered,
734                                              count,
735                                              info,
736                                              &needed,
737                                              &werror);
738
739         if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
740                 offered = needed;
741                 buffer = data_blob_talloc_zero(mem_ctx, needed);
742                 W_ERROR_HAVE_NO_MEMORY(buffer.data);
743
744                 status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
745                                                      flags,
746                                                      server,
747                                                      level,
748                                                      (offered > 0) ? &buffer : NULL,
749                                                      offered,
750                                                      count,
751                                                      info,
752                                                      &needed,
753                                                      &werror);
754         }
755
756         return werror;
757 }
758
759 /**********************************************************************
760  convencience wrapper around rpccli_spoolss_GetPrinterData
761 **********************************************************************/
762
763 WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli,
764                                      TALLOC_CTX *mem_ctx,
765                                      struct policy_handle *handle,
766                                      const char *value_name,
767                                      uint32_t offered,
768                                      enum winreg_Type *type,
769                                      uint32_t *needed_p,
770                                      uint8_t **data_p)
771 {
772         NTSTATUS status;
773         WERROR werror;
774         uint32_t needed;
775         uint8_t *data;
776
777         data = talloc_zero_array(mem_ctx, uint8_t, offered);
778         W_ERROR_HAVE_NO_MEMORY(data);
779
780         status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
781                                                handle,
782                                                value_name,
783                                                type,
784                                                data,
785                                                offered,
786                                                &needed,
787                                                &werror);
788
789         if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
790                 offered = needed;
791                 data = talloc_zero_array(mem_ctx, uint8_t, offered);
792                 W_ERROR_HAVE_NO_MEMORY(data);
793
794                 status = rpccli_spoolss_GetPrinterData(cli, mem_ctx,
795                                                        handle,
796                                                        value_name,
797                                                        type,
798                                                        data,
799                                                        offered,
800                                                        &needed,
801                                                        &werror);
802         }
803
804         *data_p = data;
805         *needed_p = needed;
806
807         return werror;
808 }
809
810 /**********************************************************************
811  convencience wrapper around rpccli_spoolss_EnumPrinterKey
812 **********************************************************************/
813
814 WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli,
815                                      TALLOC_CTX *mem_ctx,
816                                      struct policy_handle *handle,
817                                      const char *key_name,
818                                      const char ***key_buffer,
819                                      uint32_t offered)
820 {
821         NTSTATUS status;
822         WERROR werror;
823         uint32_t needed;
824         union spoolss_KeyNames _key_buffer;
825         uint32_t _ndr_size;
826
827         status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
828                                                handle,
829                                                key_name,
830                                                &_ndr_size,
831                                                &_key_buffer,
832                                                offered,
833                                                &needed,
834                                                &werror);
835
836         if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
837                 offered = needed;
838                 status = rpccli_spoolss_EnumPrinterKey(cli, mem_ctx,
839                                                        handle,
840                                                        key_name,
841                                                        &_ndr_size,
842                                                        &_key_buffer,
843                                                        offered,
844                                                        &needed,
845                                                        &werror);
846         }
847
848         *key_buffer = _key_buffer.string_array;
849
850         return werror;
851 }
852
853 /**********************************************************************
854  convencience wrapper around rpccli_spoolss_EnumPrinterDataEx
855 **********************************************************************/
856
857 WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli,
858                                         TALLOC_CTX *mem_ctx,
859                                         struct policy_handle *handle,
860                                         const char *key_name,
861                                         uint32_t offered,
862                                         uint32_t *count,
863                                         struct spoolss_PrinterEnumValues **info)
864 {
865         NTSTATUS status;
866         WERROR werror;
867         uint32_t needed;
868
869         status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
870                                                   handle,
871                                                   key_name,
872                                                   offered,
873                                                   count,
874                                                   info,
875                                                   &needed,
876                                                   &werror);
877
878         if (W_ERROR_EQUAL(werror, WERR_MORE_DATA)) {
879                 offered = needed;
880
881                 status = rpccli_spoolss_EnumPrinterDataEx(cli, mem_ctx,
882                                                           handle,
883                                                           key_name,
884                                                           offered,
885                                                           count,
886                                                           info,
887                                                           &needed,
888                                                           &werror);
889         }
890
891         return werror;
892 }