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