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