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