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