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