Memory leaks and other fixes found by Coverity
[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 "rpc_client.h"
27
28 /*********************************************************************
29  Decode various spoolss rpc's and info levels
30  ********************************************************************/
31
32 /**********************************************************************
33 **********************************************************************/
34
35 static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
36                                 uint32 returned, PRINTER_INFO_0 **info)
37 {
38         uint32 i;
39         PRINTER_INFO_0  *inf;
40
41         if (returned) {
42                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_0, returned);
43                 if (!inf) {
44                         return False;
45                 }
46                 memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
47         } else {
48                 inf = NULL;
49         }
50
51         prs_set_offset(&buffer->prs,0);
52
53         for (i=0; i<returned; i++) {
54                 if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) {
55                         return False;
56                 }
57         }
58
59         *info=inf;
60         return True;
61 }
62
63 /**********************************************************************
64 **********************************************************************/
65
66 static bool decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
67                                 uint32 returned, PRINTER_INFO_1 **info)
68 {
69         uint32 i;
70         PRINTER_INFO_1  *inf;
71
72         if (returned) {
73                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_1, returned);
74                 if (!inf) {
75                         return False;
76                 }
77                 memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
78         } else {
79                 inf = NULL;
80         }
81
82         prs_set_offset(&buffer->prs,0);
83
84         for (i=0; i<returned; i++) {
85                 if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) {
86                         return False;
87                 }
88         }
89
90         *info=inf;
91         return True;
92 }
93
94 /**********************************************************************
95 **********************************************************************/
96
97 static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
98                                 uint32 returned, PRINTER_INFO_2 **info)
99 {
100         uint32 i;
101         PRINTER_INFO_2  *inf;
102
103         if (returned) {
104                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_2, returned);
105                 if (!inf) {
106                         return False;
107                 }
108                 memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
109         } else {
110                 inf = NULL;
111         }
112
113         prs_set_offset(&buffer->prs,0);
114
115         for (i=0; i<returned; i++) {
116                 /* a little initialization as we go */
117                 inf[i].secdesc = NULL;
118                 if (!smb_io_printer_info_2("", buffer, &inf[i], 0)) {
119                         return False;
120                 }
121         }
122
123         *info=inf;
124         return True;
125 }
126
127 /**********************************************************************
128 **********************************************************************/
129
130 static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
131                                 uint32 returned, PRINTER_INFO_3 **info)
132 {
133         uint32 i;
134         PRINTER_INFO_3  *inf;
135
136         if (returned) {
137                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_3, returned);
138                 if (!inf) {
139                         return False;
140                 }
141                 memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
142         } else {
143                 inf = NULL;
144         }
145
146         prs_set_offset(&buffer->prs,0);
147
148         for (i=0; i<returned; i++) {
149                 inf[i].secdesc = NULL;
150                 if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) {
151                         return False;
152                 }
153         }
154
155         *info=inf;
156         return True;
157 }
158
159 /**********************************************************************
160 **********************************************************************/
161
162 static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
163                                 uint32 returned, PRINTER_INFO_7 **info)
164 {
165         uint32 i;
166         PRINTER_INFO_7  *inf;
167
168         if (returned) {
169                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned);
170                 if (!inf) {
171                         return False;
172                 }
173                 memset(inf, 0, returned*sizeof(PRINTER_INFO_7));
174         } else {
175                 inf = NULL;
176         }
177
178         prs_set_offset(&buffer->prs,0);
179
180         for (i=0; i<returned; i++) {
181                 if (!smb_io_printer_info_7("", buffer, &inf[i], 0)) {
182                         return False;
183                 }
184         }
185
186         *info=inf;
187         return True;
188 }
189
190
191 /**********************************************************************
192 **********************************************************************/
193
194 static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
195                         uint32 returned, PORT_INFO_1 **info)
196 {
197         uint32 i;
198         PORT_INFO_1 *inf;
199
200         if (returned) {
201                 inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_1, returned);
202                 if (!inf) {
203                         return False;
204                 }
205                 memset(inf, 0, returned*sizeof(PORT_INFO_1));
206         } else {
207                 inf = NULL;
208         }
209
210         prs_set_offset(&buffer->prs, 0);
211
212         for (i=0; i<returned; i++) {
213                 if (!smb_io_port_info_1("", buffer, &(inf[i]), 0)) {
214                         return False;
215                 }
216         }
217
218         *info=inf;
219         return True;
220 }
221
222 /**********************************************************************
223 **********************************************************************/
224
225 static bool decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
226                         uint32 returned, PORT_INFO_2 **info)
227 {
228         uint32 i;
229         PORT_INFO_2 *inf;
230
231         if (returned) {
232                 inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_2, returned);
233                 if (!inf) {
234                         return False;
235                 }
236                 memset(inf, 0, returned*sizeof(PORT_INFO_2));
237         } else {
238                 inf = NULL;
239         }
240
241         prs_set_offset(&buffer->prs, 0);
242
243         for (i=0; i<returned; i++) {
244                 if (!smb_io_port_info_2("", buffer, &(inf[i]), 0)) {
245                         return False;
246                 }
247         }
248
249         *info=inf;
250         return True;
251 }
252
253 /**********************************************************************
254 **********************************************************************/
255
256 static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
257                         uint32 returned, DRIVER_INFO_1 **info)
258 {
259         uint32 i;
260         DRIVER_INFO_1 *inf;
261
262         if (returned) {
263                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_1, returned);
264                 if (!inf) {
265                         return False;
266                 }
267                 memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
268         } else {
269                 inf = NULL;
270         }
271
272         prs_set_offset(&buffer->prs,0);
273
274         for (i=0; i<returned; i++) {
275                 if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) {
276                         return False;
277                 }
278         }
279
280         *info=inf;
281         return True;
282 }
283
284 /**********************************************************************
285 **********************************************************************/
286
287 static bool decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
288                         uint32 returned, DRIVER_INFO_2 **info)
289 {
290         uint32 i;
291         DRIVER_INFO_2 *inf;
292
293         if (returned) {
294                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_2, returned);
295                 if (!inf) {
296                         return False;
297                 }
298                 memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
299         } else {
300                 inf = NULL;
301         }
302
303         prs_set_offset(&buffer->prs,0);
304
305         for (i=0; i<returned; i++) {
306                 if (!smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0)) {
307                         return False;
308                 }
309         }
310
311         *info=inf;
312         return True;
313 }
314
315 /**********************************************************************
316 **********************************************************************/
317
318 static bool decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
319                         uint32 returned, DRIVER_INFO_3 **info)
320 {
321         uint32 i;
322         DRIVER_INFO_3 *inf;
323
324         if (returned) {
325                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_3, returned);
326                 if (!inf) {
327                         return False;
328                 }
329                 memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
330         } else {
331                 inf = NULL;
332         }
333
334         prs_set_offset(&buffer->prs,0);
335
336         for (i=0; i<returned; i++) {
337                 if (!smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0)) {
338                         return False;
339                 }
340         }
341
342         *info=inf;
343         return True;
344 }
345
346 /**********************************************************************
347 **********************************************************************/
348
349 static bool decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
350                         uint32 returned, DRIVER_DIRECTORY_1 **info
351 )
352 {
353         DRIVER_DIRECTORY_1 *inf;
354  
355         inf=TALLOC_P(mem_ctx, DRIVER_DIRECTORY_1);
356         if (!inf) {
357                 return False;
358         }
359         memset(inf, 0, sizeof(DRIVER_DIRECTORY_1));
360
361         prs_set_offset(&buffer->prs, 0);
362
363         if (!smb_io_driverdir_1("", buffer, inf, 0)) {
364                 return False;
365         }
366  
367         *info=inf;
368         return True;
369 }
370
371 /**********************************************************************
372 **********************************************************************/
373
374 static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
375                           uint32 num_jobs, JOB_INFO_1 **jobs)
376 {
377         uint32 i;
378
379         if (num_jobs) {
380                 *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_1, num_jobs);
381                 if (*jobs == NULL) {
382                         return False;
383                 }
384         } else {
385                 *jobs = NULL;
386         }
387         prs_set_offset(&buffer->prs,0);
388
389         for (i = 0; i < num_jobs; i++) {
390                 if (!smb_io_job_info_1("", buffer, &((*jobs)[i]), 0)) {
391                         return False;
392                 }
393         }
394
395         return True;
396 }
397
398 /**********************************************************************
399 **********************************************************************/
400
401 static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
402                           uint32 num_jobs, JOB_INFO_2 **jobs)
403 {
404         uint32 i;
405
406         if (num_jobs) {
407                 *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_2, num_jobs);
408                 if (*jobs == NULL) {
409                         return False;
410                 }
411         } else {
412                 *jobs = NULL;
413         }
414         prs_set_offset(&buffer->prs,0);
415
416         for (i = 0; i < num_jobs; i++) {
417                 if (!smb_io_job_info_2("", buffer, &((*jobs)[i]), 0)) {
418                         return False;
419                 }
420         }
421
422         return True;
423 }
424
425 /**********************************************************************
426 **********************************************************************/
427
428 static bool decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
429                            uint32 num_forms, FORM_1 **forms)
430 {
431         int i;
432
433         if (num_forms) {
434                 *forms = TALLOC_ARRAY(mem_ctx, FORM_1, num_forms);
435                 if (*forms == NULL) {
436                         return False;
437                 }
438         } else {
439                 *forms = NULL;
440         }
441
442         prs_set_offset(&buffer->prs,0);
443
444         for (i = 0; i < num_forms; i++) {
445                 if (!smb_io_form_1("", buffer, &((*forms)[i]), 0)) {
446                         return False;
447                 }
448         }
449
450         return True;
451 }
452
453 /**********************************************************************
454 **********************************************************************/
455
456 WERROR rpccli_spoolss_open_printer_ex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
457                                 const char *printername, const char *datatype, uint32 access_required,
458                                 const char *station, const char *username, POLICY_HND *pol)
459 {
460         prs_struct qbuf, rbuf;
461         SPOOL_Q_OPEN_PRINTER_EX in;
462         SPOOL_R_OPEN_PRINTER_EX out;
463
464         ZERO_STRUCT(in);
465         ZERO_STRUCT(out);
466
467         make_spoolss_q_open_printer_ex( &in, printername, datatype,
468                 access_required, station, username );
469
470         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_OPENPRINTEREX,
471                     in, out, 
472                     qbuf, rbuf,
473                     spoolss_io_q_open_printer_ex,
474                     spoolss_io_r_open_printer_ex, 
475                     WERR_GENERAL_FAILURE );
476
477         memcpy( pol, &out.handle, sizeof(POLICY_HND) );
478         
479         return out.status;
480 }
481
482 /**********************************************************************
483 **********************************************************************/
484
485 WERROR rpccli_spoolss_close_printer(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
486                                  POLICY_HND *pol)
487 {
488         prs_struct qbuf, rbuf;
489         SPOOL_Q_CLOSEPRINTER in;
490         SPOOL_R_CLOSEPRINTER out;
491
492         ZERO_STRUCT(in);
493         ZERO_STRUCT(out);
494
495         make_spoolss_q_closeprinter( &in, pol );
496
497         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_CLOSEPRINTER,
498                     in, out, 
499                     qbuf, rbuf,
500                     spoolss_io_q_closeprinter,
501                     spoolss_io_r_closeprinter, 
502                     WERR_GENERAL_FAILURE );
503                     
504         return out.status;
505 }
506
507 /**********************************************************************
508 **********************************************************************/
509
510 WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
511                                  char *name, uint32 flags, uint32 level,
512                                  uint32 *num_printers, PRINTER_INFO_CTR *ctr)
513 {
514         prs_struct qbuf, rbuf;
515         SPOOL_Q_ENUMPRINTERS in;
516         SPOOL_R_ENUMPRINTERS out;
517         RPC_BUFFER buffer;
518         uint32 offered;
519
520         ZERO_STRUCT(in);
521         ZERO_STRUCT(out);
522
523         offered = 0;
524         if (!rpcbuf_init(&buffer, offered, mem_ctx))
525                 return WERR_NOMEM;
526         make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
527
528         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
529                     in, out, 
530                     qbuf, rbuf,
531                     spoolss_io_q_enumprinters,
532                     spoolss_io_r_enumprinters, 
533                     WERR_GENERAL_FAILURE );
534                     
535         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
536                 offered = out.needed;
537                 
538                 ZERO_STRUCT(in);
539                 ZERO_STRUCT(out);
540
541                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
542                         return WERR_NOMEM;
543                 make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
544
545                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
546                             in, out, 
547                             qbuf, rbuf,
548                             spoolss_io_q_enumprinters,
549                             spoolss_io_r_enumprinters, 
550                             WERR_GENERAL_FAILURE );
551         }
552
553         if ( !W_ERROR_IS_OK(out.status) )
554                 return out.status;
555
556         switch (level) {
557         case 0:
558                 if (!decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0)) {
559                         return WERR_GENERAL_FAILURE;
560                 }
561                 break;
562         case 1:
563                 if (!decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1)) {
564                         return WERR_GENERAL_FAILURE;
565                 }
566                 break;
567         case 2:
568                 if (!decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2)) {
569                         return WERR_GENERAL_FAILURE;
570                 }
571                 break;
572         case 3:
573                 if (!decode_printer_info_3(mem_ctx, out.buffer, out.returned, &ctr->printers_3)) {
574                         return WERR_GENERAL_FAILURE;
575                 }
576                 break;
577         default:
578                 return WERR_UNKNOWN_LEVEL;
579         }                       
580
581         *num_printers = out.returned;
582
583         return out.status;
584 }
585
586 /**********************************************************************
587 **********************************************************************/
588
589 WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
590                               uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
591 {
592         prs_struct qbuf, rbuf;
593         SPOOL_Q_ENUMPORTS in;
594         SPOOL_R_ENUMPORTS out;
595         RPC_BUFFER buffer;
596         fstring server;
597         uint32 offered;
598
599         ZERO_STRUCT(in);
600         ZERO_STRUCT(out);
601
602         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
603         strupper_m(server);
604
605         offered = 0;
606         if (!rpcbuf_init(&buffer, offered, mem_ctx))
607                 return WERR_NOMEM;
608         make_spoolss_q_enumports( &in, server, level, &buffer, offered );
609         
610         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
611                     in, out, 
612                     qbuf, rbuf,
613                     spoolss_io_q_enumports,
614                     spoolss_io_r_enumports, 
615                     WERR_GENERAL_FAILURE );
616                         
617         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
618                 offered = out.needed;
619                 
620                 ZERO_STRUCT(in);
621                 ZERO_STRUCT(out);
622                 
623                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
624                         return WERR_NOMEM;
625                 make_spoolss_q_enumports( &in, server, level, &buffer, offered );
626
627                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
628                             in, out, 
629                             qbuf, rbuf,
630                             spoolss_io_q_enumports,
631                             spoolss_io_r_enumports, 
632                             WERR_GENERAL_FAILURE );
633         }
634         
635         if ( !W_ERROR_IS_OK(out.status) )
636                 return out.status;
637         
638         switch (level) {
639         case 1:
640                 if (!decode_port_info_1(mem_ctx, out.buffer, out.returned, &ctr->port.info_1)) {
641                         return WERR_GENERAL_FAILURE;
642                 }
643                 break;
644         case 2:
645                 if (!decode_port_info_2(mem_ctx, out.buffer, out.returned, &ctr->port.info_2)) {
646                         return WERR_GENERAL_FAILURE;
647                 }
648                 break;
649         default:
650                 return WERR_UNKNOWN_LEVEL;
651         }
652
653         *num_ports = out.returned;
654
655         return out.status;
656 }
657
658 /**********************************************************************
659 **********************************************************************/
660
661 WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
662                               POLICY_HND *pol, uint32 level, 
663                               PRINTER_INFO_CTR *ctr)
664 {
665         prs_struct qbuf, rbuf;
666         SPOOL_Q_GETPRINTER in;
667         SPOOL_R_GETPRINTER out;
668         RPC_BUFFER buffer;
669         uint32 offered;
670
671         ZERO_STRUCT(in);
672         ZERO_STRUCT(out);
673
674         /* Initialise input parameters */
675
676         offered = 0;
677         if (!rpcbuf_init(&buffer, offered, mem_ctx))
678                 return WERR_NOMEM;
679         make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
680         
681         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
682                     in, out, 
683                     qbuf, rbuf,
684                     spoolss_io_q_getprinter,
685                     spoolss_io_r_getprinter, 
686                     WERR_GENERAL_FAILURE );
687
688         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
689                 offered = out.needed;
690                 
691                 ZERO_STRUCT(in);
692                 ZERO_STRUCT(out);
693                 
694                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
695                         return WERR_NOMEM;
696                 make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
697
698                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
699                             in, out, 
700                             qbuf, rbuf,
701                             spoolss_io_q_getprinter,
702                             spoolss_io_r_getprinter, 
703                             WERR_GENERAL_FAILURE );
704         }
705         
706         if ( !W_ERROR_IS_OK(out.status) )
707                 return out.status;
708                 
709         switch (level) {
710         case 0:
711                 if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) {
712                         return WERR_GENERAL_FAILURE;
713                 }
714                 break;
715         case 1:
716                 if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) {
717                         return WERR_GENERAL_FAILURE;
718                 }
719                 break;
720         case 2:
721                 if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) {
722                         return WERR_GENERAL_FAILURE;
723                 }
724                 break;
725         case 3:
726                 if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) {
727                         return WERR_GENERAL_FAILURE;
728                 }
729                 break;
730         case 7:
731                 if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) {
732                         return WERR_GENERAL_FAILURE;
733                 }
734                 break;
735         default:
736                 return WERR_UNKNOWN_LEVEL;
737         }
738
739         return out.status;
740 }
741
742 /**********************************************************************
743 **********************************************************************/
744
745 WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
746                               POLICY_HND *pol, uint32 level, 
747                               PRINTER_INFO_CTR *ctr, uint32 command)
748 {
749         prs_struct qbuf, rbuf;
750         SPOOL_Q_SETPRINTER in;
751         SPOOL_R_SETPRINTER out;
752
753         ZERO_STRUCT(in);
754         ZERO_STRUCT(out);
755
756         make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command );
757
758         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER,
759                     in, out, 
760                     qbuf, rbuf,
761                     spoolss_io_q_setprinter,
762                     spoolss_io_r_setprinter, 
763                     WERR_GENERAL_FAILURE );
764
765         return out.status;
766 }
767
768 /**********************************************************************
769 **********************************************************************/
770
771 WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, 
772                                     TALLOC_CTX *mem_ctx, 
773                                     POLICY_HND *pol, uint32 level, 
774                                     const char *env, int version, PRINTER_DRIVER_CTR *ctr)
775 {
776         prs_struct qbuf, rbuf;
777         SPOOL_Q_GETPRINTERDRIVER2 in;
778         SPOOL_R_GETPRINTERDRIVER2 out;
779         RPC_BUFFER buffer;
780         fstring server;
781         uint32 offered;
782
783         ZERO_STRUCT(in);
784         ZERO_STRUCT(out);
785
786         fstrcpy(server, cli->desthost);
787         strupper_m(server);
788
789         offered = 0;
790         if (!rpcbuf_init(&buffer, offered, mem_ctx))
791                 return WERR_NOMEM;
792         make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
793                 version, 2, &buffer, offered);
794
795         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
796                     in, out, 
797                     qbuf, rbuf,
798                     spoolss_io_q_getprinterdriver2,
799                     spoolss_io_r_getprinterdriver2, 
800                     WERR_GENERAL_FAILURE );
801                     
802         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
803                 offered = out.needed;
804                 
805                 ZERO_STRUCT(in);
806                 ZERO_STRUCT(out);
807                 
808                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
809                         return WERR_NOMEM;
810                 make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
811                         version, 2, &buffer, offered);
812
813                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
814                             in, out, 
815                             qbuf, rbuf,
816                             spoolss_io_q_getprinterdriver2,
817                             spoolss_io_r_getprinterdriver2, 
818                             WERR_GENERAL_FAILURE );
819         }
820                 
821         if ( !W_ERROR_IS_OK(out.status) )
822                 return out.status;
823
824         switch (level) {
825         case 1:
826                 if (!decode_printer_driver_1(mem_ctx, out.buffer, 1, &ctr->info1)) {
827                         return WERR_GENERAL_FAILURE;
828                 }
829                 break;
830         case 2:
831                 if (!decode_printer_driver_2(mem_ctx, out.buffer, 1, &ctr->info2)) {
832                         return WERR_GENERAL_FAILURE;
833                 }
834                 break;
835         case 3:
836                 if (!decode_printer_driver_3(mem_ctx, out.buffer, 1, &ctr->info3)) {
837                         return WERR_GENERAL_FAILURE;
838                 }
839                 break;
840         default:
841                 return WERR_UNKNOWN_LEVEL;
842         }
843
844         return out.status;      
845 }
846
847 /**********************************************************************
848 **********************************************************************/
849
850 WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, 
851                                        TALLOC_CTX *mem_ctx,
852                                        uint32 level, const char *env,
853                                        uint32 *num_drivers,
854                                        PRINTER_DRIVER_CTR *ctr)
855 {
856         prs_struct qbuf, rbuf;
857         SPOOL_Q_ENUMPRINTERDRIVERS in;
858         SPOOL_R_ENUMPRINTERDRIVERS out;
859         RPC_BUFFER buffer;
860         fstring server;
861         uint32 offered;
862
863         ZERO_STRUCT(in);
864         ZERO_STRUCT(out);
865
866         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
867         strupper_m(server);
868
869         offered = 0;
870         if (!rpcbuf_init(&buffer, offered, mem_ctx))
871                 return WERR_NOMEM;
872         make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
873                 &buffer, offered);
874         
875         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
876                     in, out, 
877                     qbuf, rbuf,
878                     spoolss_io_q_enumprinterdrivers,
879                     spoolss_io_r_enumprinterdrivers, 
880                     WERR_GENERAL_FAILURE );
881
882         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
883                 offered = out.needed;
884                 
885                 ZERO_STRUCT(in);
886                 ZERO_STRUCT(out);
887                 
888                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
889                         return WERR_NOMEM;
890                 make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
891                         &buffer, offered);
892         
893                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
894                             in, out, 
895                             qbuf, rbuf,
896                             spoolss_io_q_enumprinterdrivers,
897                             spoolss_io_r_enumprinterdrivers, 
898                             WERR_GENERAL_FAILURE );
899         }
900         
901         *num_drivers = out.returned;
902
903         if ( !W_ERROR_IS_OK(out.status) )
904                 return out.status;
905                 
906         if ( out.returned ) {
907
908                 switch (level) {
909                 case 1:
910                         if (!decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1)) {
911                                 return WERR_GENERAL_FAILURE;
912                         }
913                         break;
914                 case 2:
915                         if (!decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2)) {
916                                 return WERR_GENERAL_FAILURE;
917                         }
918                         break;
919                 case 3:
920                         if (!decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3)) {
921                                 return WERR_GENERAL_FAILURE;
922                         }
923                         break;
924                 default:
925                         return WERR_UNKNOWN_LEVEL;
926                 }
927         }
928
929         return out.status;
930 }
931
932
933 /**********************************************************************
934 **********************************************************************/
935
936 WERROR rpccli_spoolss_getprinterdriverdir (struct rpc_pipe_client *cli, 
937                                         TALLOC_CTX *mem_ctx,
938                                         uint32 level, char *env,
939                                         DRIVER_DIRECTORY_CTR *ctr)
940 {
941         prs_struct qbuf, rbuf;
942         SPOOL_Q_GETPRINTERDRIVERDIR in;
943         SPOOL_R_GETPRINTERDRIVERDIR out;
944         RPC_BUFFER buffer;
945         fstring server;
946         uint32 offered;
947
948         ZERO_STRUCT(in);
949         ZERO_STRUCT(out);
950
951         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
952         strupper_m(server);
953
954         offered = 0;
955         if (!rpcbuf_init(&buffer, offered, mem_ctx))
956                 return WERR_NOMEM;
957         make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
958                 &buffer, offered );
959
960         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
961                     in, out, 
962                     qbuf, rbuf,
963                     spoolss_io_q_getprinterdriverdir,
964                     spoolss_io_r_getprinterdriverdir, 
965                     WERR_GENERAL_FAILURE );
966                     
967         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
968                 offered = out.needed;
969                 
970                 ZERO_STRUCT(in);
971                 ZERO_STRUCT(out);
972                 
973                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
974                         return WERR_NOMEM;
975                 make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
976                         &buffer, offered );
977
978                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
979                             in, out, 
980                             qbuf, rbuf,
981                             spoolss_io_q_getprinterdriverdir,
982                             spoolss_io_r_getprinterdriverdir, 
983                             WERR_GENERAL_FAILURE );
984         }
985         
986         if (!W_ERROR_IS_OK(out.status))
987                 return out.status;
988                 
989         if (!decode_printerdriverdir_1(mem_ctx, out.buffer, 1, &ctr->info1)) {
990                 return WERR_GENERAL_FAILURE;
991         }
992
993         return out.status;
994 }
995
996 /**********************************************************************
997 **********************************************************************/
998
999 WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli, 
1000                                      TALLOC_CTX *mem_ctx, uint32 level,
1001                                      PRINTER_DRIVER_CTR *ctr)
1002 {
1003         prs_struct qbuf, rbuf;
1004         SPOOL_Q_ADDPRINTERDRIVER in;
1005         SPOOL_R_ADDPRINTERDRIVER out;
1006         fstring server;
1007
1008         ZERO_STRUCT(in);
1009         ZERO_STRUCT(out);
1010         
1011         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1012         strupper_m(server);
1013
1014         make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr );
1015
1016         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTERDRIVER,
1017                     in, out, 
1018                     qbuf, rbuf,
1019                     spoolss_io_q_addprinterdriver,
1020                     spoolss_io_r_addprinterdriver, 
1021                     WERR_GENERAL_FAILURE );
1022
1023         return out.status;                  
1024 }
1025
1026 /**********************************************************************
1027 **********************************************************************/
1028
1029 WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1030                                  uint32 level, PRINTER_INFO_CTR*ctr)
1031 {
1032         prs_struct qbuf, rbuf;
1033         SPOOL_Q_ADDPRINTEREX in;
1034         SPOOL_R_ADDPRINTEREX out;
1035         fstring server, client, user;
1036
1037         ZERO_STRUCT(in);
1038         ZERO_STRUCT(out);
1039         
1040         slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname());
1041         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1042         
1043         strupper_m(client);
1044         strupper_m(server);
1045
1046         fstrcpy  (user, cli->auth->user_name);
1047
1048         make_spoolss_q_addprinterex( mem_ctx, &in, server, client, 
1049                 user, level, ctr);
1050
1051         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTEREX,
1052                     in, out, 
1053                     qbuf, rbuf,
1054                     spoolss_io_q_addprinterex,
1055                     spoolss_io_r_addprinterex, 
1056                     WERR_GENERAL_FAILURE );
1057
1058         return out.status;      
1059 }
1060
1061 /**********************************************************************
1062 **********************************************************************/
1063
1064 WERROR rpccli_spoolss_deleteprinterdriverex(struct rpc_pipe_client *cli, 
1065                                          TALLOC_CTX *mem_ctx, const char *arch,
1066                                          const char *driver, int version)
1067 {
1068         prs_struct qbuf, rbuf;
1069         SPOOL_Q_DELETEPRINTERDRIVEREX in;
1070         SPOOL_R_DELETEPRINTERDRIVEREX out;
1071         fstring server;
1072
1073         ZERO_STRUCT(in);
1074         ZERO_STRUCT(out);
1075
1076         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1077         strupper_m(server);
1078
1079         make_spoolss_q_deleteprinterdriverex( mem_ctx, &in, server, arch, driver, version );
1080
1081         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDRIVEREX,
1082                     in, out, 
1083                     qbuf, rbuf,
1084                     spoolss_io_q_deleteprinterdriverex,
1085                     spoolss_io_r_deleteprinterdriverex, 
1086                     WERR_GENERAL_FAILURE );
1087                     
1088         return out.status;      
1089 }
1090
1091 /**********************************************************************
1092 **********************************************************************/
1093
1094 WERROR rpccli_spoolss_deleteprinterdriver (struct rpc_pipe_client *cli, 
1095                                         TALLOC_CTX *mem_ctx, const char *arch,
1096                                         const char *driver)
1097 {
1098         prs_struct qbuf, rbuf;
1099         SPOOL_Q_DELETEPRINTERDRIVER in;
1100         SPOOL_R_DELETEPRINTERDRIVER out;
1101         fstring server;
1102
1103         ZERO_STRUCT(in);
1104         ZERO_STRUCT(out);
1105
1106         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1107         strupper_m(server);
1108
1109         make_spoolss_q_deleteprinterdriver( mem_ctx, &in, server, arch, driver );
1110
1111         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDRIVER,
1112                     in, out, 
1113                     qbuf, rbuf,
1114                     spoolss_io_q_deleteprinterdriver,
1115                     spoolss_io_r_deleteprinterdriver, 
1116                     WERR_GENERAL_FAILURE );
1117                     
1118         return out.status;      
1119 }
1120
1121 /**********************************************************************
1122 **********************************************************************/
1123
1124 WERROR rpccli_spoolss_getprintprocessordirectory(struct rpc_pipe_client *cli,
1125                                               TALLOC_CTX *mem_ctx,
1126                                               char *name, char *environment,
1127                                               fstring procdir)
1128 {
1129         prs_struct qbuf, rbuf;
1130         SPOOL_Q_GETPRINTPROCESSORDIRECTORY in;
1131         SPOOL_R_GETPRINTPROCESSORDIRECTORY out;
1132         int level = 1;
1133         RPC_BUFFER buffer;
1134         uint32 offered;
1135
1136         ZERO_STRUCT(in);
1137         ZERO_STRUCT(out);
1138
1139         offered = 0;
1140         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1141                 return WERR_NOMEM;
1142         make_spoolss_q_getprintprocessordirectory( &in, name, 
1143                 environment, level, &buffer, offered );
1144
1145         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1146                     in, out, 
1147                     qbuf, rbuf,
1148                     spoolss_io_q_getprintprocessordirectory,
1149                     spoolss_io_r_getprintprocessordirectory, 
1150                     WERR_GENERAL_FAILURE );
1151                     
1152         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1153                 offered = out.needed;
1154                 
1155                 ZERO_STRUCT(in);
1156                 ZERO_STRUCT(out);
1157                 
1158                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1159                         return WERR_NOMEM;
1160                 make_spoolss_q_getprintprocessordirectory( &in, name, 
1161                         environment, level, &buffer, offered );
1162
1163                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1164                             in, out, 
1165                             qbuf, rbuf,
1166                             spoolss_io_q_getprintprocessordirectory,
1167                             spoolss_io_r_getprintprocessordirectory, 
1168                             WERR_GENERAL_FAILURE );
1169         }
1170         
1171         if ( !W_ERROR_IS_OK(out.status) )
1172                 return out.status;
1173         
1174         fstrcpy(procdir, "Not implemented!");
1175         
1176         return out.status;
1177 }
1178
1179 /**********************************************************************
1180 **********************************************************************/
1181
1182 WERROR rpccli_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1183                            POLICY_HND *handle, uint32 level, FORM *form)
1184 {
1185         prs_struct qbuf, rbuf;
1186         SPOOL_Q_ADDFORM in;
1187         SPOOL_R_ADDFORM out;
1188
1189         ZERO_STRUCT(in);
1190         ZERO_STRUCT(out);
1191
1192         make_spoolss_q_addform( &in, handle, level, form );
1193         
1194         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDFORM,
1195                     in, out, 
1196                     qbuf, rbuf,
1197                     spoolss_io_q_addform,
1198                     spoolss_io_r_addform, 
1199                     WERR_GENERAL_FAILURE );
1200
1201         return out.status;
1202 }
1203
1204 /**********************************************************************
1205 **********************************************************************/
1206
1207 WERROR rpccli_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1208                            POLICY_HND *handle, uint32 level, 
1209                            const char *form_name, FORM *form)
1210 {
1211         prs_struct qbuf, rbuf;
1212         SPOOL_Q_SETFORM in;
1213         SPOOL_R_SETFORM out;
1214
1215         ZERO_STRUCT(in);
1216         ZERO_STRUCT(out);
1217
1218         make_spoolss_q_setform( &in, handle, level, form_name, form );
1219         
1220         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETFORM,
1221                     in, out, 
1222                     qbuf, rbuf,
1223                     spoolss_io_q_setform,
1224                     spoolss_io_r_setform, 
1225                     WERR_GENERAL_FAILURE );
1226
1227         return out.status;
1228 }
1229
1230 /**********************************************************************
1231 **********************************************************************/
1232
1233 WERROR rpccli_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1234                            POLICY_HND *handle, const char *formname, 
1235                            uint32 level, FORM_1 *form)
1236 {
1237         prs_struct qbuf, rbuf;
1238         SPOOL_Q_GETFORM in;
1239         SPOOL_R_GETFORM out;
1240         RPC_BUFFER buffer;
1241         uint32 offered;
1242
1243         ZERO_STRUCT(in);
1244         ZERO_STRUCT(out);
1245
1246         offered = 0;
1247         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1248                 return WERR_NOMEM;
1249         make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
1250         
1251         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETFORM,
1252                     in, out, 
1253                     qbuf, rbuf,
1254                     spoolss_io_q_getform,
1255                     spoolss_io_r_getform, 
1256                     WERR_GENERAL_FAILURE );
1257                     
1258         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1259                 offered = out.needed;
1260                 
1261                 ZERO_STRUCT(in);
1262                 ZERO_STRUCT(out);
1263                 
1264                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1265                         return WERR_NOMEM;
1266                 make_spoolss_q_getform( &in, handle, formname, level, &buffer, offered );
1267         
1268                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETFORM,
1269                             in, out, 
1270                             qbuf, rbuf,
1271                             spoolss_io_q_getform,
1272                             spoolss_io_r_getform, 
1273                             WERR_GENERAL_FAILURE );
1274         }
1275         
1276         if (!W_ERROR_IS_OK(out.status))
1277                 return out.status;
1278
1279         if (!smb_io_form_1("", out.buffer, form, 0)) {
1280                 return WERR_GENERAL_FAILURE;
1281         }
1282
1283         return out.status;
1284 }
1285
1286 /**********************************************************************
1287 **********************************************************************/
1288
1289 WERROR rpccli_spoolss_deleteform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1290                               POLICY_HND *handle, const char *form_name)
1291 {
1292         prs_struct qbuf, rbuf;
1293         SPOOL_Q_DELETEFORM in;
1294         SPOOL_R_DELETEFORM out;
1295
1296         ZERO_STRUCT(in);
1297         ZERO_STRUCT(out);
1298
1299         make_spoolss_q_deleteform( &in, handle, form_name );
1300         
1301         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEFORM,
1302                     in, out, 
1303                     qbuf, rbuf,
1304                     spoolss_io_q_deleteform,
1305                     spoolss_io_r_deleteform, 
1306                     WERR_GENERAL_FAILURE );
1307                     
1308         return out.status;
1309 }
1310
1311 /**********************************************************************
1312 **********************************************************************/
1313
1314 WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1315                              POLICY_HND *handle, int level, uint32 *num_forms,
1316                              FORM_1 **forms)
1317 {
1318         prs_struct qbuf, rbuf;
1319         SPOOL_Q_ENUMFORMS in;
1320         SPOOL_R_ENUMFORMS out;
1321         RPC_BUFFER buffer;
1322         uint32 offered;
1323
1324         ZERO_STRUCT(in);
1325         ZERO_STRUCT(out);
1326
1327         offered = 0;
1328         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1329                 return WERR_NOMEM;
1330         make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
1331
1332         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
1333                     in, out, 
1334                     qbuf, rbuf,
1335                     spoolss_io_q_enumforms,
1336                     spoolss_io_r_enumforms, 
1337                     WERR_GENERAL_FAILURE );
1338
1339         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1340                 offered = out.needed;
1341                 
1342                 ZERO_STRUCT(in);
1343                 ZERO_STRUCT(out);
1344
1345                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1346                         return WERR_NOMEM;
1347                 make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
1348
1349                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
1350                             in, out, 
1351                             qbuf, rbuf,
1352                             spoolss_io_q_enumforms,
1353                             spoolss_io_r_enumforms, 
1354                             WERR_GENERAL_FAILURE );
1355         }
1356
1357         if (!W_ERROR_IS_OK(out.status))
1358                 return out.status;
1359
1360         *num_forms = out.numofforms;
1361         
1362         if (!decode_forms_1(mem_ctx, out.buffer, *num_forms, forms)) {
1363                 return WERR_GENERAL_FAILURE;
1364         }
1365
1366         return out.status;
1367 }
1368
1369 /**********************************************************************
1370 **********************************************************************/
1371
1372 WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1373                             POLICY_HND *hnd, uint32 level, uint32 firstjob, 
1374                             uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
1375 {
1376         prs_struct qbuf, rbuf;
1377         SPOOL_Q_ENUMJOBS in;
1378         SPOOL_R_ENUMJOBS out;
1379         RPC_BUFFER buffer;
1380         uint32 offered;
1381
1382         ZERO_STRUCT(in);
1383         ZERO_STRUCT(out);
1384
1385         offered = 0;
1386         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1387                 return WERR_NOMEM;
1388         make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
1389                 &buffer, offered );
1390
1391         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
1392                     in, out, 
1393                     qbuf, rbuf,
1394                     spoolss_io_q_enumjobs,
1395                     spoolss_io_r_enumjobs, 
1396                     WERR_GENERAL_FAILURE );
1397
1398         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1399                 offered = out.needed;
1400                 
1401                 ZERO_STRUCT(in);
1402                 ZERO_STRUCT(out);
1403
1404                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1405                         return WERR_NOMEM;
1406                 make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
1407                         &buffer, offered );
1408
1409                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
1410                             in, out, 
1411                             qbuf, rbuf,
1412                             spoolss_io_q_enumjobs,
1413                             spoolss_io_r_enumjobs, 
1414                             WERR_GENERAL_FAILURE );
1415         }
1416
1417         if (!W_ERROR_IS_OK(out.status))
1418                 return out.status;
1419                 
1420         switch(level) {
1421         case 1:
1422                 if (!decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1)) {
1423                         return WERR_GENERAL_FAILURE;
1424                 }
1425                 break;
1426         case 2:
1427                 if (!decode_jobs_2(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_2)) {
1428                         return WERR_GENERAL_FAILURE;
1429                 }
1430                 break;
1431         default:
1432                 DEBUG(3, ("unsupported info level %d", level));
1433                 return WERR_UNKNOWN_LEVEL;
1434         }
1435         
1436         *returned = out.returned;
1437
1438         return out.status;
1439 }
1440
1441 /**********************************************************************
1442 **********************************************************************/
1443
1444 WERROR rpccli_spoolss_setjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1445                           POLICY_HND *hnd, uint32 jobid, uint32 level, 
1446                           uint32 command)
1447 {
1448         prs_struct qbuf, rbuf;
1449         SPOOL_Q_SETJOB in;
1450         SPOOL_R_SETJOB out;
1451
1452         ZERO_STRUCT(in);
1453         ZERO_STRUCT(out);
1454
1455         make_spoolss_q_setjob( &in, hnd, jobid, level, command );
1456
1457         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETJOB,
1458                     in, out, 
1459                     qbuf, rbuf,
1460                     spoolss_io_q_setjob,
1461                     spoolss_io_r_setjob, 
1462                     WERR_GENERAL_FAILURE );
1463                     
1464         return out.status;
1465 }
1466
1467 /**********************************************************************
1468 **********************************************************************/
1469
1470 WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1471                           POLICY_HND *hnd, uint32 jobid, uint32 level,
1472                           JOB_INFO_CTR *ctr)
1473 {
1474         prs_struct qbuf, rbuf;
1475         SPOOL_Q_GETJOB in;
1476         SPOOL_R_GETJOB out;
1477         RPC_BUFFER buffer;
1478         uint32 offered;
1479
1480         ZERO_STRUCT(in);
1481         ZERO_STRUCT(out);
1482
1483         offered = 0;
1484         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1485                 return WERR_NOMEM;
1486         make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
1487
1488         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
1489                     in, out, 
1490                     qbuf, rbuf,
1491                     spoolss_io_q_getjob,
1492                     spoolss_io_r_getjob, 
1493                     WERR_GENERAL_FAILURE );
1494
1495         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1496                 offered = out.needed;
1497                 
1498                 ZERO_STRUCT(in);
1499                 ZERO_STRUCT(out);
1500                 
1501                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1502                         return WERR_NOMEM;
1503                 make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
1504
1505                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
1506                             in, out, 
1507                             qbuf, rbuf,
1508                             spoolss_io_q_getjob,
1509                             spoolss_io_r_getjob, 
1510                             WERR_GENERAL_FAILURE );
1511         }
1512
1513         if (!W_ERROR_IS_OK(out.status))
1514                 return out.status;
1515
1516         switch(level) {
1517         case 1:
1518                 if (!decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1)) {
1519                         return WERR_GENERAL_FAILURE;
1520                 }
1521                 break;
1522         case 2:
1523                 if (!decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2)) {
1524                         return WERR_GENERAL_FAILURE;
1525                 }
1526                 break;
1527         default:
1528                 return WERR_UNKNOWN_LEVEL;
1529         }
1530
1531         return out.status;
1532 }
1533
1534 /**********************************************************************
1535 **********************************************************************/
1536
1537 WERROR rpccli_spoolss_startpageprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1538                                     POLICY_HND *hnd)
1539 {
1540         prs_struct qbuf, rbuf;
1541         SPOOL_Q_STARTPAGEPRINTER in;
1542         SPOOL_R_STARTPAGEPRINTER out;
1543
1544         ZERO_STRUCT(in);
1545         ZERO_STRUCT(out);
1546
1547         make_spoolss_q_startpageprinter( &in, hnd );
1548
1549         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_STARTPAGEPRINTER,
1550                     in, out, 
1551                     qbuf, rbuf,
1552                     spoolss_io_q_startpageprinter,
1553                     spoolss_io_r_startpageprinter, 
1554                     WERR_GENERAL_FAILURE );
1555                     
1556         return out.status;
1557 }
1558
1559 /**********************************************************************
1560 **********************************************************************/
1561
1562 WERROR rpccli_spoolss_endpageprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1563                                   POLICY_HND *hnd)
1564 {
1565         prs_struct qbuf, rbuf;
1566         SPOOL_Q_ENDPAGEPRINTER in;
1567         SPOOL_R_ENDPAGEPRINTER out;
1568
1569         ZERO_STRUCT(in);
1570         ZERO_STRUCT(out);
1571
1572         make_spoolss_q_endpageprinter( &in, hnd );
1573
1574         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENDPAGEPRINTER,
1575                     in, out, 
1576                     qbuf, rbuf,
1577                     spoolss_io_q_endpageprinter,
1578                     spoolss_io_r_endpageprinter, 
1579                     WERR_GENERAL_FAILURE );
1580                     
1581         return out.status;
1582 }
1583
1584 /**********************************************************************
1585 **********************************************************************/
1586
1587 WERROR rpccli_spoolss_startdocprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1588                                    POLICY_HND *hnd, char *docname, 
1589                                    char *outputfile, char *datatype, 
1590                                    uint32 *jobid)
1591 {
1592         prs_struct qbuf, rbuf;
1593         SPOOL_Q_STARTDOCPRINTER in;
1594         SPOOL_R_STARTDOCPRINTER out;
1595         uint32 level = 1;
1596
1597         ZERO_STRUCT(in);
1598         ZERO_STRUCT(out);
1599
1600         make_spoolss_q_startdocprinter( &in, hnd, level, docname, 
1601                 outputfile, datatype );
1602
1603         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_STARTDOCPRINTER,
1604                     in, out, 
1605                     qbuf, rbuf,
1606                     spoolss_io_q_startdocprinter,
1607                     spoolss_io_r_startdocprinter, 
1608                     WERR_GENERAL_FAILURE );
1609
1610         *jobid = out.jobid;
1611
1612         return out.status;
1613 }
1614
1615 /**********************************************************************
1616 **********************************************************************/
1617
1618 WERROR rpccli_spoolss_enddocprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1619                                   POLICY_HND *hnd)
1620 {
1621         prs_struct qbuf, rbuf;
1622         SPOOL_Q_ENDDOCPRINTER in;
1623         SPOOL_R_ENDDOCPRINTER out;
1624
1625         ZERO_STRUCT(in);
1626         ZERO_STRUCT(out);
1627
1628         make_spoolss_q_enddocprinter( &in, hnd );
1629
1630         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENDDOCPRINTER,
1631                     in, out, 
1632                     qbuf, rbuf,
1633                     spoolss_io_q_enddocprinter,
1634                     spoolss_io_r_enddocprinter, 
1635                     WERR_GENERAL_FAILURE );
1636                     
1637         return out.status;
1638 }
1639
1640 /**********************************************************************
1641 **********************************************************************/
1642
1643 WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1644                                   POLICY_HND *hnd, const char *valuename, 
1645                                   REGISTRY_VALUE *value)
1646 {
1647         prs_struct qbuf, rbuf;
1648         SPOOL_Q_GETPRINTERDATA in;
1649         SPOOL_R_GETPRINTERDATA out;
1650         uint32 offered;
1651
1652         ZERO_STRUCT(in);
1653         ZERO_STRUCT(out);
1654
1655         offered = 0;
1656         make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
1657
1658         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
1659                     in, out, 
1660                     qbuf, rbuf,
1661                     spoolss_io_q_getprinterdata,
1662                     spoolss_io_r_getprinterdata, 
1663                     WERR_GENERAL_FAILURE );
1664
1665         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1666                 offered = out.needed;
1667                 
1668                 ZERO_STRUCT(in);
1669                 ZERO_STRUCT(out);
1670                 
1671                 make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
1672
1673                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
1674                             in, out, 
1675                             qbuf, rbuf,
1676                             spoolss_io_q_getprinterdata,
1677                             spoolss_io_r_getprinterdata, 
1678                             WERR_GENERAL_FAILURE );
1679         }
1680
1681         if (!W_ERROR_IS_OK(out.status))
1682                 return out.status;      
1683
1684         /* Return output parameters */
1685
1686         if (out.needed) {
1687                 value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
1688         } else {
1689                 value->data_p = NULL;
1690         }
1691         value->type = out.type;
1692         value->size = out.size;
1693
1694         return out.status;
1695 }
1696
1697 /**********************************************************************
1698 **********************************************************************/
1699
1700 WERROR rpccli_spoolss_getprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1701                                     POLICY_HND *hnd, const char *keyname, 
1702                                     const char *valuename, 
1703                                     REGISTRY_VALUE *value)
1704 {
1705         prs_struct qbuf, rbuf;
1706         SPOOL_Q_GETPRINTERDATAEX in;
1707         SPOOL_R_GETPRINTERDATAEX out;
1708         uint32 offered = 0;
1709
1710         ZERO_STRUCT(in);
1711         ZERO_STRUCT(out);
1712
1713         make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
1714
1715         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATAEX,
1716                     in, out, 
1717                     qbuf, rbuf,
1718                     spoolss_io_q_getprinterdataex,
1719                     spoolss_io_r_getprinterdataex, 
1720                     WERR_GENERAL_FAILURE );
1721
1722         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1723                 offered = out.needed;
1724                 
1725                 ZERO_STRUCT(in);
1726                 ZERO_STRUCT(out);
1727                 
1728                 make_spoolss_q_getprinterdataex( &in, hnd, keyname, valuename, offered );
1729
1730                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATAEX,
1731                             in, out, 
1732                             qbuf, rbuf,
1733                             spoolss_io_q_getprinterdataex,
1734                             spoolss_io_r_getprinterdataex, 
1735                             WERR_GENERAL_FAILURE );
1736         }
1737
1738         if (!W_ERROR_IS_OK(out.status))
1739                 return out.status;      
1740
1741         /* Return output parameters */
1742
1743         if (out.needed) {
1744                 value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
1745         } else {
1746                 value->data_p = NULL;
1747         }
1748         value->type = out.type;
1749         value->size = out.needed;
1750         
1751         return out.status;
1752 }
1753
1754 /**********************************************************************
1755 **********************************************************************/
1756
1757 WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1758                                   POLICY_HND *hnd, REGISTRY_VALUE *value)
1759 {
1760         prs_struct qbuf, rbuf;
1761         SPOOL_Q_SETPRINTERDATA in;
1762         SPOOL_R_SETPRINTERDATA out;
1763
1764         ZERO_STRUCT(in);
1765         ZERO_STRUCT(out);
1766
1767         make_spoolss_q_setprinterdata( &in, hnd, value->valuename, 
1768                 value->type, (char *)value->data_p, value->size);
1769
1770         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATA,
1771                     in, out, 
1772                     qbuf, rbuf,
1773                     spoolss_io_q_setprinterdata,
1774                     spoolss_io_r_setprinterdata, 
1775                     WERR_GENERAL_FAILURE );
1776                     
1777         return out.status;
1778 }
1779
1780 /**********************************************************************
1781 **********************************************************************/
1782
1783 WERROR rpccli_spoolss_setprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1784                                     POLICY_HND *hnd, char *keyname, 
1785                                     REGISTRY_VALUE *value)
1786 {
1787         prs_struct qbuf, rbuf;
1788         SPOOL_Q_SETPRINTERDATAEX in;
1789         SPOOL_R_SETPRINTERDATAEX out;
1790         
1791         ZERO_STRUCT(in);
1792         ZERO_STRUCT(out);
1793
1794         make_spoolss_q_setprinterdataex( &in, hnd, keyname, value->valuename, 
1795                 value->type, (char *)value->data_p, value->size);
1796
1797         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATAEX,
1798                     in, out, 
1799                     qbuf, rbuf,
1800                     spoolss_io_q_setprinterdataex,
1801                     spoolss_io_r_setprinterdataex, 
1802                     WERR_GENERAL_FAILURE );
1803
1804         return out.status;
1805 }
1806
1807 /**********************************************************************
1808 **********************************************************************/
1809
1810 WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1811                                    POLICY_HND *hnd, uint32 ndx,
1812                                    uint32 value_offered, uint32 data_offered,
1813                                    uint32 *value_needed, uint32 *data_needed,
1814                                    REGISTRY_VALUE *value)
1815 {
1816         prs_struct qbuf, rbuf;
1817         SPOOL_Q_ENUMPRINTERDATA in;
1818         SPOOL_R_ENUMPRINTERDATA out;
1819
1820         ZERO_STRUCT(in);
1821         ZERO_STRUCT(out);
1822
1823         make_spoolss_q_enumprinterdata( &in, hnd, ndx, value_offered, data_offered );
1824
1825         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATA,
1826                     in, out, 
1827                     qbuf, rbuf,
1828                     spoolss_io_q_enumprinterdata,
1829                     spoolss_io_r_enumprinterdata, 
1830                     WERR_GENERAL_FAILURE );
1831
1832         if ( value_needed )
1833                 *value_needed = out.realvaluesize;
1834         if ( data_needed )
1835                 *data_needed = out.realdatasize;
1836                 
1837         if (!W_ERROR_IS_OK(out.status))
1838                 return out.status;
1839
1840         if (value) {
1841                 rpcstr_pull(value->valuename, out.value, sizeof(value->valuename), -1,
1842                             STR_TERMINATE);
1843                 if (out.realdatasize) {
1844                         value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data,
1845                                                        out.realdatasize);
1846                 } else {
1847                         value->data_p = NULL;
1848                 }
1849                 value->type = out.type;
1850                 value->size = out.realdatasize;
1851         }
1852         
1853         return out.status;
1854 }
1855
1856 /**********************************************************************
1857 **********************************************************************/
1858
1859 WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1860                                      POLICY_HND *hnd, const char *keyname, 
1861                                      REGVAL_CTR *ctr)
1862 {
1863         prs_struct qbuf, rbuf;
1864         SPOOL_Q_ENUMPRINTERDATAEX in;
1865         SPOOL_R_ENUMPRINTERDATAEX out;
1866         int i;
1867         uint32 offered;
1868
1869         ZERO_STRUCT(in);
1870         ZERO_STRUCT(out);
1871
1872         offered = 0;
1873         make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
1874
1875         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
1876                     in, out, 
1877                     qbuf, rbuf,
1878                     spoolss_io_q_enumprinterdataex,
1879                     spoolss_io_r_enumprinterdataex, 
1880                     WERR_GENERAL_FAILURE );
1881
1882         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1883                 offered = out.needed;
1884                 
1885                 ZERO_STRUCT(in);
1886                 ZERO_STRUCT(out);
1887                 
1888                 make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
1889
1890                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
1891                             in, out, 
1892                             qbuf, rbuf,
1893                             spoolss_io_q_enumprinterdataex,
1894                             spoolss_io_r_enumprinterdataex, 
1895                             WERR_GENERAL_FAILURE );
1896         }
1897         
1898         if (!W_ERROR_IS_OK(out.status))
1899                 return out.status;
1900
1901         for (i = 0; i < out.returned; i++) {
1902                 PRINTER_ENUM_VALUES *v = &out.ctr.values[i];
1903                 fstring name;
1904
1905                 rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, 
1906                             STR_TERMINATE);
1907                 regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
1908         }
1909
1910         return out.status;
1911 }
1912
1913 /**********************************************************************
1914 **********************************************************************/
1915
1916 WERROR rpccli_spoolss_writeprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1917                                 POLICY_HND *hnd, uint32 data_size, char *data,
1918                                 uint32 *num_written)
1919 {
1920         prs_struct qbuf, rbuf;
1921         SPOOL_Q_WRITEPRINTER in;
1922         SPOOL_R_WRITEPRINTER out;
1923
1924         ZERO_STRUCT(in);
1925         ZERO_STRUCT(out);
1926
1927         make_spoolss_q_writeprinter( &in, hnd, data_size, data );
1928
1929         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_WRITEPRINTER,
1930                     in, out, 
1931                     qbuf, rbuf,
1932                     spoolss_io_q_writeprinter,
1933                     spoolss_io_r_writeprinter, 
1934                     WERR_GENERAL_FAILURE );
1935                     
1936         if (num_written)
1937                 *num_written = out.buffer_written;
1938                 
1939         return out.status;
1940 }
1941
1942 /**********************************************************************
1943 **********************************************************************/
1944
1945 WERROR rpccli_spoolss_deleteprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1946                                      POLICY_HND *hnd, char *valuename)
1947 {
1948         prs_struct qbuf, rbuf;
1949         SPOOL_Q_DELETEPRINTERDATA in;
1950         SPOOL_R_DELETEPRINTERDATA out;
1951
1952         ZERO_STRUCT(in);
1953         ZERO_STRUCT(out);
1954
1955         make_spoolss_q_deleteprinterdata( &in, hnd, valuename );
1956
1957         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDATA,
1958                     in, out, 
1959                     qbuf, rbuf,
1960                     spoolss_io_q_deleteprinterdata,
1961                     spoolss_io_r_deleteprinterdata, 
1962                     WERR_GENERAL_FAILURE );
1963
1964         return out.status;
1965 }
1966
1967 /**********************************************************************
1968 **********************************************************************/
1969
1970 WERROR rpccli_spoolss_deleteprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1971                                        POLICY_HND *hnd, char *keyname, 
1972                                        char *valuename)
1973 {
1974         prs_struct qbuf, rbuf;
1975         SPOOL_Q_DELETEPRINTERDATAEX in;
1976         SPOOL_R_DELETEPRINTERDATAEX out;
1977
1978         ZERO_STRUCT(in);
1979         ZERO_STRUCT(out);
1980
1981         make_spoolss_q_deleteprinterdataex( &in, hnd, keyname, valuename );
1982
1983         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERDATAEX,
1984                     in, out, 
1985                     qbuf, rbuf,
1986                     spoolss_io_q_deleteprinterdataex,
1987                     spoolss_io_r_deleteprinterdataex, 
1988                     WERR_GENERAL_FAILURE );
1989
1990         return out.status;
1991 }
1992
1993 /**********************************************************************
1994 **********************************************************************/
1995
1996 WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1997                                   POLICY_HND *hnd, const char *keyname,
1998                                   uint16 **keylist, uint32 *len)
1999 {
2000         prs_struct qbuf, rbuf;
2001         SPOOL_Q_ENUMPRINTERKEY in;
2002         SPOOL_R_ENUMPRINTERKEY out;
2003         uint32 offered = 0;
2004
2005         ZERO_STRUCT(in);
2006         ZERO_STRUCT(out);
2007
2008         make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
2009
2010         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
2011                     in, out, 
2012                     qbuf, rbuf,
2013                     spoolss_io_q_enumprinterkey,
2014                     spoolss_io_r_enumprinterkey, 
2015                     WERR_GENERAL_FAILURE );
2016
2017         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
2018                 offered = out.needed;
2019                 
2020                 ZERO_STRUCT(in);
2021                 ZERO_STRUCT(out);
2022                 
2023                 make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
2024
2025                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
2026                             in, out, 
2027                             qbuf, rbuf,
2028                             spoolss_io_q_enumprinterkey,
2029                             spoolss_io_r_enumprinterkey, 
2030                             WERR_GENERAL_FAILURE );
2031         }
2032
2033         if ( !W_ERROR_IS_OK(out.status) )
2034                 return out.status;      
2035         
2036         if (keylist) {
2037                 *keylist = SMB_MALLOC_ARRAY(uint16, out.keys.buf_len);
2038                 if (!*keylist) {
2039                         return WERR_NOMEM;
2040                 }
2041                 memcpy(*keylist, out.keys.buffer, out.keys.buf_len * 2);
2042                 if (len)
2043                         *len = out.keys.buf_len * 2;
2044         }
2045
2046         return out.status;
2047 }
2048
2049 /**********************************************************************
2050 **********************************************************************/
2051
2052 WERROR rpccli_spoolss_deleteprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
2053                                     POLICY_HND *hnd, char *keyname)
2054 {
2055         prs_struct qbuf, rbuf;
2056         SPOOL_Q_DELETEPRINTERKEY in;
2057         SPOOL_R_DELETEPRINTERKEY out;
2058
2059         ZERO_STRUCT(in);
2060         ZERO_STRUCT(out);
2061
2062         make_spoolss_q_deleteprinterkey( &in, hnd, keyname );
2063
2064         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_DELETEPRINTERKEY,
2065                     in, out, 
2066                     qbuf, rbuf,
2067                     spoolss_io_q_deleteprinterkey,
2068                     spoolss_io_r_deleteprinterkey, 
2069                     WERR_GENERAL_FAILURE );
2070                     
2071         return out.status;
2072 }
2073
2074 /** @} **/