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