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