s3-spoolss: remove old spoolss_SetPrinterDataEx.
[tprouty/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  convencience wrapper around rpccli_spoolss_OpenPrinterEx
30 **********************************************************************/
31
32 WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
33                                      TALLOC_CTX *mem_ctx,
34                                      const char *printername,
35                                      uint32_t access_desired,
36                                      struct policy_handle *handle)
37 {
38         NTSTATUS status;
39         WERROR werror;
40         struct spoolss_DevmodeContainer devmode_ctr;
41         union spoolss_UserLevel userlevel;
42         struct spoolss_UserLevel1 level1;
43
44         ZERO_STRUCT(devmode_ctr);
45
46         level1.size     = 28;
47         level1.client   = cli->srv_name_slash;
48         level1.user     = cli->auth->user_name;
49         level1.build    = 1381;
50         level1.major    = 2;
51         level1.minor    = 0;
52         level1.processor = 0;
53
54         userlevel.level1 = &level1;
55
56         status = rpccli_spoolss_OpenPrinterEx(cli, mem_ctx,
57                                               printername,
58                                               NULL,
59                                               devmode_ctr,
60                                               access_desired,
61                                               1, /* level */
62                                               userlevel,
63                                               handle,
64                                               &werror);
65
66         if (!W_ERROR_IS_OK(werror)) {
67                 return werror;
68         }
69
70         if (!NT_STATUS_IS_OK(status)) {
71                 return ntstatus_to_werror(status);
72         }
73
74         return WERR_OK;
75 }
76
77 /*********************************************************************
78  Decode various spoolss rpc's and info levels
79  ********************************************************************/
80
81 /**********************************************************************
82 **********************************************************************/
83
84 static bool decode_printer_info_0(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
85                                 uint32 returned, PRINTER_INFO_0 **info)
86 {
87         uint32 i;
88         PRINTER_INFO_0  *inf;
89
90         if (returned) {
91                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_0, returned);
92                 if (!inf) {
93                         return False;
94                 }
95                 memset(inf, 0, returned*sizeof(PRINTER_INFO_0));
96         } else {
97                 inf = NULL;
98         }
99
100         prs_set_offset(&buffer->prs,0);
101
102         for (i=0; i<returned; i++) {
103                 if (!smb_io_printer_info_0("", buffer, &inf[i], 0)) {
104                         return False;
105                 }
106         }
107
108         *info=inf;
109         return True;
110 }
111
112 /**********************************************************************
113 **********************************************************************/
114
115 static bool decode_printer_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
116                                 uint32 returned, PRINTER_INFO_1 **info)
117 {
118         uint32 i;
119         PRINTER_INFO_1  *inf;
120
121         if (returned) {
122                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_1, returned);
123                 if (!inf) {
124                         return False;
125                 }
126                 memset(inf, 0, returned*sizeof(PRINTER_INFO_1));
127         } else {
128                 inf = NULL;
129         }
130
131         prs_set_offset(&buffer->prs,0);
132
133         for (i=0; i<returned; i++) {
134                 if (!smb_io_printer_info_1("", buffer, &inf[i], 0)) {
135                         return False;
136                 }
137         }
138
139         *info=inf;
140         return True;
141 }
142
143 /**********************************************************************
144 **********************************************************************/
145
146 static bool decode_printer_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
147                                 uint32 returned, PRINTER_INFO_2 **info)
148 {
149         uint32 i;
150         PRINTER_INFO_2  *inf;
151
152         if (returned) {
153                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_2, returned);
154                 if (!inf) {
155                         return False;
156                 }
157                 memset(inf, 0, returned*sizeof(PRINTER_INFO_2));
158         } else {
159                 inf = NULL;
160         }
161
162         prs_set_offset(&buffer->prs,0);
163
164         for (i=0; i<returned; i++) {
165                 /* a little initialization as we go */
166                 inf[i].secdesc = NULL;
167                 if (!smb_io_printer_info_2("", buffer, &inf[i], 0)) {
168                         return False;
169                 }
170         }
171
172         *info=inf;
173         return True;
174 }
175
176 /**********************************************************************
177 **********************************************************************/
178
179 static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
180                                 uint32 returned, PRINTER_INFO_3 **info)
181 {
182         uint32 i;
183         PRINTER_INFO_3  *inf;
184
185         if (returned) {
186                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_3, returned);
187                 if (!inf) {
188                         return False;
189                 }
190                 memset(inf, 0, returned*sizeof(PRINTER_INFO_3));
191         } else {
192                 inf = NULL;
193         }
194
195         prs_set_offset(&buffer->prs,0);
196
197         for (i=0; i<returned; i++) {
198                 inf[i].secdesc = NULL;
199                 if (!smb_io_printer_info_3("", buffer, &inf[i], 0)) {
200                         return False;
201                 }
202         }
203
204         *info=inf;
205         return True;
206 }
207
208 /**********************************************************************
209 **********************************************************************/
210
211 static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
212                                 uint32 returned, PRINTER_INFO_7 **info)
213 {
214         uint32 i;
215         PRINTER_INFO_7  *inf;
216
217         if (returned) {
218                 inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned);
219                 if (!inf) {
220                         return False;
221                 }
222                 memset(inf, 0, returned*sizeof(PRINTER_INFO_7));
223         } else {
224                 inf = NULL;
225         }
226
227         prs_set_offset(&buffer->prs,0);
228
229         for (i=0; i<returned; i++) {
230                 if (!smb_io_printer_info_7("", buffer, &inf[i], 0)) {
231                         return False;
232                 }
233         }
234
235         *info=inf;
236         return True;
237 }
238
239
240 /**********************************************************************
241 **********************************************************************/
242
243 static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
244                         uint32 returned, PORT_INFO_1 **info)
245 {
246         uint32 i;
247         PORT_INFO_1 *inf;
248
249         if (returned) {
250                 inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_1, returned);
251                 if (!inf) {
252                         return False;
253                 }
254                 memset(inf, 0, returned*sizeof(PORT_INFO_1));
255         } else {
256                 inf = NULL;
257         }
258
259         prs_set_offset(&buffer->prs, 0);
260
261         for (i=0; i<returned; i++) {
262                 if (!smb_io_port_info_1("", buffer, &(inf[i]), 0)) {
263                         return False;
264                 }
265         }
266
267         *info=inf;
268         return True;
269 }
270
271 /**********************************************************************
272 **********************************************************************/
273
274 static bool decode_port_info_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
275                         uint32 returned, PORT_INFO_2 **info)
276 {
277         uint32 i;
278         PORT_INFO_2 *inf;
279
280         if (returned) {
281                 inf=TALLOC_ARRAY(mem_ctx, PORT_INFO_2, returned);
282                 if (!inf) {
283                         return False;
284                 }
285                 memset(inf, 0, returned*sizeof(PORT_INFO_2));
286         } else {
287                 inf = NULL;
288         }
289
290         prs_set_offset(&buffer->prs, 0);
291
292         for (i=0; i<returned; i++) {
293                 if (!smb_io_port_info_2("", buffer, &(inf[i]), 0)) {
294                         return False;
295                 }
296         }
297
298         *info=inf;
299         return True;
300 }
301
302 /**********************************************************************
303 **********************************************************************/
304
305 static bool decode_printer_driver_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
306                         uint32 returned, DRIVER_INFO_1 **info)
307 {
308         uint32 i;
309         DRIVER_INFO_1 *inf;
310
311         if (returned) {
312                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_1, returned);
313                 if (!inf) {
314                         return False;
315                 }
316                 memset(inf, 0, returned*sizeof(DRIVER_INFO_1));
317         } else {
318                 inf = NULL;
319         }
320
321         prs_set_offset(&buffer->prs,0);
322
323         for (i=0; i<returned; i++) {
324                 if (!smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0)) {
325                         return False;
326                 }
327         }
328
329         *info=inf;
330         return True;
331 }
332
333 /**********************************************************************
334 **********************************************************************/
335
336 static bool decode_printer_driver_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
337                         uint32 returned, DRIVER_INFO_2 **info)
338 {
339         uint32 i;
340         DRIVER_INFO_2 *inf;
341
342         if (returned) {
343                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_2, returned);
344                 if (!inf) {
345                         return False;
346                 }
347                 memset(inf, 0, returned*sizeof(DRIVER_INFO_2));
348         } else {
349                 inf = NULL;
350         }
351
352         prs_set_offset(&buffer->prs,0);
353
354         for (i=0; i<returned; i++) {
355                 if (!smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0)) {
356                         return False;
357                 }
358         }
359
360         *info=inf;
361         return True;
362 }
363
364 /**********************************************************************
365 **********************************************************************/
366
367 static bool decode_printer_driver_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
368                         uint32 returned, DRIVER_INFO_3 **info)
369 {
370         uint32 i;
371         DRIVER_INFO_3 *inf;
372
373         if (returned) {
374                 inf=TALLOC_ARRAY(mem_ctx, DRIVER_INFO_3, returned);
375                 if (!inf) {
376                         return False;
377                 }
378                 memset(inf, 0, returned*sizeof(DRIVER_INFO_3));
379         } else {
380                 inf = NULL;
381         }
382
383         prs_set_offset(&buffer->prs,0);
384
385         for (i=0; i<returned; i++) {
386                 if (!smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0)) {
387                         return False;
388                 }
389         }
390
391         *info=inf;
392         return True;
393 }
394
395 /**********************************************************************
396 **********************************************************************/
397
398 static bool decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer,
399                         uint32 returned, DRIVER_DIRECTORY_1 **info
400 )
401 {
402         DRIVER_DIRECTORY_1 *inf;
403  
404         inf=TALLOC_P(mem_ctx, DRIVER_DIRECTORY_1);
405         if (!inf) {
406                 return False;
407         }
408         memset(inf, 0, sizeof(DRIVER_DIRECTORY_1));
409
410         prs_set_offset(&buffer->prs, 0);
411
412         if (!smb_io_driverdir_1("", buffer, inf, 0)) {
413                 return False;
414         }
415  
416         *info=inf;
417         return True;
418 }
419
420 /**********************************************************************
421 **********************************************************************/
422
423 static bool decode_jobs_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
424                           uint32 num_jobs, JOB_INFO_1 **jobs)
425 {
426         uint32 i;
427
428         if (num_jobs) {
429                 *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_1, num_jobs);
430                 if (*jobs == NULL) {
431                         return False;
432                 }
433         } else {
434                 *jobs = NULL;
435         }
436         prs_set_offset(&buffer->prs,0);
437
438         for (i = 0; i < num_jobs; i++) {
439                 if (!smb_io_job_info_1("", buffer, &((*jobs)[i]), 0)) {
440                         return False;
441                 }
442         }
443
444         return True;
445 }
446
447 /**********************************************************************
448 **********************************************************************/
449
450 static bool decode_jobs_2(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
451                           uint32 num_jobs, JOB_INFO_2 **jobs)
452 {
453         uint32 i;
454
455         if (num_jobs) {
456                 *jobs = TALLOC_ARRAY(mem_ctx, JOB_INFO_2, num_jobs);
457                 if (*jobs == NULL) {
458                         return False;
459                 }
460         } else {
461                 *jobs = NULL;
462         }
463         prs_set_offset(&buffer->prs,0);
464
465         for (i = 0; i < num_jobs; i++) {
466                 if (!smb_io_job_info_2("", buffer, &((*jobs)[i]), 0)) {
467                         return False;
468                 }
469         }
470
471         return True;
472 }
473
474 /**********************************************************************
475 **********************************************************************/
476
477 static bool decode_forms_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, 
478                            uint32 num_forms, FORM_1 **forms)
479 {
480         int i;
481
482         if (num_forms) {
483                 *forms = TALLOC_ARRAY(mem_ctx, FORM_1, num_forms);
484                 if (*forms == NULL) {
485                         return False;
486                 }
487         } else {
488                 *forms = NULL;
489         }
490
491         prs_set_offset(&buffer->prs,0);
492
493         for (i = 0; i < num_forms; i++) {
494                 if (!smb_io_form_1("", buffer, &((*forms)[i]), 0)) {
495                         return False;
496                 }
497         }
498
499         return True;
500 }
501
502 /**********************************************************************
503 **********************************************************************/
504
505 WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
506                                  char *name, uint32 flags, uint32 level,
507                                  uint32 *num_printers, PRINTER_INFO_CTR *ctr)
508 {
509         prs_struct qbuf, rbuf;
510         SPOOL_Q_ENUMPRINTERS in;
511         SPOOL_R_ENUMPRINTERS out;
512         RPC_BUFFER buffer;
513         uint32 offered;
514
515         ZERO_STRUCT(in);
516         ZERO_STRUCT(out);
517
518         offered = 0;
519         if (!rpcbuf_init(&buffer, offered, mem_ctx))
520                 return WERR_NOMEM;
521         make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
522
523         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
524                     in, out, 
525                     qbuf, rbuf,
526                     spoolss_io_q_enumprinters,
527                     spoolss_io_r_enumprinters, 
528                     WERR_GENERAL_FAILURE );
529                     
530         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
531                 offered = out.needed;
532                 
533                 ZERO_STRUCT(in);
534                 ZERO_STRUCT(out);
535
536                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
537                         return WERR_NOMEM;
538                 make_spoolss_q_enumprinters( &in, flags, name, level, &buffer, offered );
539
540                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERS,
541                             in, out, 
542                             qbuf, rbuf,
543                             spoolss_io_q_enumprinters,
544                             spoolss_io_r_enumprinters, 
545                             WERR_GENERAL_FAILURE );
546         }
547
548         if ( !W_ERROR_IS_OK(out.status) )
549                 return out.status;
550
551         switch (level) {
552         case 0:
553                 if (!decode_printer_info_0(mem_ctx, out.buffer, out.returned, &ctr->printers_0)) {
554                         return WERR_GENERAL_FAILURE;
555                 }
556                 break;
557         case 1:
558                 if (!decode_printer_info_1(mem_ctx, out.buffer, out.returned, &ctr->printers_1)) {
559                         return WERR_GENERAL_FAILURE;
560                 }
561                 break;
562         case 2:
563                 if (!decode_printer_info_2(mem_ctx, out.buffer, out.returned, &ctr->printers_2)) {
564                         return WERR_GENERAL_FAILURE;
565                 }
566                 break;
567         case 3:
568                 if (!decode_printer_info_3(mem_ctx, out.buffer, out.returned, &ctr->printers_3)) {
569                         return WERR_GENERAL_FAILURE;
570                 }
571                 break;
572         default:
573                 return WERR_UNKNOWN_LEVEL;
574         }                       
575
576         *num_printers = out.returned;
577
578         return out.status;
579 }
580
581 /**********************************************************************
582 **********************************************************************/
583
584 WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
585                               uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr)
586 {
587         prs_struct qbuf, rbuf;
588         SPOOL_Q_ENUMPORTS in;
589         SPOOL_R_ENUMPORTS out;
590         RPC_BUFFER buffer;
591         fstring server;
592         uint32 offered;
593
594         ZERO_STRUCT(in);
595         ZERO_STRUCT(out);
596
597         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
598         strupper_m(server);
599
600         offered = 0;
601         if (!rpcbuf_init(&buffer, offered, mem_ctx))
602                 return WERR_NOMEM;
603         make_spoolss_q_enumports( &in, server, level, &buffer, offered );
604         
605         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
606                     in, out, 
607                     qbuf, rbuf,
608                     spoolss_io_q_enumports,
609                     spoolss_io_r_enumports, 
610                     WERR_GENERAL_FAILURE );
611                         
612         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
613                 offered = out.needed;
614                 
615                 ZERO_STRUCT(in);
616                 ZERO_STRUCT(out);
617                 
618                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
619                         return WERR_NOMEM;
620                 make_spoolss_q_enumports( &in, server, level, &buffer, offered );
621
622                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPORTS,
623                             in, out, 
624                             qbuf, rbuf,
625                             spoolss_io_q_enumports,
626                             spoolss_io_r_enumports, 
627                             WERR_GENERAL_FAILURE );
628         }
629         
630         if ( !W_ERROR_IS_OK(out.status) )
631                 return out.status;
632         
633         switch (level) {
634         case 1:
635                 if (!decode_port_info_1(mem_ctx, out.buffer, out.returned, &ctr->port.info_1)) {
636                         return WERR_GENERAL_FAILURE;
637                 }
638                 break;
639         case 2:
640                 if (!decode_port_info_2(mem_ctx, out.buffer, out.returned, &ctr->port.info_2)) {
641                         return WERR_GENERAL_FAILURE;
642                 }
643                 break;
644         default:
645                 return WERR_UNKNOWN_LEVEL;
646         }
647
648         *num_ports = out.returned;
649
650         return out.status;
651 }
652
653 /**********************************************************************
654 **********************************************************************/
655
656 WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
657                               POLICY_HND *pol, uint32 level, 
658                               PRINTER_INFO_CTR *ctr)
659 {
660         prs_struct qbuf, rbuf;
661         SPOOL_Q_GETPRINTER in;
662         SPOOL_R_GETPRINTER out;
663         RPC_BUFFER buffer;
664         uint32 offered;
665
666         ZERO_STRUCT(in);
667         ZERO_STRUCT(out);
668
669         /* Initialise input parameters */
670
671         offered = 0;
672         if (!rpcbuf_init(&buffer, offered, mem_ctx))
673                 return WERR_NOMEM;
674         make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
675         
676         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
677                     in, out, 
678                     qbuf, rbuf,
679                     spoolss_io_q_getprinter,
680                     spoolss_io_r_getprinter, 
681                     WERR_GENERAL_FAILURE );
682
683         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
684                 offered = out.needed;
685                 
686                 ZERO_STRUCT(in);
687                 ZERO_STRUCT(out);
688                 
689                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
690                         return WERR_NOMEM;
691                 make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered );
692
693                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER,
694                             in, out, 
695                             qbuf, rbuf,
696                             spoolss_io_q_getprinter,
697                             spoolss_io_r_getprinter, 
698                             WERR_GENERAL_FAILURE );
699         }
700         
701         if ( !W_ERROR_IS_OK(out.status) )
702                 return out.status;
703                 
704         switch (level) {
705         case 0:
706                 if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) {
707                         return WERR_GENERAL_FAILURE;
708                 }
709                 break;
710         case 1:
711                 if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) {
712                         return WERR_GENERAL_FAILURE;
713                 }
714                 break;
715         case 2:
716                 if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) {
717                         return WERR_GENERAL_FAILURE;
718                 }
719                 break;
720         case 3:
721                 if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) {
722                         return WERR_GENERAL_FAILURE;
723                 }
724                 break;
725         case 7:
726                 if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) {
727                         return WERR_GENERAL_FAILURE;
728                 }
729                 break;
730         default:
731                 return WERR_UNKNOWN_LEVEL;
732         }
733
734         return out.status;
735 }
736
737 /**********************************************************************
738 **********************************************************************/
739
740 WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
741                               POLICY_HND *pol, uint32 level, 
742                               PRINTER_INFO_CTR *ctr, uint32 command)
743 {
744         prs_struct qbuf, rbuf;
745         SPOOL_Q_SETPRINTER in;
746         SPOOL_R_SETPRINTER out;
747
748         ZERO_STRUCT(in);
749         ZERO_STRUCT(out);
750
751         make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command );
752
753         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER,
754                     in, out, 
755                     qbuf, rbuf,
756                     spoolss_io_q_setprinter,
757                     spoolss_io_r_setprinter, 
758                     WERR_GENERAL_FAILURE );
759
760         return out.status;
761 }
762
763 /**********************************************************************
764 **********************************************************************/
765
766 WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, 
767                                     TALLOC_CTX *mem_ctx, 
768                                     POLICY_HND *pol, uint32 level, 
769                                     const char *env, int version, PRINTER_DRIVER_CTR *ctr)
770 {
771         prs_struct qbuf, rbuf;
772         SPOOL_Q_GETPRINTERDRIVER2 in;
773         SPOOL_R_GETPRINTERDRIVER2 out;
774         RPC_BUFFER buffer;
775         fstring server;
776         uint32 offered;
777
778         ZERO_STRUCT(in);
779         ZERO_STRUCT(out);
780
781         fstrcpy(server, cli->desthost);
782         strupper_m(server);
783
784         offered = 0;
785         if (!rpcbuf_init(&buffer, offered, mem_ctx))
786                 return WERR_NOMEM;
787         make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
788                 version, 2, &buffer, offered);
789
790         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
791                     in, out, 
792                     qbuf, rbuf,
793                     spoolss_io_q_getprinterdriver2,
794                     spoolss_io_r_getprinterdriver2, 
795                     WERR_GENERAL_FAILURE );
796                     
797         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
798                 offered = out.needed;
799                 
800                 ZERO_STRUCT(in);
801                 ZERO_STRUCT(out);
802                 
803                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
804                         return WERR_NOMEM;
805                 make_spoolss_q_getprinterdriver2( &in, pol, env, level, 
806                         version, 2, &buffer, offered);
807
808                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2,
809                             in, out, 
810                             qbuf, rbuf,
811                             spoolss_io_q_getprinterdriver2,
812                             spoolss_io_r_getprinterdriver2, 
813                             WERR_GENERAL_FAILURE );
814         }
815                 
816         if ( !W_ERROR_IS_OK(out.status) )
817                 return out.status;
818
819         switch (level) {
820         case 1:
821                 if (!decode_printer_driver_1(mem_ctx, out.buffer, 1, &ctr->info1)) {
822                         return WERR_GENERAL_FAILURE;
823                 }
824                 break;
825         case 2:
826                 if (!decode_printer_driver_2(mem_ctx, out.buffer, 1, &ctr->info2)) {
827                         return WERR_GENERAL_FAILURE;
828                 }
829                 break;
830         case 3:
831                 if (!decode_printer_driver_3(mem_ctx, out.buffer, 1, &ctr->info3)) {
832                         return WERR_GENERAL_FAILURE;
833                 }
834                 break;
835         default:
836                 return WERR_UNKNOWN_LEVEL;
837         }
838
839         return out.status;      
840 }
841
842 /**********************************************************************
843 **********************************************************************/
844
845 WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, 
846                                        TALLOC_CTX *mem_ctx,
847                                        uint32 level, const char *env,
848                                        uint32 *num_drivers,
849                                        PRINTER_DRIVER_CTR *ctr)
850 {
851         prs_struct qbuf, rbuf;
852         SPOOL_Q_ENUMPRINTERDRIVERS in;
853         SPOOL_R_ENUMPRINTERDRIVERS out;
854         RPC_BUFFER buffer;
855         fstring server;
856         uint32 offered;
857
858         ZERO_STRUCT(in);
859         ZERO_STRUCT(out);
860
861         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
862         strupper_m(server);
863
864         offered = 0;
865         if (!rpcbuf_init(&buffer, offered, mem_ctx))
866                 return WERR_NOMEM;
867         make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
868                 &buffer, offered);
869         
870         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
871                     in, out, 
872                     qbuf, rbuf,
873                     spoolss_io_q_enumprinterdrivers,
874                     spoolss_io_r_enumprinterdrivers, 
875                     WERR_GENERAL_FAILURE );
876
877         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
878                 offered = out.needed;
879                 
880                 ZERO_STRUCT(in);
881                 ZERO_STRUCT(out);
882                 
883                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
884                         return WERR_NOMEM;
885                 make_spoolss_q_enumprinterdrivers( &in, server, env, level, 
886                         &buffer, offered);
887         
888                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDRIVERS,
889                             in, out, 
890                             qbuf, rbuf,
891                             spoolss_io_q_enumprinterdrivers,
892                             spoolss_io_r_enumprinterdrivers, 
893                             WERR_GENERAL_FAILURE );
894         }
895         
896         *num_drivers = out.returned;
897
898         if ( !W_ERROR_IS_OK(out.status) )
899                 return out.status;
900                 
901         if ( out.returned ) {
902
903                 switch (level) {
904                 case 1:
905                         if (!decode_printer_driver_1(mem_ctx, out.buffer, out.returned, &ctr->info1)) {
906                                 return WERR_GENERAL_FAILURE;
907                         }
908                         break;
909                 case 2:
910                         if (!decode_printer_driver_2(mem_ctx, out.buffer, out.returned, &ctr->info2)) {
911                                 return WERR_GENERAL_FAILURE;
912                         }
913                         break;
914                 case 3:
915                         if (!decode_printer_driver_3(mem_ctx, out.buffer, out.returned, &ctr->info3)) {
916                                 return WERR_GENERAL_FAILURE;
917                         }
918                         break;
919                 default:
920                         return WERR_UNKNOWN_LEVEL;
921                 }
922         }
923
924         return out.status;
925 }
926
927
928 /**********************************************************************
929 **********************************************************************/
930
931 WERROR rpccli_spoolss_getprinterdriverdir (struct rpc_pipe_client *cli, 
932                                         TALLOC_CTX *mem_ctx,
933                                         uint32 level, char *env,
934                                         DRIVER_DIRECTORY_CTR *ctr)
935 {
936         prs_struct qbuf, rbuf;
937         SPOOL_Q_GETPRINTERDRIVERDIR in;
938         SPOOL_R_GETPRINTERDRIVERDIR out;
939         RPC_BUFFER buffer;
940         fstring server;
941         uint32 offered;
942
943         ZERO_STRUCT(in);
944         ZERO_STRUCT(out);
945
946         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
947         strupper_m(server);
948
949         offered = 0;
950         if (!rpcbuf_init(&buffer, offered, mem_ctx))
951                 return WERR_NOMEM;
952         make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
953                 &buffer, offered );
954
955         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
956                     in, out, 
957                     qbuf, rbuf,
958                     spoolss_io_q_getprinterdriverdir,
959                     spoolss_io_r_getprinterdriverdir, 
960                     WERR_GENERAL_FAILURE );
961                     
962         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
963                 offered = out.needed;
964                 
965                 ZERO_STRUCT(in);
966                 ZERO_STRUCT(out);
967                 
968                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
969                         return WERR_NOMEM;
970                 make_spoolss_q_getprinterdriverdir( &in, server, env, level, 
971                         &buffer, offered );
972
973                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
974                             in, out, 
975                             qbuf, rbuf,
976                             spoolss_io_q_getprinterdriverdir,
977                             spoolss_io_r_getprinterdriverdir, 
978                             WERR_GENERAL_FAILURE );
979         }
980         
981         if (!W_ERROR_IS_OK(out.status))
982                 return out.status;
983                 
984         if (!decode_printerdriverdir_1(mem_ctx, out.buffer, 1, &ctr->info1)) {
985                 return WERR_GENERAL_FAILURE;
986         }
987
988         return out.status;
989 }
990
991 /**********************************************************************
992 **********************************************************************/
993
994 WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli, 
995                                      TALLOC_CTX *mem_ctx, uint32 level,
996                                      PRINTER_DRIVER_CTR *ctr)
997 {
998         prs_struct qbuf, rbuf;
999         SPOOL_Q_ADDPRINTERDRIVER in;
1000         SPOOL_R_ADDPRINTERDRIVER out;
1001         fstring server;
1002
1003         ZERO_STRUCT(in);
1004         ZERO_STRUCT(out);
1005         
1006         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1007         strupper_m(server);
1008
1009         make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr );
1010
1011         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTERDRIVER,
1012                     in, out, 
1013                     qbuf, rbuf,
1014                     spoolss_io_q_addprinterdriver,
1015                     spoolss_io_r_addprinterdriver, 
1016                     WERR_GENERAL_FAILURE );
1017
1018         return out.status;                  
1019 }
1020
1021 /**********************************************************************
1022 **********************************************************************/
1023
1024 WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1025                                  uint32 level, PRINTER_INFO_CTR*ctr)
1026 {
1027         prs_struct qbuf, rbuf;
1028         SPOOL_Q_ADDPRINTEREX in;
1029         SPOOL_R_ADDPRINTEREX out;
1030         fstring server, client, user;
1031
1032         ZERO_STRUCT(in);
1033         ZERO_STRUCT(out);
1034         
1035         slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname());
1036         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
1037         
1038         strupper_m(client);
1039         strupper_m(server);
1040
1041         fstrcpy  (user, cli->auth->user_name);
1042
1043         make_spoolss_q_addprinterex( mem_ctx, &in, server, client, 
1044                 user, level, ctr);
1045
1046         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTEREX,
1047                     in, out, 
1048                     qbuf, rbuf,
1049                     spoolss_io_q_addprinterex,
1050                     spoolss_io_r_addprinterex, 
1051                     WERR_GENERAL_FAILURE );
1052
1053         return out.status;      
1054 }
1055
1056 /**********************************************************************
1057 **********************************************************************/
1058
1059 WERROR rpccli_spoolss_getprintprocessordirectory(struct rpc_pipe_client *cli,
1060                                               TALLOC_CTX *mem_ctx,
1061                                               char *name, char *environment,
1062                                               fstring procdir)
1063 {
1064         prs_struct qbuf, rbuf;
1065         SPOOL_Q_GETPRINTPROCESSORDIRECTORY in;
1066         SPOOL_R_GETPRINTPROCESSORDIRECTORY out;
1067         int level = 1;
1068         RPC_BUFFER buffer;
1069         uint32 offered;
1070
1071         ZERO_STRUCT(in);
1072         ZERO_STRUCT(out);
1073
1074         offered = 0;
1075         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1076                 return WERR_NOMEM;
1077         make_spoolss_q_getprintprocessordirectory( &in, name, 
1078                 environment, level, &buffer, offered );
1079
1080         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1081                     in, out, 
1082                     qbuf, rbuf,
1083                     spoolss_io_q_getprintprocessordirectory,
1084                     spoolss_io_r_getprintprocessordirectory, 
1085                     WERR_GENERAL_FAILURE );
1086                     
1087         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1088                 offered = out.needed;
1089                 
1090                 ZERO_STRUCT(in);
1091                 ZERO_STRUCT(out);
1092                 
1093                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1094                         return WERR_NOMEM;
1095                 make_spoolss_q_getprintprocessordirectory( &in, name, 
1096                         environment, level, &buffer, offered );
1097
1098                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
1099                             in, out, 
1100                             qbuf, rbuf,
1101                             spoolss_io_q_getprintprocessordirectory,
1102                             spoolss_io_r_getprintprocessordirectory, 
1103                             WERR_GENERAL_FAILURE );
1104         }
1105         
1106         if ( !W_ERROR_IS_OK(out.status) )
1107                 return out.status;
1108         
1109         fstrcpy(procdir, "Not implemented!");
1110         
1111         return out.status;
1112 }
1113
1114 /**********************************************************************
1115 **********************************************************************/
1116
1117 WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1118                              POLICY_HND *handle, int level, uint32 *num_forms,
1119                              FORM_1 **forms)
1120 {
1121         prs_struct qbuf, rbuf;
1122         SPOOL_Q_ENUMFORMS in;
1123         SPOOL_R_ENUMFORMS out;
1124         RPC_BUFFER buffer;
1125         uint32 offered;
1126
1127         ZERO_STRUCT(in);
1128         ZERO_STRUCT(out);
1129
1130         offered = 0;
1131         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1132                 return WERR_NOMEM;
1133         make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
1134
1135         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
1136                     in, out, 
1137                     qbuf, rbuf,
1138                     spoolss_io_q_enumforms,
1139                     spoolss_io_r_enumforms, 
1140                     WERR_GENERAL_FAILURE );
1141
1142         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1143                 offered = out.needed;
1144                 
1145                 ZERO_STRUCT(in);
1146                 ZERO_STRUCT(out);
1147
1148                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1149                         return WERR_NOMEM;
1150                 make_spoolss_q_enumforms( &in, handle, level, &buffer, offered );
1151
1152                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMFORMS,
1153                             in, out, 
1154                             qbuf, rbuf,
1155                             spoolss_io_q_enumforms,
1156                             spoolss_io_r_enumforms, 
1157                             WERR_GENERAL_FAILURE );
1158         }
1159
1160         if (!W_ERROR_IS_OK(out.status))
1161                 return out.status;
1162
1163         *num_forms = out.numofforms;
1164         
1165         if (!decode_forms_1(mem_ctx, out.buffer, *num_forms, forms)) {
1166                 return WERR_GENERAL_FAILURE;
1167         }
1168
1169         return out.status;
1170 }
1171
1172 /**********************************************************************
1173 **********************************************************************/
1174
1175 WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1176                             POLICY_HND *hnd, uint32 level, uint32 firstjob, 
1177                             uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr)
1178 {
1179         prs_struct qbuf, rbuf;
1180         SPOOL_Q_ENUMJOBS in;
1181         SPOOL_R_ENUMJOBS out;
1182         RPC_BUFFER buffer;
1183         uint32 offered;
1184
1185         ZERO_STRUCT(in);
1186         ZERO_STRUCT(out);
1187
1188         offered = 0;
1189         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1190                 return WERR_NOMEM;
1191         make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
1192                 &buffer, offered );
1193
1194         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
1195                     in, out, 
1196                     qbuf, rbuf,
1197                     spoolss_io_q_enumjobs,
1198                     spoolss_io_r_enumjobs, 
1199                     WERR_GENERAL_FAILURE );
1200
1201         if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) {
1202                 offered = out.needed;
1203                 
1204                 ZERO_STRUCT(in);
1205                 ZERO_STRUCT(out);
1206
1207                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1208                         return WERR_NOMEM;
1209                 make_spoolss_q_enumjobs( &in, hnd, firstjob, num_jobs, level, 
1210                         &buffer, offered );
1211
1212                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMJOBS,
1213                             in, out, 
1214                             qbuf, rbuf,
1215                             spoolss_io_q_enumjobs,
1216                             spoolss_io_r_enumjobs, 
1217                             WERR_GENERAL_FAILURE );
1218         }
1219
1220         if (!W_ERROR_IS_OK(out.status))
1221                 return out.status;
1222                 
1223         switch(level) {
1224         case 1:
1225                 if (!decode_jobs_1(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_1)) {
1226                         return WERR_GENERAL_FAILURE;
1227                 }
1228                 break;
1229         case 2:
1230                 if (!decode_jobs_2(mem_ctx, out.buffer, out.returned, &ctr->job.job_info_2)) {
1231                         return WERR_GENERAL_FAILURE;
1232                 }
1233                 break;
1234         default:
1235                 DEBUG(3, ("unsupported info level %d", level));
1236                 return WERR_UNKNOWN_LEVEL;
1237         }
1238         
1239         *returned = out.returned;
1240
1241         return out.status;
1242 }
1243
1244 /**********************************************************************
1245 **********************************************************************/
1246
1247 WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1248                           POLICY_HND *hnd, uint32 jobid, uint32 level,
1249                           JOB_INFO_CTR *ctr)
1250 {
1251         prs_struct qbuf, rbuf;
1252         SPOOL_Q_GETJOB in;
1253         SPOOL_R_GETJOB out;
1254         RPC_BUFFER buffer;
1255         uint32 offered;
1256
1257         ZERO_STRUCT(in);
1258         ZERO_STRUCT(out);
1259
1260         offered = 0;
1261         if (!rpcbuf_init(&buffer, offered, mem_ctx))
1262                 return WERR_NOMEM;
1263         make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
1264
1265         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
1266                     in, out, 
1267                     qbuf, rbuf,
1268                     spoolss_io_q_getjob,
1269                     spoolss_io_r_getjob, 
1270                     WERR_GENERAL_FAILURE );
1271
1272         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1273                 offered = out.needed;
1274                 
1275                 ZERO_STRUCT(in);
1276                 ZERO_STRUCT(out);
1277                 
1278                 if (!rpcbuf_init(&buffer, offered, mem_ctx))
1279                         return WERR_NOMEM;
1280                 make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered );
1281
1282                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB,
1283                             in, out, 
1284                             qbuf, rbuf,
1285                             spoolss_io_q_getjob,
1286                             spoolss_io_r_getjob, 
1287                             WERR_GENERAL_FAILURE );
1288         }
1289
1290         if (!W_ERROR_IS_OK(out.status))
1291                 return out.status;
1292
1293         switch(level) {
1294         case 1:
1295                 if (!decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1)) {
1296                         return WERR_GENERAL_FAILURE;
1297                 }
1298                 break;
1299         case 2:
1300                 if (!decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2)) {
1301                         return WERR_GENERAL_FAILURE;
1302                 }
1303                 break;
1304         default:
1305                 return WERR_UNKNOWN_LEVEL;
1306         }
1307
1308         return out.status;
1309 }
1310
1311 /**********************************************************************
1312 **********************************************************************/
1313
1314 WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1315                                   POLICY_HND *hnd, const char *valuename, 
1316                                   REGISTRY_VALUE *value)
1317 {
1318         prs_struct qbuf, rbuf;
1319         SPOOL_Q_GETPRINTERDATA in;
1320         SPOOL_R_GETPRINTERDATA out;
1321         uint32 offered;
1322
1323         ZERO_STRUCT(in);
1324         ZERO_STRUCT(out);
1325
1326         offered = 0;
1327         make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
1328
1329         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
1330                     in, out, 
1331                     qbuf, rbuf,
1332                     spoolss_io_q_getprinterdata,
1333                     spoolss_io_r_getprinterdata, 
1334                     WERR_GENERAL_FAILURE );
1335
1336         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1337                 offered = out.needed;
1338                 
1339                 ZERO_STRUCT(in);
1340                 ZERO_STRUCT(out);
1341                 
1342                 make_spoolss_q_getprinterdata( &in, hnd, valuename, offered );
1343
1344                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDATA,
1345                             in, out, 
1346                             qbuf, rbuf,
1347                             spoolss_io_q_getprinterdata,
1348                             spoolss_io_r_getprinterdata, 
1349                             WERR_GENERAL_FAILURE );
1350         }
1351
1352         if (!W_ERROR_IS_OK(out.status))
1353                 return out.status;      
1354
1355         /* Return output parameters */
1356
1357         if (out.needed) {
1358                 value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data, out.needed);
1359         } else {
1360                 value->data_p = NULL;
1361         }
1362         value->type = out.type;
1363         value->size = out.size;
1364
1365         return out.status;
1366 }
1367
1368 /**********************************************************************
1369 **********************************************************************/
1370
1371 WERROR rpccli_spoolss_setprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1372                                   POLICY_HND *hnd, REGISTRY_VALUE *value)
1373 {
1374         prs_struct qbuf, rbuf;
1375         SPOOL_Q_SETPRINTERDATA in;
1376         SPOOL_R_SETPRINTERDATA out;
1377
1378         ZERO_STRUCT(in);
1379         ZERO_STRUCT(out);
1380
1381         make_spoolss_q_setprinterdata( &in, hnd, value->valuename, 
1382                 value->type, (char *)value->data_p, value->size);
1383
1384         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTERDATA,
1385                     in, out, 
1386                     qbuf, rbuf,
1387                     spoolss_io_q_setprinterdata,
1388                     spoolss_io_r_setprinterdata, 
1389                     WERR_GENERAL_FAILURE );
1390                     
1391         return out.status;
1392 }
1393
1394 /**********************************************************************
1395 **********************************************************************/
1396
1397 WERROR rpccli_spoolss_enumprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1398                                    POLICY_HND *hnd, uint32 ndx,
1399                                    uint32 value_offered, uint32 data_offered,
1400                                    uint32 *value_needed, uint32 *data_needed,
1401                                    REGISTRY_VALUE *value)
1402 {
1403         prs_struct qbuf, rbuf;
1404         SPOOL_Q_ENUMPRINTERDATA in;
1405         SPOOL_R_ENUMPRINTERDATA out;
1406
1407         ZERO_STRUCT(in);
1408         ZERO_STRUCT(out);
1409
1410         make_spoolss_q_enumprinterdata( &in, hnd, ndx, value_offered, data_offered );
1411
1412         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATA,
1413                     in, out, 
1414                     qbuf, rbuf,
1415                     spoolss_io_q_enumprinterdata,
1416                     spoolss_io_r_enumprinterdata, 
1417                     WERR_GENERAL_FAILURE );
1418
1419         if ( value_needed )
1420                 *value_needed = out.realvaluesize;
1421         if ( data_needed )
1422                 *data_needed = out.realdatasize;
1423                 
1424         if (!W_ERROR_IS_OK(out.status))
1425                 return out.status;
1426
1427         if (value) {
1428                 rpcstr_pull(value->valuename, out.value, sizeof(value->valuename), -1,
1429                             STR_TERMINATE);
1430                 if (out.realdatasize) {
1431                         value->data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, out.data,
1432                                                        out.realdatasize);
1433                 } else {
1434                         value->data_p = NULL;
1435                 }
1436                 value->type = out.type;
1437                 value->size = out.realdatasize;
1438         }
1439         
1440         return out.status;
1441 }
1442
1443 /**********************************************************************
1444 **********************************************************************/
1445
1446 WERROR rpccli_spoolss_enumprinterdataex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1447                                      POLICY_HND *hnd, const char *keyname, 
1448                                      REGVAL_CTR *ctr)
1449 {
1450         prs_struct qbuf, rbuf;
1451         SPOOL_Q_ENUMPRINTERDATAEX in;
1452         SPOOL_R_ENUMPRINTERDATAEX out;
1453         int i;
1454         uint32 offered;
1455
1456         ZERO_STRUCT(in);
1457         ZERO_STRUCT(out);
1458
1459         offered = 0;
1460         make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
1461
1462         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
1463                     in, out, 
1464                     qbuf, rbuf,
1465                     spoolss_io_q_enumprinterdataex,
1466                     spoolss_io_r_enumprinterdataex, 
1467                     WERR_GENERAL_FAILURE );
1468
1469         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1470                 offered = out.needed;
1471                 
1472                 ZERO_STRUCT(in);
1473                 ZERO_STRUCT(out);
1474                 
1475                 make_spoolss_q_enumprinterdataex( &in, hnd, keyname, offered );
1476
1477                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERDATAEX,
1478                             in, out, 
1479                             qbuf, rbuf,
1480                             spoolss_io_q_enumprinterdataex,
1481                             spoolss_io_r_enumprinterdataex, 
1482                             WERR_GENERAL_FAILURE );
1483         }
1484         
1485         if (!W_ERROR_IS_OK(out.status))
1486                 return out.status;
1487
1488         for (i = 0; i < out.returned; i++) {
1489                 PRINTER_ENUM_VALUES *v = &out.ctr.values[i];
1490                 fstring name;
1491
1492                 rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, 
1493                             STR_TERMINATE);
1494                 regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
1495         }
1496
1497         return out.status;
1498 }
1499
1500 /**********************************************************************
1501 **********************************************************************/
1502
1503 WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
1504                                   POLICY_HND *hnd, const char *keyname,
1505                                   uint16 **keylist, uint32 *len)
1506 {
1507         prs_struct qbuf, rbuf;
1508         SPOOL_Q_ENUMPRINTERKEY in;
1509         SPOOL_R_ENUMPRINTERKEY out;
1510         uint32 offered = 0;
1511
1512         ZERO_STRUCT(in);
1513         ZERO_STRUCT(out);
1514
1515         make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
1516
1517         CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
1518                     in, out, 
1519                     qbuf, rbuf,
1520                     spoolss_io_q_enumprinterkey,
1521                     spoolss_io_r_enumprinterkey, 
1522                     WERR_GENERAL_FAILURE );
1523
1524         if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) {
1525                 offered = out.needed;
1526                 
1527                 ZERO_STRUCT(in);
1528                 ZERO_STRUCT(out);
1529                 
1530                 make_spoolss_q_enumprinterkey( &in, hnd, keyname, offered );
1531
1532                 CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ENUMPRINTERKEY,
1533                             in, out, 
1534                             qbuf, rbuf,
1535                             spoolss_io_q_enumprinterkey,
1536                             spoolss_io_r_enumprinterkey, 
1537                             WERR_GENERAL_FAILURE );
1538         }
1539
1540         if ( !W_ERROR_IS_OK(out.status) )
1541                 return out.status;      
1542         
1543         if (keylist) {
1544                 *keylist = SMB_MALLOC_ARRAY(uint16, out.keys.buf_len);
1545                 if (!*keylist) {
1546                         return WERR_NOMEM;
1547                 }
1548                 memcpy(*keylist, out.keys.buffer, out.keys.buf_len * 2);
1549                 if (len)
1550                         *len = out.keys.buf_len * 2;
1551         }
1552
1553         return out.status;
1554 }
1555
1556 /** @} **/