s4:libcli/rap: the caller should get talloc children from call->ndr_pull_{param,data}
[mat/samba.git] / source4 / libcli / rap / rap.c
1 /*
2    Unix SMB/CIFS implementation.
3    RAP client
4    Copyright (C) Volker Lendecke 2004
5    Copyright (C) Tim Potter 2005
6    Copyright (C) Jelmer Vernooij 2007
7    Copyright (C) Guenther Deschner 2010-2011
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "libcli/libcli.h"
25 #include "../librpc/gen_ndr/ndr_rap.h"
26 #include "libcli/rap/rap.h"
27 #include "librpc/ndr/libndr.h"
28
29 struct rap_call *new_rap_cli_call(TALLOC_CTX *mem_ctx, uint16_t callno)
30 {
31         struct rap_call *call;
32
33         call = talloc_zero(mem_ctx, struct rap_call);
34         if (call == NULL) {
35                 return NULL;
36         }
37
38         call->callno = callno;
39         call->rcv_paramlen = 4;
40
41         call->ndr_push_param = ndr_push_init_ctx(call);
42         call->ndr_push_param->flags = RAPNDR_FLAGS;
43
44         call->ndr_push_data = ndr_push_init_ctx(call);
45         call->ndr_push_data->flags = RAPNDR_FLAGS;
46
47         call->pull_mem_ctx = mem_ctx;
48
49         return call;
50 }
51
52 static void rap_cli_push_paramdesc(struct rap_call *call, char desc)
53 {
54         int len = 0;
55
56         if (call->paramdesc != NULL)
57                 len = strlen(call->paramdesc);
58
59         call->paramdesc = talloc_realloc(call,
60                                          call->paramdesc,
61                                          char,
62                                          len+2);
63
64         call->paramdesc[len] = desc;
65         call->paramdesc[len+1] = '\0';
66 }
67
68 static void rap_cli_push_word(struct rap_call *call, uint16_t val)
69 {
70         rap_cli_push_paramdesc(call, 'W');
71         ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, val);
72 }
73
74 static void rap_cli_push_dword(struct rap_call *call, uint32_t val)
75 {
76         rap_cli_push_paramdesc(call, 'D');
77         ndr_push_uint32(call->ndr_push_param, NDR_SCALARS, val);
78 }
79
80 static void rap_cli_push_rcvbuf(struct rap_call *call, int len)
81 {
82         rap_cli_push_paramdesc(call, 'r');
83         rap_cli_push_paramdesc(call, 'L');
84         ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, len);
85         call->rcv_datalen = len;
86 }
87
88 static void rap_cli_push_sendbuf(struct rap_call *call, int len)
89 {
90         rap_cli_push_paramdesc(call, 's');
91         rap_cli_push_paramdesc(call, 'T');
92         ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, len);
93 }
94
95 static void rap_cli_push_param(struct rap_call *call, uint16_t val)
96 {
97         rap_cli_push_paramdesc(call, 'P');
98         ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, val);
99 }
100
101 static void rap_cli_expect_multiple_entries(struct rap_call *call)
102 {
103         rap_cli_push_paramdesc(call, 'e');
104         rap_cli_push_paramdesc(call, 'h');
105         call->rcv_paramlen += 4; /* uint16_t entry count, uint16_t total */
106 }
107
108 static void rap_cli_expect_word(struct rap_call *call)
109 {
110         rap_cli_push_paramdesc(call, 'h');
111         call->rcv_paramlen += 2;
112 }
113
114 static void rap_cli_push_string(struct rap_call *call, const char *str)
115 {
116         if (str == NULL) {
117                 rap_cli_push_paramdesc(call, 'O');
118                 return;
119         }
120         rap_cli_push_paramdesc(call, 'z');
121         ndr_push_string(call->ndr_push_param, NDR_SCALARS, str);
122 }
123
124 static void rap_cli_expect_format(struct rap_call *call, const char *format)
125 {
126         call->datadesc = format;
127 }
128
129 static void rap_cli_expect_extra_format(struct rap_call *call, const char *format)
130 {
131         call->auxdatadesc = format;
132 }
133
134 static NTSTATUS rap_pull_string(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr,
135                                 uint16_t convert, const char **dest)
136 {
137         uint16_t string_offset;
138         uint16_t ignore;
139         const char *p;
140         size_t len;
141
142         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &string_offset));
143         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &ignore));
144
145         string_offset -= convert;
146
147         if (string_offset+1 > ndr->data_size)
148                 return NT_STATUS_INVALID_PARAMETER;
149
150         p = (const char *)(ndr->data + string_offset);
151         len = strnlen(p, ndr->data_size-string_offset);
152
153         if ( string_offset + len + 1 >  ndr->data_size )
154                 return NT_STATUS_INVALID_PARAMETER;
155
156         *dest = talloc_zero_array(mem_ctx, char, len+1);
157         pull_string(discard_const_p(char, *dest), p, len+1, len, STR_ASCII);
158
159         return NT_STATUS_OK;
160 }
161
162 NTSTATUS rap_cli_do_call(struct smbcli_tree *tree,
163                          struct rap_call *call)
164 {
165         NTSTATUS result;
166         DATA_BLOB param_blob;
167         DATA_BLOB data_blob;
168         struct ndr_push *params;
169         struct ndr_push *data;
170         struct smb_trans2 trans;
171
172         params = ndr_push_init_ctx(call);
173
174         if (params == NULL)
175                 return NT_STATUS_NO_MEMORY;
176
177         params->flags = RAPNDR_FLAGS;
178
179         data = ndr_push_init_ctx(call);
180
181         if (data == NULL)
182                 return NT_STATUS_NO_MEMORY;
183
184         data->flags = RAPNDR_FLAGS;
185
186         trans.in.max_param = call->rcv_paramlen;
187         trans.in.max_data = call->rcv_datalen;
188         trans.in.max_setup = 0;
189         trans.in.flags = 0;
190         trans.in.timeout = 0;
191         trans.in.setup_count = 0;
192         trans.in.setup = NULL;
193         trans.in.trans_name = "\\PIPE\\LANMAN";
194
195         NDR_RETURN(ndr_push_uint16(params, NDR_SCALARS, call->callno));
196         if (call->paramdesc)
197                 NDR_RETURN(ndr_push_string(params, NDR_SCALARS, call->paramdesc));
198         if (call->datadesc)
199                 NDR_RETURN(ndr_push_string(params, NDR_SCALARS, call->datadesc));
200
201         param_blob = ndr_push_blob(call->ndr_push_param);
202         NDR_RETURN(ndr_push_bytes(params, param_blob.data,
203                                  param_blob.length));
204
205         data_blob = ndr_push_blob(call->ndr_push_data);
206         NDR_RETURN(ndr_push_bytes(data, data_blob.data,
207                                  data_blob.length));
208
209         if (call->auxdatadesc)
210                 NDR_RETURN(ndr_push_string(params, NDR_SCALARS, call->auxdatadesc));
211
212         trans.in.params = ndr_push_blob(params);
213         trans.in.data = ndr_push_blob(data);
214
215         result = smb_raw_trans(tree, call, &trans);
216
217         if (!NT_STATUS_IS_OK(result))
218                 return result;
219
220         call->ndr_pull_param = ndr_pull_init_blob(&trans.out.params, call);
221         call->ndr_pull_param->flags = RAPNDR_FLAGS;
222         call->ndr_pull_param->current_mem_ctx = call->pull_mem_ctx;
223         call->ndr_pull_data = ndr_pull_init_blob(&trans.out.data, call);
224         call->ndr_pull_data->flags = RAPNDR_FLAGS;
225         call->ndr_pull_data->current_mem_ctx = call->pull_mem_ctx;
226
227         return result;
228 }
229
230
231 NTSTATUS smbcli_rap_netshareenum(struct smbcli_tree *tree,
232                                  TALLOC_CTX *mem_ctx,
233                                  struct rap_NetShareEnum *r)
234 {
235         struct rap_call *call;
236         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
237         int i;
238
239         call = new_rap_cli_call(tree, RAP_WshareEnum);
240
241         if (call == NULL)
242                 return NT_STATUS_NO_MEMORY;
243
244         rap_cli_push_word(call, r->in.level); /* Level */
245         rap_cli_push_rcvbuf(call, r->in.bufsize);
246         rap_cli_expect_multiple_entries(call);
247
248         switch(r->in.level) {
249         case 0:
250                 rap_cli_expect_format(call, "B13");
251                 break;
252         case 1:
253                 rap_cli_expect_format(call, "B13BWz");
254                 break;
255         }
256
257         if (DEBUGLEVEL >= 10) {
258                 NDR_PRINT_IN_DEBUG(rap_NetShareEnum, r);
259         }
260
261         result = rap_cli_do_call(tree, call);
262
263         if (!NT_STATUS_IS_OK(result))
264                 goto done;
265
266         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
267         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
268         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
269         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
270
271         r->out.info = talloc_array(mem_ctx, union rap_share_info, r->out.count);
272
273         if (r->out.info == NULL) {
274                 result = NT_STATUS_NO_MEMORY;
275                 goto done;
276         }
277
278         for (i=0; i<r->out.count; i++) {
279                 switch(r->in.level) {
280                 case 0:
281                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
282                                                 r->out.info[i].info0.share_name, 13));
283                         break;
284                 case 1:
285                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
286                                                 r->out.info[i].info1.share_name, 13));
287                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
288                                                 &r->out.info[i].info1.reserved1, 1));
289                         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_data,
290                                                NDR_SCALARS, &r->out.info[i].info1.share_type));
291                         RAP_GOTO(rap_pull_string(mem_ctx, call->ndr_pull_data,
292                                                r->out.convert,
293                                                &r->out.info[i].info1.comment));
294                         break;
295                 }
296         }
297
298         if (DEBUGLEVEL >= 10) {
299                 NDR_PRINT_OUT_DEBUG(rap_NetShareEnum, r);
300         }
301         result = NT_STATUS_OK;
302
303  done:
304         talloc_free(call);
305         return result;
306 }
307
308 NTSTATUS smbcli_rap_netserverenum2(struct smbcli_tree *tree,
309                                    TALLOC_CTX *mem_ctx,
310                                    struct rap_NetServerEnum2 *r)
311 {
312         struct rap_call *call;
313         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
314         int i;
315
316         call = new_rap_cli_call(mem_ctx, RAP_NetServerEnum2);
317
318         if (call == NULL)
319                 return NT_STATUS_NO_MEMORY;
320
321         rap_cli_push_word(call, r->in.level);
322         rap_cli_push_rcvbuf(call, r->in.bufsize);
323         rap_cli_expect_multiple_entries(call);
324         rap_cli_push_dword(call, r->in.servertype);
325         rap_cli_push_string(call, r->in.domain);
326
327         switch(r->in.level) {
328         case 0:
329                 rap_cli_expect_format(call, "B16");
330                 break;
331         case 1:
332                 rap_cli_expect_format(call, "B16BBDz");
333                 break;
334         }
335
336         if (DEBUGLEVEL >= 10) {
337                 NDR_PRINT_IN_DEBUG(rap_NetServerEnum2, r);
338         }
339
340         result = rap_cli_do_call(tree, call);
341
342         if (!NT_STATUS_IS_OK(result))
343                 goto done;
344
345         result = NT_STATUS_INVALID_PARAMETER;
346
347         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
348         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
349         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
350         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
351
352         r->out.info = talloc_array(mem_ctx, union rap_server_info, r->out.count);
353
354         if (r->out.info == NULL) {
355                 result = NT_STATUS_NO_MEMORY;
356                 goto done;
357         }
358
359         for (i=0; i<r->out.count; i++) {
360                 switch(r->in.level) {
361                 case 0:
362                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
363                                                 r->out.info[i].info0.name, 16));
364                         break;
365                 case 1:
366                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
367                                                 r->out.info[i].info1.name, 16));
368                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
369                                               &r->out.info[i].info1.version_major, 1));
370                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
371                                               &r->out.info[i].info1.version_minor, 1));
372                         NDR_GOTO(ndr_pull_uint32(call->ndr_pull_data,
373                                                NDR_SCALARS, &r->out.info[i].info1.servertype));
374                         RAP_GOTO(rap_pull_string(mem_ctx, call->ndr_pull_data,
375                                                r->out.convert,
376                                                &r->out.info[i].info1.comment));
377                 }
378         }
379
380         if (DEBUGLEVEL >= 10) {
381                 NDR_PRINT_OUT_DEBUG(rap_NetServerEnum2, r);
382         }
383
384         result = NT_STATUS_OK;
385
386  done:
387         talloc_free(call);
388         return result;
389 }
390
391 NTSTATUS smbcli_rap_netservergetinfo(struct smbcli_tree *tree,
392                                      TALLOC_CTX *mem_ctx,
393                                      struct rap_WserverGetInfo *r)
394 {
395         struct rap_call *call;
396         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
397
398         if (!(call = new_rap_cli_call(mem_ctx, RAP_WserverGetInfo))) {
399                 return NT_STATUS_NO_MEMORY;
400         }
401
402         rap_cli_push_word(call, r->in.level);
403         rap_cli_push_rcvbuf(call, r->in.bufsize);
404         rap_cli_expect_word(call);
405
406         switch(r->in.level) {
407         case 0:
408                 rap_cli_expect_format(call, "B16");
409                 break;
410         case 1:
411                 rap_cli_expect_format(call, "B16BBDz");
412                 break;
413         default:
414                 result = NT_STATUS_INVALID_PARAMETER;
415                 goto done;
416         }
417
418         if (DEBUGLEVEL >= 10) {
419                 NDR_PRINT_IN_DEBUG(rap_WserverGetInfo, r);
420         }
421
422         result = rap_cli_do_call(tree, call);
423
424         if (!NT_STATUS_IS_OK(result))
425                 goto done;
426
427         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
428         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
429         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
430
431         switch(r->in.level) {
432         case 0:
433                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
434                                         r->out.info.info0.name, 16));
435                 break;
436         case 1:
437                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
438                                         r->out.info.info1.name, 16));
439                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
440                                       &r->out.info.info1.version_major, 1));
441                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
442                                       &r->out.info.info1.version_minor, 1));
443                 NDR_GOTO(ndr_pull_uint32(call->ndr_pull_data,
444                                        NDR_SCALARS, &r->out.info.info1.servertype));
445                 RAP_GOTO(rap_pull_string(mem_ctx, call->ndr_pull_data,
446                                        r->out.convert,
447                                        &r->out.info.info1.comment));
448         }
449
450         if (DEBUGLEVEL >= 10) {
451                 NDR_PRINT_OUT_DEBUG(rap_WserverGetInfo, r);
452         }
453  done:
454         talloc_free(call);
455         return result;
456 }
457
458 static enum ndr_err_code ndr_pull_rap_NetPrintQEnum_data(struct ndr_pull *ndr, struct rap_NetPrintQEnum *r)
459 {
460         uint32_t cntr_info_0;
461         TALLOC_CTX *_mem_save_info_0;
462
463         NDR_PULL_ALLOC_N(ndr, r->out.info, r->out.count);
464         _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
465         NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0);
466         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
467                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->out.info[cntr_info_0], r->in.level));
468                 NDR_CHECK(ndr_pull_rap_printq_info(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
469         }
470         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
471                 NDR_CHECK(ndr_pull_rap_printq_info(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
472         }
473         NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
474
475         return NDR_ERR_SUCCESS;
476 }
477
478 NTSTATUS smbcli_rap_netprintqenum(struct smbcli_tree *tree,
479                                   TALLOC_CTX *mem_ctx,
480                                   struct rap_NetPrintQEnum *r)
481 {
482         struct rap_call *call;
483         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
484
485         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintQEnum))) {
486                 return NT_STATUS_NO_MEMORY;
487         }
488
489         rap_cli_push_word(call, r->in.level);
490         rap_cli_push_rcvbuf(call, r->in.bufsize);
491         rap_cli_expect_multiple_entries(call);
492
493         switch(r->in.level) {
494         case 0:
495                 rap_cli_expect_format(call, "B13");
496                 break;
497         case 1:
498                 rap_cli_expect_format(call, "B13BWWWzzzzzWW");
499                 break;
500         case 2:
501                 rap_cli_expect_format(call, "B13BWWWzzzzzWN");
502                 rap_cli_expect_extra_format(call, "WB21BB16B10zWWzDDz");
503                 break;
504         case 3:
505                 rap_cli_expect_format(call, "zWWWWzzzzWWzzl");
506                 break;
507         case 4:
508                 rap_cli_expect_format(call, "zWWWWzzzzWNzzl");
509                 rap_cli_expect_extra_format(call, "WWzWWDDzz");
510                 /* no mention of extra format in MS-RAP */
511                 break;
512         case 5:
513                 rap_cli_expect_format(call, "z");
514                 break;
515         default:
516                 result = NT_STATUS_INVALID_PARAMETER;
517                 goto done;
518         }
519
520         if (DEBUGLEVEL >= 10) {
521                 NDR_PRINT_IN_DEBUG(rap_NetPrintQEnum, r);
522         }
523
524         result = rap_cli_do_call(tree, call);
525
526         if (!NT_STATUS_IS_OK(result))
527                 goto done;
528
529         result = NT_STATUS_INVALID_PARAMETER;
530
531         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
532         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
533         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
534         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
535
536         call->ndr_pull_data->relative_rap_convert = r->out.convert;
537
538         NDR_GOTO(ndr_pull_rap_NetPrintQEnum_data(call->ndr_pull_data, r));
539
540         r->out.info = talloc_steal(mem_ctx, r->out.info);
541
542         if (DEBUGLEVEL >= 10) {
543                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQEnum, r);
544         }
545
546         result = NT_STATUS_OK;
547
548  done:
549         talloc_free(call);
550         return result;
551 }
552
553 NTSTATUS smbcli_rap_netprintqgetinfo(struct smbcli_tree *tree,
554                                      TALLOC_CTX *mem_ctx,
555                                      struct rap_NetPrintQGetInfo *r)
556 {
557         struct rap_call *call;
558         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
559
560         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintQGetInfo))) {
561                 return NT_STATUS_NO_MEMORY;
562         }
563
564         rap_cli_push_string(call, r->in.PrintQueueName);
565         rap_cli_push_word(call, r->in.level);
566         rap_cli_push_rcvbuf(call, r->in.bufsize);
567         rap_cli_expect_word(call);
568
569         switch(r->in.level) {
570         case 0:
571                 rap_cli_expect_format(call, "B13");
572                 break;
573         case 1:
574                 rap_cli_expect_format(call, "B13BWWWzzzzzWW");
575                 break;
576         case 2:
577                 rap_cli_expect_format(call, "B13BWWWzzzzzWN");
578                 rap_cli_expect_extra_format(call, "WB21BB16B10zWWzDDz");
579                 break;
580         case 3:
581                 rap_cli_expect_format(call, "zWWWWzzzzWWzzl");
582                 break;
583         case 4:
584                 rap_cli_expect_format(call, "zWWWWzzzzWNzzl");
585                 rap_cli_expect_extra_format(call, "WWzWWDDzz");
586                 /* no mention of extra format in MS-RAP */
587                 break;
588         case 5:
589                 rap_cli_expect_format(call, "z");
590                 break;
591         default:
592                 result = NT_STATUS_INVALID_PARAMETER;
593                 goto done;
594         }
595
596         if (DEBUGLEVEL >= 10) {
597                 NDR_PRINT_IN_DEBUG(rap_NetPrintQGetInfo, r);
598         }
599
600         result = rap_cli_do_call(tree, call);
601
602         if (!NT_STATUS_IS_OK(result))
603                 goto done;
604
605         result = NT_STATUS_INVALID_PARAMETER;
606
607         ZERO_STRUCT(r->out);
608
609         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
610         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
611         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
612
613         if (r->out.status == 0) {
614                 call->ndr_pull_data->relative_rap_convert = r->out.convert;
615
616                 NDR_GOTO(ndr_pull_set_switch_value(call->ndr_pull_data, &r->out.info, r->in.level));
617                 NDR_GOTO(ndr_pull_rap_printq_info(call->ndr_pull_data, NDR_SCALARS|NDR_BUFFERS, &r->out.info));
618         }
619
620         if (DEBUGLEVEL >= 10) {
621                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQGetInfo, r);
622         }
623
624         result = NT_STATUS_OK;
625  done:
626         talloc_free(call);
627         return result;
628 }
629
630 NTSTATUS smbcli_rap_netprintjobpause(struct smbcli_tree *tree,
631                                      TALLOC_CTX *mem_ctx,
632                                      struct rap_NetPrintJobPause *r)
633 {
634         struct rap_call *call;
635         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
636
637         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintJobPause))) {
638                 return NT_STATUS_NO_MEMORY;
639         }
640
641         rap_cli_push_word(call, r->in.JobID);
642
643         rap_cli_expect_format(call, "W");
644
645         if (DEBUGLEVEL >= 10) {
646                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobPause, r);
647         }
648
649         result = rap_cli_do_call(tree, call);
650
651         if (!NT_STATUS_IS_OK(result))
652                 goto done;
653
654         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
655         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
656
657         if (DEBUGLEVEL >= 10) {
658                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobPause, r);
659         }
660
661  done:
662         talloc_free(call);
663         return result;
664 }
665
666 NTSTATUS smbcli_rap_netprintjobcontinue(struct smbcli_tree *tree,
667                                         TALLOC_CTX *mem_ctx,
668                                         struct rap_NetPrintJobContinue *r)
669 {
670         struct rap_call *call;
671         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
672
673         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintJobContinue))) {
674                 return NT_STATUS_NO_MEMORY;
675         }
676
677         rap_cli_push_word(call, r->in.JobID);
678
679         rap_cli_expect_format(call, "W");
680
681         if (DEBUGLEVEL >= 10) {
682                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobContinue, r);
683         }
684
685         result = rap_cli_do_call(tree, call);
686
687         if (!NT_STATUS_IS_OK(result))
688                 goto done;
689
690         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
691         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
692
693         if (DEBUGLEVEL >= 10) {
694                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobContinue, r);
695         }
696
697  done:
698         talloc_free(call);
699         return result;
700 }
701
702 NTSTATUS smbcli_rap_netprintjobdelete(struct smbcli_tree *tree,
703                                       TALLOC_CTX *mem_ctx,
704                                       struct rap_NetPrintJobDelete *r)
705 {
706         struct rap_call *call;
707         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
708
709         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintJobDel))) {
710                 return NT_STATUS_NO_MEMORY;
711         }
712
713         rap_cli_push_word(call, r->in.JobID);
714
715         rap_cli_expect_format(call, "W");
716
717         if (DEBUGLEVEL >= 10) {
718                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobDelete, r);
719         }
720
721         result = rap_cli_do_call(tree, call);
722
723         if (!NT_STATUS_IS_OK(result))
724                 goto done;
725
726         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
727         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
728
729         if (DEBUGLEVEL >= 10) {
730                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobDelete, r);
731         }
732
733  done:
734         talloc_free(call);
735         return result;
736 }
737
738 NTSTATUS smbcli_rap_netprintqueuepause(struct smbcli_tree *tree,
739                                        TALLOC_CTX *mem_ctx,
740                                        struct rap_NetPrintQueuePause *r)
741 {
742         struct rap_call *call;
743         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
744
745         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintQPause))) {
746                 return NT_STATUS_NO_MEMORY;
747         }
748
749         rap_cli_push_string(call, r->in.PrintQueueName);
750
751         rap_cli_expect_format(call, "");
752
753         if (DEBUGLEVEL >= 10) {
754                 NDR_PRINT_IN_DEBUG(rap_NetPrintQueuePause, r);
755         }
756
757         result = rap_cli_do_call(tree, call);
758
759         if (!NT_STATUS_IS_OK(result))
760                 goto done;
761
762         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
763         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
764
765         if (DEBUGLEVEL >= 10) {
766                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQueuePause, r);
767         }
768
769  done:
770         talloc_free(call);
771         return result;
772 }
773
774 NTSTATUS smbcli_rap_netprintqueueresume(struct smbcli_tree *tree,
775                                         TALLOC_CTX *mem_ctx,
776                                         struct rap_NetPrintQueueResume *r)
777 {
778         struct rap_call *call;
779         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
780
781         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintQContinue))) {
782                 return NT_STATUS_NO_MEMORY;
783         }
784
785         rap_cli_push_string(call, r->in.PrintQueueName);
786
787         rap_cli_expect_format(call, "");
788
789         if (DEBUGLEVEL >= 10) {
790                 NDR_PRINT_IN_DEBUG(rap_NetPrintQueueResume, r);
791         }
792
793         result = rap_cli_do_call(tree, call);
794
795         if (!NT_STATUS_IS_OK(result))
796                 goto done;
797
798         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
799         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
800
801         if (DEBUGLEVEL >= 10) {
802                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQueueResume, r);
803         }
804
805  done:
806         talloc_free(call);
807         return result;
808 }
809
810 NTSTATUS smbcli_rap_netprintqueuepurge(struct smbcli_tree *tree,
811                                        TALLOC_CTX *mem_ctx,
812                                        struct rap_NetPrintQueuePurge *r)
813 {
814         struct rap_call *call;
815         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
816
817         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintQPurge))) {
818                 return NT_STATUS_NO_MEMORY;
819         }
820
821         rap_cli_push_string(call, r->in.PrintQueueName);
822
823         rap_cli_expect_format(call, "");
824
825         if (DEBUGLEVEL >= 10) {
826                 NDR_PRINT_IN_DEBUG(rap_NetPrintQueuePurge, r);
827         }
828
829         result = rap_cli_do_call(tree, call);
830
831         if (!NT_STATUS_IS_OK(result))
832                 goto done;
833
834         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
835         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
836
837         if (DEBUGLEVEL >= 10) {
838                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQueuePurge, r);
839         }
840
841  done:
842         talloc_free(call);
843         return result;
844 }
845
846 static enum ndr_err_code ndr_pull_rap_NetPrintJobEnum_data(struct ndr_pull *ndr, struct rap_NetPrintJobEnum *r)
847 {
848         uint32_t cntr_info_0;
849         TALLOC_CTX *_mem_save_info_0;
850
851         NDR_PULL_ALLOC_N(ndr, r->out.info, r->out.count);
852         _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
853         NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0);
854         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
855                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->out.info[cntr_info_0], r->in.level));
856                 NDR_CHECK(ndr_pull_rap_printj_info(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
857         }
858         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
859                 NDR_CHECK(ndr_pull_rap_printj_info(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
860         }
861         NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
862
863         return NDR_ERR_SUCCESS;
864 }
865
866 NTSTATUS smbcli_rap_netprintjobenum(struct smbcli_tree *tree,
867                                     TALLOC_CTX *mem_ctx,
868                                     struct rap_NetPrintJobEnum *r)
869 {
870         struct rap_call *call;
871         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
872
873         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintJobEnum))) {
874                 return NT_STATUS_NO_MEMORY;
875         }
876
877         rap_cli_push_string(call, r->in.PrintQueueName);
878         rap_cli_push_word(call, r->in.level);
879         rap_cli_push_rcvbuf(call, r->in.bufsize);
880         rap_cli_expect_multiple_entries(call);
881
882         switch(r->in.level) {
883         case 0:
884                 rap_cli_expect_format(call, "W");
885                 break;
886         case 1:
887                 rap_cli_expect_format(call, "WB21BB16B10zWWzDDz");
888                 break;
889         case 2:
890                 rap_cli_expect_format(call, "WWzWWDDzz");
891                 break;
892         case 3:
893                 rap_cli_expect_format(call, "WWzWWDDzzzzzzzzzzlz");
894                 break;
895         case 4:
896                 rap_cli_expect_format(call, "WWzWWDDzzzzzDDDDDDD");
897                 break;
898         default:
899                 result = NT_STATUS_INVALID_PARAMETER;
900                 goto done;
901         }
902
903         if (DEBUGLEVEL >= 10) {
904                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobEnum, r);
905         }
906
907         result = rap_cli_do_call(tree, call);
908
909         if (!NT_STATUS_IS_OK(result))
910                 goto done;
911
912         result = NT_STATUS_INVALID_PARAMETER;
913
914         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
915         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
916         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
917         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
918
919         call->ndr_pull_data->relative_rap_convert = r->out.convert;
920
921         NDR_GOTO(ndr_pull_rap_NetPrintJobEnum_data(call->ndr_pull_data, r));
922
923         if (DEBUGLEVEL >= 10) {
924                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobEnum, r);
925         }
926
927         r->out.info = talloc_steal(mem_ctx, r->out.info);
928
929         result = NT_STATUS_OK;
930
931  done:
932         talloc_free(call);
933         return result;
934 }
935
936 NTSTATUS smbcli_rap_netprintjobgetinfo(struct smbcli_tree *tree,
937                                        TALLOC_CTX *mem_ctx,
938                                        struct rap_NetPrintJobGetInfo *r)
939 {
940         struct rap_call *call;
941         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
942
943         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintJobGetInfo))) {
944                 return NT_STATUS_NO_MEMORY;
945         }
946
947         rap_cli_push_word(call, r->in.JobID);
948         rap_cli_push_word(call, r->in.level);
949         rap_cli_push_rcvbuf(call, r->in.bufsize);
950         rap_cli_expect_word(call);
951
952         switch(r->in.level) {
953         case 0:
954                 rap_cli_expect_format(call, "W");
955                 break;
956         case 1:
957                 rap_cli_expect_format(call, "WB21BB16B10zWWzDDz");
958                 break;
959         case 2:
960                 rap_cli_expect_format(call, "WWzWWDDzz");
961                 break;
962         case 3:
963                 rap_cli_expect_format(call, "WWzWWDDzzzzzzzzzzlz");
964                 break;
965         case 4:
966                 rap_cli_expect_format(call, "WWzWWDDzzzzzDDDDDDD");
967                 break;
968         default:
969                 result = NT_STATUS_INVALID_PARAMETER;
970                 goto done;
971         }
972
973         if (DEBUGLEVEL >= 10) {
974                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobGetInfo, r);
975         }
976
977         result = rap_cli_do_call(tree, call);
978
979         if (!NT_STATUS_IS_OK(result))
980                 goto done;
981
982         result = NT_STATUS_INVALID_PARAMETER;
983
984         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
985         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
986         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
987
988         call->ndr_pull_data->relative_rap_convert = r->out.convert;
989
990         NDR_GOTO(ndr_pull_set_switch_value(call->ndr_pull_data, &r->out.info, r->in.level));
991         NDR_GOTO(ndr_pull_rap_printj_info(call->ndr_pull_data, NDR_SCALARS|NDR_BUFFERS, &r->out.info));
992
993         if (DEBUGLEVEL >= 10) {
994                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobGetInfo, r);
995         }
996
997         result = NT_STATUS_OK;
998
999  done:
1000         talloc_free(call);
1001         return result;
1002 }
1003
1004 NTSTATUS smbcli_rap_netprintjobsetinfo(struct smbcli_tree *tree,
1005                                        TALLOC_CTX *mem_ctx,
1006                                        struct rap_NetPrintJobSetInfo *r)
1007 {
1008         struct rap_call *call;
1009         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1010
1011         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintJobSetInfo))) {
1012                 return NT_STATUS_NO_MEMORY;
1013         }
1014
1015         rap_cli_push_word(call, r->in.JobID);
1016         rap_cli_push_word(call, r->in.level);
1017         rap_cli_push_sendbuf(call, r->in.bufsize);
1018         rap_cli_push_param(call, r->in.ParamNum);
1019
1020         switch (r->in.ParamNum) {
1021         case RAP_PARAM_JOBNUM:
1022         case RAP_PARAM_JOBPOSITION:
1023         case RAP_PARAM_JOBSTATUS:
1024                 NDR_GOTO(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r->in.Param.value));
1025                 break;
1026         case RAP_PARAM_USERNAME:
1027         case RAP_PARAM_NOTIFYNAME:
1028         case RAP_PARAM_DATATYPE:
1029         case RAP_PARAM_PARAMETERS_STRING:
1030         case RAP_PARAM_JOBSTATUSSTR:
1031         case RAP_PARAM_JOBCOMMENT:
1032                 NDR_GOTO(ndr_push_string(call->ndr_push_param, NDR_SCALARS, r->in.Param.string));
1033                 break;
1034         case RAP_PARAM_TIMESUBMITTED:
1035         case RAP_PARAM_JOBSIZE:
1036                 NDR_GOTO(ndr_push_uint32(call->ndr_push_param, NDR_SCALARS, r->in.Param.value4));
1037                 break;
1038         default:
1039                 result = NT_STATUS_INVALID_PARAMETER;
1040                 break;
1041         }
1042
1043         /* not really sure if this is correct */
1044         rap_cli_expect_format(call, "WB21BB16B10zWWzDDz");
1045
1046         if (DEBUGLEVEL >= 10) {
1047                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobSetInfo, r);
1048         }
1049
1050         result = rap_cli_do_call(tree, call);
1051
1052         if (!NT_STATUS_IS_OK(result))
1053                 goto done;
1054
1055         result = NT_STATUS_INVALID_PARAMETER;
1056
1057         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1058         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1059
1060         result = NT_STATUS_OK;
1061
1062         if (!NT_STATUS_IS_OK(result)) {
1063                 goto done;
1064         }
1065
1066         if (DEBUGLEVEL >= 10) {
1067                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobSetInfo, r);
1068         }
1069
1070  done:
1071         talloc_free(call);
1072         return result;
1073 }
1074
1075 static enum ndr_err_code ndr_pull_rap_NetPrintDestEnum_data(struct ndr_pull *ndr, struct rap_NetPrintDestEnum *r)
1076 {
1077         uint32_t cntr_info_0;
1078         TALLOC_CTX *_mem_save_info_0;
1079
1080         NDR_PULL_ALLOC_N(ndr, r->out.info, r->out.count);
1081         _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
1082         NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0);
1083         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
1084                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->out.info[cntr_info_0], r->in.level));
1085                 NDR_CHECK(ndr_pull_rap_printdest_info(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
1086         }
1087         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
1088                 NDR_CHECK(ndr_pull_rap_printdest_info(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
1089         }
1090         NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
1091
1092         return NDR_ERR_SUCCESS;
1093 }
1094
1095
1096 NTSTATUS smbcli_rap_netprintdestenum(struct smbcli_tree *tree,
1097                                      TALLOC_CTX *mem_ctx,
1098                                      struct rap_NetPrintDestEnum *r)
1099 {
1100         struct rap_call *call;
1101         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1102
1103         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintDestEnum))) {
1104                 return NT_STATUS_NO_MEMORY;
1105         }
1106
1107         rap_cli_push_word(call, r->in.level);
1108         rap_cli_push_rcvbuf(call, r->in.bufsize);
1109         rap_cli_expect_multiple_entries(call);
1110
1111         switch(r->in.level) {
1112         case 0:
1113                 rap_cli_expect_format(call, "B9");
1114                 break;
1115         case 1:
1116                 rap_cli_expect_format(call, "B9B21WWzW");
1117                 break;
1118         case 2:
1119                 rap_cli_expect_format(call, "z");
1120                 break;
1121         case 3:
1122                 rap_cli_expect_format(call, "zzzWWzzzWW");
1123                 break;
1124         default:
1125                 result = NT_STATUS_INVALID_PARAMETER;
1126                 goto done;
1127         }
1128
1129         if (DEBUGLEVEL >= 10) {
1130                 NDR_PRINT_IN_DEBUG(rap_NetPrintDestEnum, r);
1131         }
1132
1133         result = rap_cli_do_call(tree, call);
1134
1135         if (!NT_STATUS_IS_OK(result))
1136                 goto done;
1137
1138         result = NT_STATUS_INVALID_PARAMETER;
1139
1140         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1141         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1142         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
1143         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1144
1145         call->ndr_pull_data->relative_rap_convert = r->out.convert;
1146
1147         NDR_GOTO(ndr_pull_rap_NetPrintDestEnum_data(call->ndr_pull_data, r));
1148
1149         r->out.info = talloc_steal(mem_ctx, r->out.info);
1150
1151         if (DEBUGLEVEL >= 10) {
1152                 NDR_PRINT_OUT_DEBUG(rap_NetPrintDestEnum, r);
1153         }
1154
1155         result = NT_STATUS_OK;
1156
1157  done:
1158         talloc_free(call);
1159         return result;
1160 }
1161
1162 NTSTATUS smbcli_rap_netprintdestgetinfo(struct smbcli_tree *tree,
1163                                         TALLOC_CTX *mem_ctx,
1164                                         struct rap_NetPrintDestGetInfo *r)
1165 {
1166         struct rap_call *call;
1167         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1168
1169         if (!(call = new_rap_cli_call(mem_ctx, RAP_WPrintDestGetInfo))) {
1170                 return NT_STATUS_NO_MEMORY;
1171         }
1172
1173         rap_cli_push_string(call, r->in.PrintDestName);
1174         rap_cli_push_word(call, r->in.level);
1175         rap_cli_push_rcvbuf(call, r->in.bufsize);
1176         rap_cli_expect_word(call);
1177
1178         switch(r->in.level) {
1179         case 0:
1180                 rap_cli_expect_format(call, "B9");
1181                 break;
1182         case 1:
1183                 rap_cli_expect_format(call, "B9B21WWzW");
1184                 break;
1185         case 2:
1186                 rap_cli_expect_format(call, "z");
1187                 break;
1188         case 3:
1189                 rap_cli_expect_format(call, "zzzWWzzzWW");
1190                 break;
1191         default:
1192                 result = NT_STATUS_INVALID_PARAMETER;
1193                 goto done;
1194         }
1195
1196         if (DEBUGLEVEL >= 10) {
1197                 NDR_PRINT_IN_DEBUG(rap_NetPrintDestGetInfo, r);
1198         }
1199
1200         result = rap_cli_do_call(tree, call);
1201
1202         if (!NT_STATUS_IS_OK(result))
1203                 goto done;
1204
1205         result = NT_STATUS_INVALID_PARAMETER;
1206
1207         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1208         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1209         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1210
1211         call->ndr_pull_data->relative_rap_convert = r->out.convert;
1212
1213         NDR_GOTO(ndr_pull_set_switch_value(call->ndr_pull_data, &r->out.info, r->in.level));
1214         NDR_GOTO(ndr_pull_rap_printdest_info(call->ndr_pull_data, NDR_SCALARS|NDR_BUFFERS, &r->out.info));
1215
1216         if (DEBUGLEVEL >= 10) {
1217                 NDR_PRINT_OUT_DEBUG(rap_NetPrintDestGetInfo, r);
1218         }
1219
1220         result = NT_STATUS_OK;
1221
1222  done:
1223         talloc_free(call);
1224         return result;
1225 }
1226
1227 NTSTATUS smbcli_rap_netuserpasswordset2(struct smbcli_tree *tree,
1228                                         TALLOC_CTX *mem_ctx,
1229                                         struct rap_NetUserPasswordSet2 *r)
1230 {
1231         struct rap_call *call;
1232         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1233
1234         if (!(call = new_rap_cli_call(mem_ctx, RAP_WUserPasswordSet2))) {
1235                 return NT_STATUS_NO_MEMORY;
1236         }
1237
1238         rap_cli_push_string(call, r->in.UserName);
1239         rap_cli_push_paramdesc(call, 'b');
1240         rap_cli_push_paramdesc(call, '1');
1241         rap_cli_push_paramdesc(call, '6');
1242         ndr_push_array_uint8(call->ndr_push_param, NDR_SCALARS, r->in.OldPassword, 16);
1243         rap_cli_push_paramdesc(call, 'b');
1244         rap_cli_push_paramdesc(call, '1');
1245         rap_cli_push_paramdesc(call, '6');
1246         ndr_push_array_uint8(call->ndr_push_param, NDR_SCALARS, r->in.NewPassword, 16);
1247         rap_cli_push_word(call, r->in.EncryptedPassword);
1248         rap_cli_push_word(call, r->in.RealPasswordLength);
1249
1250         rap_cli_expect_format(call, "");
1251
1252         if (DEBUGLEVEL >= 10) {
1253                 NDR_PRINT_IN_DEBUG(rap_NetUserPasswordSet2, r);
1254         }
1255
1256         result = rap_cli_do_call(tree, call);
1257
1258         if (!NT_STATUS_IS_OK(result))
1259                 goto done;
1260
1261         result = NT_STATUS_INVALID_PARAMETER;
1262
1263         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1264         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1265
1266         result = NT_STATUS_OK;
1267
1268         if (!NT_STATUS_IS_OK(result)) {
1269                 goto done;
1270         }
1271
1272         if (DEBUGLEVEL >= 10) {
1273                 NDR_PRINT_OUT_DEBUG(rap_NetUserPasswordSet2, r);
1274         }
1275
1276  done:
1277         talloc_free(call);
1278         return result;
1279 }
1280
1281 NTSTATUS smbcli_rap_netoemchangepassword(struct smbcli_tree *tree,
1282                                          TALLOC_CTX *mem_ctx,
1283                                          struct rap_NetOEMChangePassword *r)
1284 {
1285         struct rap_call *call;
1286         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1287
1288         if (!(call = new_rap_cli_call(mem_ctx, RAP_SamOEMChgPasswordUser2_P))) {
1289                 return NT_STATUS_NO_MEMORY;
1290         }
1291
1292         rap_cli_push_string(call, r->in.UserName);
1293         rap_cli_push_sendbuf(call, 532);
1294         ndr_push_array_uint8(call->ndr_push_data, NDR_SCALARS, r->in.crypt_password, 516);
1295         ndr_push_array_uint8(call->ndr_push_data, NDR_SCALARS, r->in.password_hash, 16);
1296
1297         rap_cli_expect_format(call, "B516B16");
1298
1299         if (DEBUGLEVEL >= 10) {
1300                 NDR_PRINT_IN_DEBUG(rap_NetOEMChangePassword, r);
1301         }
1302
1303         result = rap_cli_do_call(tree, call);
1304
1305         if (!NT_STATUS_IS_OK(result))
1306                 goto done;
1307
1308         result = NT_STATUS_INVALID_PARAMETER;
1309
1310         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1311         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1312
1313         result = NT_STATUS_OK;
1314
1315         if (!NT_STATUS_IS_OK(result)) {
1316                 goto done;
1317         }
1318
1319         if (DEBUGLEVEL >= 10) {
1320                 NDR_PRINT_OUT_DEBUG(rap_NetOEMChangePassword, r);
1321         }
1322
1323  done:
1324         talloc_free(call);
1325         return result;
1326 }
1327
1328 NTSTATUS smbcli_rap_netusergetinfo(struct smbcli_tree *tree,
1329                                    TALLOC_CTX *mem_ctx,
1330                                    struct rap_NetUserGetInfo *r)
1331 {
1332         struct rap_call *call;
1333         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1334
1335         if (!(call = new_rap_cli_call(mem_ctx, RAP_WUserGetInfo))) {
1336                 return NT_STATUS_NO_MEMORY;
1337         }
1338
1339         rap_cli_push_string(call, r->in.UserName);
1340         rap_cli_push_word(call, r->in.level);
1341         rap_cli_push_rcvbuf(call, r->in.bufsize);
1342         rap_cli_expect_word(call);
1343
1344         switch(r->in.level) {
1345         case 0:
1346                 rap_cli_expect_format(call, "B21");
1347                 break;
1348         case 1:
1349                 rap_cli_expect_format(call, "B21BB16DWzzWz");
1350                 break;
1351         case 2:
1352                 rap_cli_expect_format(call, "B21BB16DWzzWzDzzzzDDDDWb21WWzWW");
1353                 break;
1354         case 10:
1355                 rap_cli_expect_format(call, "B21Bzzz");
1356                 break;
1357         case 11:
1358                 rap_cli_expect_format(call, "B21BzzzWDDzzDDWWzWzDWb21W");
1359                 break;
1360         default:
1361                 result = NT_STATUS_INVALID_PARAMETER;
1362                 goto done;
1363         }
1364
1365         if (DEBUGLEVEL >= 10) {
1366                 NDR_PRINT_IN_DEBUG(rap_NetUserGetInfo, r);
1367         }
1368
1369         result = rap_cli_do_call(tree, call);
1370
1371         if (!NT_STATUS_IS_OK(result))
1372                 goto done;
1373
1374         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1375         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1376         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1377
1378         call->ndr_pull_data->relative_rap_convert = r->out.convert;
1379
1380         NDR_GOTO(ndr_pull_set_switch_value(call->ndr_pull_data, &r->out.info, r->in.level));
1381         NDR_GOTO(ndr_pull_rap_netuser_info(call->ndr_pull_data, NDR_SCALARS|NDR_BUFFERS, &r->out.info));
1382
1383         if (DEBUGLEVEL >= 10) {
1384                 NDR_PRINT_OUT_DEBUG(rap_NetUserGetInfo, r);
1385         }
1386
1387         result = NT_STATUS_OK;
1388
1389  done:
1390         talloc_free(call);
1391         return result;
1392 }
1393
1394
1395 static enum ndr_err_code ndr_pull_rap_NetSessionEnum_data(struct ndr_pull *ndr, struct rap_NetSessionEnum *r)
1396 {
1397         uint32_t cntr_info_0;
1398         TALLOC_CTX *_mem_save_info_0;
1399
1400         NDR_PULL_ALLOC_N(ndr, r->out.info, r->out.count);
1401         _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
1402         NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0);
1403         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
1404                 NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->out.info[cntr_info_0], r->in.level));
1405                 NDR_CHECK(ndr_pull_rap_session_info(ndr, NDR_SCALARS, &r->out.info[cntr_info_0]));
1406         }
1407         for (cntr_info_0 = 0; cntr_info_0 < r->out.count; cntr_info_0++) {
1408                 NDR_CHECK(ndr_pull_rap_session_info(ndr, NDR_BUFFERS, &r->out.info[cntr_info_0]));
1409         }
1410         NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
1411
1412         return NDR_ERR_SUCCESS;
1413 }
1414
1415
1416 NTSTATUS smbcli_rap_netsessionenum(struct smbcli_tree *tree,
1417                                    TALLOC_CTX *mem_ctx,
1418                                    struct rap_NetSessionEnum *r)
1419 {
1420         struct rap_call *call;
1421         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1422
1423         call = new_rap_cli_call(tree, RAP_WsessionEnum);
1424
1425         if (call == NULL)
1426                 return NT_STATUS_NO_MEMORY;
1427
1428         rap_cli_push_word(call, r->in.level);
1429         rap_cli_push_rcvbuf(call, r->in.bufsize);
1430         rap_cli_expect_multiple_entries(call);
1431
1432         switch(r->in.level) {
1433         case 2:
1434                 rap_cli_expect_format(call, "zzWWWDDDz");
1435                 break;
1436         default:
1437                 result = NT_STATUS_INVALID_PARAMETER;
1438                 goto done;
1439         }
1440
1441         if (DEBUGLEVEL >= 10) {
1442                 NDR_PRINT_IN_DEBUG(rap_NetSessionEnum, r);
1443         }
1444
1445         result = rap_cli_do_call(tree, call);
1446
1447         if (!NT_STATUS_IS_OK(result))
1448                 goto done;
1449
1450         result = NT_STATUS_INVALID_PARAMETER;
1451
1452         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1453         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1454         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
1455         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1456
1457         call->ndr_pull_data->relative_rap_convert = r->out.convert;
1458
1459         NDR_GOTO(ndr_pull_rap_NetSessionEnum_data(call->ndr_pull_data, r));
1460
1461         r->out.info = talloc_steal(mem_ctx, r->out.info);
1462
1463         if (DEBUGLEVEL >= 10) {
1464                 NDR_PRINT_OUT_DEBUG(rap_NetSessionEnum, r);
1465         }
1466
1467         result = NT_STATUS_OK;
1468
1469  done:
1470         talloc_free(call);
1471         return result;
1472 }
1473
1474 NTSTATUS smbcli_rap_netsessiongetinfo(struct smbcli_tree *tree,
1475                                       TALLOC_CTX *mem_ctx,
1476                                       struct rap_NetSessionGetInfo *r)
1477 {
1478         struct rap_call *call;
1479         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1480
1481         if (!(call = new_rap_cli_call(mem_ctx, RAP_WsessionGetInfo))) {
1482                 return NT_STATUS_NO_MEMORY;
1483         }
1484
1485         rap_cli_push_string(call, r->in.SessionName);
1486         rap_cli_push_word(call, r->in.level);
1487         rap_cli_push_rcvbuf(call, r->in.bufsize);
1488         rap_cli_expect_word(call);
1489
1490         switch(r->in.level) {
1491         case 2:
1492                 rap_cli_expect_format(call, "zzWWWDDDz");
1493                 break;
1494         default:
1495                 result = NT_STATUS_INVALID_PARAMETER;
1496                 break;
1497         }
1498
1499         if (DEBUGLEVEL >= 10) {
1500                 NDR_PRINT_IN_DEBUG(rap_NetSessionGetInfo, r);
1501         }
1502
1503         result = rap_cli_do_call(tree, call);
1504
1505         if (!NT_STATUS_IS_OK(result))
1506                 goto done;
1507
1508         result = NT_STATUS_INVALID_PARAMETER;
1509
1510         ZERO_STRUCT(r->out);
1511
1512         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1513         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1514         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1515
1516         if (r->out.status == 0 && r->out.available) {
1517                 call->ndr_pull_data->relative_rap_convert = r->out.convert;
1518
1519                 NDR_GOTO(ndr_pull_set_switch_value(call->ndr_pull_data, &r->out.info, r->in.level));
1520                 NDR_GOTO(ndr_pull_rap_session_info(call->ndr_pull_data, NDR_SCALARS|NDR_BUFFERS, &r->out.info));
1521         }
1522
1523         if (DEBUGLEVEL >= 10) {
1524                 NDR_PRINT_OUT_DEBUG(rap_NetSessionGetInfo, r);
1525         }
1526
1527         result = NT_STATUS_OK;
1528  done:
1529         talloc_free(call);
1530         return result;
1531 }
1532
1533
1534 NTSTATUS smbcli_rap_netuseradd(struct smbcli_tree *tree,
1535                                TALLOC_CTX *mem_ctx,
1536                                struct rap_NetUserAdd *r)
1537 {
1538         struct rap_call *call;
1539         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1540
1541         if (!(call = new_rap_cli_call(mem_ctx, RAP_WUserAdd2))) {
1542                 return NT_STATUS_NO_MEMORY;
1543         }
1544
1545         rap_cli_push_word(call, r->in.level);
1546         rap_cli_push_sendbuf(call, r->in.bufsize);
1547         rap_cli_push_word(call, r->in.pwdlength);
1548         rap_cli_push_word(call, r->in.unknown);
1549
1550         switch (r->in.level) {
1551         case 1:
1552                 rap_cli_expect_format(call, "B21BB16DWzzWz");
1553                 break;
1554         default:
1555                 result = NT_STATUS_INVALID_PARAMETER;
1556                 break;
1557         }
1558
1559         if (DEBUGLEVEL >= 10) {
1560                 NDR_PRINT_IN_DEBUG(rap_NetUserAdd, r);
1561         }
1562
1563         NDR_GOTO(ndr_push_set_switch_value(call->ndr_push_data, &r->in.info, r->in.level));
1564         NDR_GOTO(ndr_push_rap_netuser_info(call->ndr_push_data, NDR_SCALARS|NDR_BUFFERS, &r->in.info));
1565
1566         result = rap_cli_do_call(tree, call);
1567
1568         if (!NT_STATUS_IS_OK(result))
1569                 goto done;
1570
1571         result = NT_STATUS_INVALID_PARAMETER;
1572
1573         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1574         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1575
1576         result = NT_STATUS_OK;
1577
1578         if (!NT_STATUS_IS_OK(result)) {
1579                 goto done;
1580         }
1581
1582         if (DEBUGLEVEL >= 10) {
1583                 NDR_PRINT_OUT_DEBUG(rap_NetUserAdd, r);
1584         }
1585
1586  done:
1587         talloc_free(call);
1588         return result;
1589 }
1590
1591 NTSTATUS smbcli_rap_netuserdelete(struct smbcli_tree *tree,
1592                                   TALLOC_CTX *mem_ctx,
1593                                   struct rap_NetUserDelete *r)
1594 {
1595         struct rap_call *call;
1596         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1597
1598         if (!(call = new_rap_cli_call(mem_ctx, RAP_WUserDel))) {
1599                 return NT_STATUS_NO_MEMORY;
1600         }
1601
1602         rap_cli_push_string(call, r->in.UserName);
1603
1604         rap_cli_expect_format(call, "");
1605         rap_cli_expect_extra_format(call, "");
1606
1607         if (DEBUGLEVEL >= 10) {
1608                 NDR_PRINT_IN_DEBUG(rap_NetUserDelete, r);
1609         }
1610
1611         result = rap_cli_do_call(tree, call);
1612
1613         if (!NT_STATUS_IS_OK(result))
1614                 goto done;
1615
1616         result = NT_STATUS_INVALID_PARAMETER;
1617
1618         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1619         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1620
1621         result = NT_STATUS_OK;
1622
1623         if (!NT_STATUS_IS_OK(result)) {
1624                 goto done;
1625         }
1626
1627         if (DEBUGLEVEL >= 10) {
1628                 NDR_PRINT_OUT_DEBUG(rap_NetUserDelete, r);
1629         }
1630
1631  done:
1632         talloc_free(call);
1633         return result;
1634 }
1635
1636 NTSTATUS smbcli_rap_netremotetod(struct smbcli_tree *tree,
1637                                   TALLOC_CTX *mem_ctx,
1638                                   struct rap_NetRemoteTOD *r)
1639 {
1640         struct rap_call *call;
1641         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1642
1643         if (!(call = new_rap_cli_call(mem_ctx, RAP_NetRemoteTOD))) {
1644                 return NT_STATUS_NO_MEMORY;
1645         }
1646
1647         rap_cli_push_rcvbuf(call, r->in.bufsize);
1648
1649         rap_cli_expect_format(call, "DDBBBBWWBBWB");
1650         rap_cli_expect_extra_format(call, "");
1651
1652         if (DEBUGLEVEL >= 10) {
1653                 NDR_PRINT_IN_DEBUG(rap_NetRemoteTOD, r);
1654         }
1655
1656         result = rap_cli_do_call(tree, call);
1657
1658         if (!NT_STATUS_IS_OK(result))
1659                 goto done;
1660
1661         result = NT_STATUS_INVALID_PARAMETER;
1662
1663         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1664         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1665
1666         NDR_GOTO(ndr_pull_rap_TimeOfDayInfo(call->ndr_pull_data, NDR_SCALARS|NDR_BUFFERS, &r->out.tod));
1667
1668         result = NT_STATUS_OK;
1669
1670         if (!NT_STATUS_IS_OK(result)) {
1671                 goto done;
1672         }
1673
1674         if (DEBUGLEVEL >= 10) {
1675                 NDR_PRINT_OUT_DEBUG(rap_NetRemoteTOD, r);
1676         }
1677
1678  done:
1679         talloc_free(call);
1680         return result;
1681 }