s4-smbtorture: test netservergetinfo level 1 also against s3.
[metze/samba/wip.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, struct smb_iconv_convenience *iconv_convenience, 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, iconv_convenience);
102         call->ndr_push_param->flags = RAPNDR_FLAGS;
103
104         call->ndr_push_data = ndr_push_init_ctx(mem_ctx, iconv_convenience);
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((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 smb_iconv_convenience *iconv_convenience,
222                                 struct rap_call *call)
223 {
224         NTSTATUS result;
225         DATA_BLOB param_blob;
226         DATA_BLOB data_blob;
227         struct ndr_push *params;
228         struct ndr_push *data;
229         struct smb_trans2 trans;
230
231         params = ndr_push_init_ctx(call, iconv_convenience);
232
233         if (params == NULL)
234                 return NT_STATUS_NO_MEMORY;
235
236         params->flags = RAPNDR_FLAGS;
237
238         data = ndr_push_init_ctx(call, iconv_convenience);
239
240         if (data == NULL)
241                 return NT_STATUS_NO_MEMORY;
242
243         data->flags = RAPNDR_FLAGS;
244
245         trans.in.max_param = call->rcv_paramlen;
246         trans.in.max_data = call->rcv_datalen;
247         trans.in.max_setup = 0;
248         trans.in.flags = 0;
249         trans.in.timeout = 0;
250         trans.in.setup_count = 0;
251         trans.in.setup = NULL;
252         trans.in.trans_name = "\\PIPE\\LANMAN";
253
254         NDR_RETURN(ndr_push_uint16(params, NDR_SCALARS, call->callno));
255         if (call->paramdesc)
256                 NDR_RETURN(ndr_push_string(params, NDR_SCALARS, call->paramdesc));
257         if (call->datadesc)
258                 NDR_RETURN(ndr_push_string(params, NDR_SCALARS, call->datadesc));
259
260         param_blob = ndr_push_blob(call->ndr_push_param);
261         NDR_RETURN(ndr_push_bytes(params, param_blob.data,
262                                  param_blob.length));
263
264         data_blob = ndr_push_blob(call->ndr_push_data);
265         NDR_RETURN(ndr_push_bytes(data, data_blob.data,
266                                  data_blob.length));
267
268         if (call->auxdatadesc)
269                 NDR_RETURN(ndr_push_string(params, NDR_SCALARS, call->auxdatadesc));
270
271         trans.in.params = ndr_push_blob(params);
272         trans.in.data = ndr_push_blob(data);
273
274         result = smb_raw_trans(tree, call, &trans);
275
276         if (!NT_STATUS_IS_OK(result))
277                 return result;
278
279         call->ndr_pull_param = ndr_pull_init_blob(&trans.out.params, call,
280                                                   iconv_convenience);
281         call->ndr_pull_param->flags = RAPNDR_FLAGS;
282
283         call->ndr_pull_data = ndr_pull_init_blob(&trans.out.data, call,
284                                                  iconv_convenience);
285         call->ndr_pull_data->flags = RAPNDR_FLAGS;
286
287         return result;
288 }
289
290
291 static NTSTATUS smbcli_rap_netshareenum(struct smbcli_tree *tree,
292                                         struct smb_iconv_convenience *iconv_convenience,
293                                         TALLOC_CTX *mem_ctx,
294                                         struct rap_NetShareEnum *r)
295 {
296         struct rap_call *call;
297         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
298         int i;
299
300         call = new_rap_cli_call(tree, iconv_convenience, RAP_WshareEnum);
301
302         if (call == NULL)
303                 return NT_STATUS_NO_MEMORY;
304
305         rap_cli_push_word(call, r->in.level); /* Level */
306         rap_cli_push_rcvbuf(call, r->in.bufsize);
307         rap_cli_expect_multiple_entries(call);
308
309         switch(r->in.level) {
310         case 0:
311                 rap_cli_expect_format(call, "B13");
312                 break;
313         case 1:
314                 rap_cli_expect_format(call, "B13BWz");
315                 break;
316         }
317
318         if (DEBUGLEVEL >= 10) {
319                 NDR_PRINT_IN_DEBUG(rap_NetShareEnum, r);
320         }
321
322         result = rap_cli_do_call(tree, iconv_convenience, call);
323
324         if (!NT_STATUS_IS_OK(result))
325                 goto done;
326
327         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
328         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
329         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
330         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
331
332         r->out.info = talloc_array(mem_ctx, union rap_share_info, r->out.count);
333
334         if (r->out.info == NULL) {
335                 result = NT_STATUS_NO_MEMORY;
336                 goto done;
337         }
338
339         for (i=0; i<r->out.count; i++) {
340                 switch(r->in.level) {
341                 case 0:
342                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
343                                                 r->out.info[i].info0.share_name, 13));
344                         break;
345                 case 1:
346                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
347                                                 r->out.info[i].info1.share_name, 13));
348                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
349                                                 &r->out.info[i].info1.reserved1, 1));
350                         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_data,
351                                                NDR_SCALARS, &r->out.info[i].info1.share_type));
352                         RAP_GOTO(rap_pull_string(mem_ctx, call->ndr_pull_data,
353                                                r->out.convert,
354                                                &r->out.info[i].info1.comment));
355                         break;
356                 }
357         }
358
359         if (DEBUGLEVEL >= 10) {
360                 NDR_PRINT_OUT_DEBUG(rap_NetShareEnum, r);
361         }
362         result = NT_STATUS_OK;
363
364  done:
365         talloc_free(call);
366         return result;
367 }
368
369 static bool test_netshareenum(struct torture_context *tctx, 
370                               struct smbcli_state *cli)
371 {
372         struct rap_NetShareEnum r;
373         int i;
374
375         r.in.level = 1;
376         r.in.bufsize = 8192;
377
378         torture_assert_ntstatus_ok(tctx, 
379                 smbcli_rap_netshareenum(cli->tree, lp_iconv_convenience(tctx->lp_ctx), tctx, &r), "");
380
381         for (i=0; i<r.out.count; i++) {
382                 printf("%s %d %s\n", r.out.info[i].info1.share_name,
383                        r.out.info[i].info1.share_type,
384                        r.out.info[i].info1.comment);
385         }
386
387         return true;
388 }
389
390 static NTSTATUS smbcli_rap_netserverenum2(struct smbcli_tree *tree,
391                                           struct smb_iconv_convenience *iconv_convenience, 
392                                           TALLOC_CTX *mem_ctx,
393                                           struct rap_NetServerEnum2 *r)
394 {
395         struct rap_call *call;
396         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
397         int i;
398
399         call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_NetServerEnum2);
400
401         if (call == NULL)
402                 return NT_STATUS_NO_MEMORY;
403
404         rap_cli_push_word(call, r->in.level);
405         rap_cli_push_rcvbuf(call, r->in.bufsize);
406         rap_cli_expect_multiple_entries(call);
407         rap_cli_push_dword(call, r->in.servertype);
408         rap_cli_push_string(call, r->in.domain);
409
410         switch(r->in.level) {
411         case 0:
412                 rap_cli_expect_format(call, "B16");
413                 break;
414         case 1:
415                 rap_cli_expect_format(call, "B16BBDz");
416                 break;
417         }
418
419         if (DEBUGLEVEL >= 10) {
420                 NDR_PRINT_IN_DEBUG(rap_NetServerEnum2, r);
421         }
422
423         result = rap_cli_do_call(tree, iconv_convenience, call);
424
425         if (!NT_STATUS_IS_OK(result))
426                 goto done;
427
428         result = NT_STATUS_INVALID_PARAMETER;
429
430         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
431         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
432         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
433         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
434
435         r->out.info = talloc_array(mem_ctx, union rap_server_info, r->out.count);
436
437         if (r->out.info == NULL) {
438                 result = NT_STATUS_NO_MEMORY;
439                 goto done;
440         }
441
442         for (i=0; i<r->out.count; i++) {
443                 switch(r->in.level) {
444                 case 0:
445                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
446                                                 r->out.info[i].info0.name, 16));
447                         break;
448                 case 1:
449                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
450                                                 r->out.info[i].info1.name, 16));
451                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
452                                               &r->out.info[i].info1.version_major, 1));
453                         NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
454                                               &r->out.info[i].info1.version_minor, 1));
455                         NDR_GOTO(ndr_pull_uint32(call->ndr_pull_data,
456                                                NDR_SCALARS, &r->out.info[i].info1.servertype));
457                         RAP_GOTO(rap_pull_string(mem_ctx, call->ndr_pull_data,
458                                                r->out.convert,
459                                                &r->out.info[i].info1.comment));
460                 }
461         }
462
463         if (DEBUGLEVEL >= 10) {
464                 NDR_PRINT_OUT_DEBUG(rap_NetServerEnum2, r);
465         }
466
467         result = NT_STATUS_OK;
468
469  done:
470         talloc_free(call);
471         return result;
472 }
473
474 static bool test_netserverenum(struct torture_context *tctx, 
475                                struct smbcli_state *cli)
476 {
477         struct rap_NetServerEnum2 r;
478         int i;
479
480         r.in.level = 0;
481         r.in.bufsize = 8192;
482         r.in.servertype = 0xffffffff;
483         r.in.servertype = 0x80000000;
484         r.in.domain = NULL;
485
486         torture_assert_ntstatus_ok(tctx, 
487                    smbcli_rap_netserverenum2(cli->tree, lp_iconv_convenience(tctx->lp_ctx), tctx, &r), "");
488
489         for (i=0; i<r.out.count; i++) {
490                 switch (r.in.level) {
491                 case 0:
492                         printf("%s\n", r.out.info[i].info0.name);
493                         break;
494                 case 1:
495                         printf("%s %x %s\n", r.out.info[i].info1.name,
496                                r.out.info[i].info1.servertype,
497                                r.out.info[i].info1.comment);
498                         break;
499                 }
500         }
501
502         return true;
503 }
504
505 NTSTATUS smbcli_rap_netservergetinfo(struct smbcli_tree *tree,
506                                               struct smb_iconv_convenience *iconv_convenience, 
507                                      TALLOC_CTX *mem_ctx,
508                                      struct rap_WserverGetInfo *r)
509 {
510         struct rap_call *call;
511         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
512
513         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WserverGetInfo))) {
514                 return NT_STATUS_NO_MEMORY;
515         }
516
517         rap_cli_push_word(call, r->in.level);
518         rap_cli_push_rcvbuf(call, r->in.bufsize);
519         rap_cli_expect_word(call);
520
521         switch(r->in.level) {
522         case 0:
523                 rap_cli_expect_format(call, "B16");
524                 break;
525         case 1:
526                 rap_cli_expect_format(call, "B16BBDz");
527                 break;
528         default:
529                 result = NT_STATUS_INVALID_PARAMETER;
530                 goto done;
531         }
532
533         if (DEBUGLEVEL >= 10) {
534                 NDR_PRINT_IN_DEBUG(rap_WserverGetInfo, r);
535         }
536
537         result = rap_cli_do_call(tree, iconv_convenience, call);
538
539         if (!NT_STATUS_IS_OK(result))
540                 goto done;
541
542         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
543         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
544         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
545
546         switch(r->in.level) {
547         case 0:
548                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
549                                         r->out.info.info0.name, 16));
550                 break;
551         case 1:
552                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
553                                         r->out.info.info1.name, 16));
554                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
555                                       &r->out.info.info1.version_major, 1));
556                 NDR_GOTO(ndr_pull_bytes(call->ndr_pull_data,
557                                       &r->out.info.info1.version_minor, 1));
558                 NDR_GOTO(ndr_pull_uint32(call->ndr_pull_data,
559                                        NDR_SCALARS, &r->out.info.info1.servertype));
560                 RAP_GOTO(rap_pull_string(mem_ctx, call->ndr_pull_data,
561                                        r->out.convert,
562                                        &r->out.info.info1.comment));
563         }
564
565         if (DEBUGLEVEL >= 10) {
566                 NDR_PRINT_OUT_DEBUG(rap_WserverGetInfo, r);
567         }
568  done:
569         talloc_free(call);
570         return result;
571 }
572
573 static NTSTATUS rap_pull_rap_JobInfo0(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintJobInfo0 *r)
574 {
575         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobID));
576
577         return NT_STATUS_OK;
578 }
579
580 static NTSTATUS rap_pull_rap_JobInfo1(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintJobInfo1 *r)
581 {
582         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobID));
583         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->UserName, 21, sizeof(uint8_t), CH_DOS));
584         NDR_RETURN(ndr_pull_uint8(ndr, NDR_SCALARS, &r->Pad));
585         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->NotifyName, 16, sizeof(uint8_t), CH_DOS));
586         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->DataType, 10, sizeof(uint8_t), CH_DOS));
587         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintParameterString));
588         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobPosition));
589         NDR_RETURN(ndr_pull_rap_PrintJStatusCode(ndr, NDR_SCALARS, &r->JobStatus));
590         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->JobStatusString));
591         NDR_RETURN(ndr_pull_time_t(ndr, NDR_SCALARS, &r->TimeSubmitted));
592         NDR_RETURN(ndr_pull_uint32(ndr, NDR_SCALARS, &r->JobSize));
593         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->JobCommentString));
594
595         return NT_STATUS_OK;
596 }
597
598 static NTSTATUS rap_pull_rap_JobInfo2(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintJobInfo2 *r)
599 {
600         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobID));
601         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Priority));
602         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->UserName));
603         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobPosition));
604         NDR_RETURN(ndr_pull_rap_PrintJStatusCode(ndr, NDR_SCALARS, &r->JobStatus));
605         NDR_RETURN(ndr_pull_time_t(ndr, NDR_SCALARS, &r->TimeSubmitted));
606         NDR_RETURN(ndr_pull_uint32(ndr, NDR_SCALARS, &r->JobSize));
607         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->JobCommentString));
608         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->DocumentName));
609
610         return NT_STATUS_OK;
611 }
612
613 static NTSTATUS rap_pull_rap_JobInfo3(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintJobInfo3 *r)
614 {
615         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobID));
616         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Priority));
617         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->UserName));
618         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobPosition));
619         NDR_RETURN(ndr_pull_rap_PrintJStatusCode(ndr, NDR_SCALARS, &r->JobStatus));
620         NDR_RETURN(ndr_pull_time_t(ndr, NDR_SCALARS, &r->TimeSubmitted));
621         NDR_RETURN(ndr_pull_uint32(ndr, NDR_SCALARS, &r->JobSize));
622         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->JobCommentString));
623         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->DocumentName));
624         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->NotifyName));
625         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->DataType));
626         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintParameterString));
627         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->StatusString));
628         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->QueueName));
629         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintProcessorName));
630         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintProcessorParams));
631         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->DriverName));
632         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->DriverDataOffset));
633         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrinterNameOffset));
634
635         return NT_STATUS_OK;
636 }
637
638 static NTSTATUS rap_pull_rap_PrintQueue0(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintQueue0 *r)
639 {
640         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->PrintQName, 13, sizeof(uint8_t), CH_DOS));
641
642         return NT_STATUS_OK;
643 }
644
645 static NTSTATUS rap_pull_rap_PrintQueue1(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintQueue1 *r)
646 {
647         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->PrintQName, 13, sizeof(uint8_t), CH_DOS));
648         NDR_RETURN(ndr_pull_uint8(ndr, NDR_SCALARS, &r->Pad1));
649         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Priority));
650         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->StartTime));
651         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->UntilTime));
652         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->SeparatorPageFilename));
653         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintProcessorDllName));
654         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintDestinationsName));
655         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintParameterString));
656         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->CommentString));
657         NDR_RETURN(ndr_pull_rap_PrintQStatusCode(ndr, NDR_SCALARS, &r->PrintQStatus));
658         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->PrintJobCount));
659
660         return NT_STATUS_OK;
661 }
662
663 static NTSTATUS rap_pull_rap_PrintQueue2(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintQueue2 *r)
664 {
665         int i;
666         RAP_RETURN(rap_pull_rap_PrintQueue1(mem_ctx, ndr, convert, &r->queue));
667         r->job = talloc_zero_array(mem_ctx, struct rap_PrintJobInfo1, r->queue.PrintJobCount);
668         if (r->job == NULL) {
669                 return NT_STATUS_NO_MEMORY;
670         }
671         for (i=0; i < r->queue.PrintJobCount; i++) {
672                 RAP_RETURN(rap_pull_rap_JobInfo1(mem_ctx, ndr, convert, &r->job[i]));
673         }
674
675         return NT_STATUS_OK;
676 }
677
678 static NTSTATUS rap_pull_rap_PrintQueue3(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintQueue3 *r)
679 {
680         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintQueueName));
681         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Priority));
682         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->StartTime));
683         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->UntilTime));
684         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Pad));
685         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->SeparatorPageFilename));
686         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintProcessorDllName));
687         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintParameterString));
688         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->CommentString));
689         NDR_RETURN(ndr_pull_rap_PrintQStatusCode(ndr, NDR_SCALARS, &r->PrintQStatus));
690         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->PrintJobCount));
691         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->Printers));
692         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->DriverName));
693         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintDriverData));
694
695         return NT_STATUS_OK;
696 }
697
698 static NTSTATUS rap_pull_rap_PrintQueue4(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintQueue4 *r)
699 {
700         int i;
701         RAP_RETURN(rap_pull_rap_PrintQueue3(mem_ctx, ndr, convert, &r->queue));
702         r->job = talloc_zero_array(mem_ctx, struct rap_PrintJobInfo2, r->queue.PrintJobCount);
703         if (r->job == NULL) {
704                 return NT_STATUS_NO_MEMORY;
705         }
706         for (i=0; i < r->queue.PrintJobCount; i++) {
707                 RAP_RETURN(rap_pull_rap_JobInfo2(mem_ctx, ndr, convert, &r->job[i]));
708         }
709
710         return NT_STATUS_OK;
711 }
712
713 static NTSTATUS rap_pull_rap_PrintQueue5(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintQueue5 *r)
714 {
715         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrintQueueName));
716
717         return NT_STATUS_OK;
718 }
719
720 NTSTATUS smbcli_rap_netprintqenum(struct smbcli_tree *tree,
721                                   struct smb_iconv_convenience *iconv_convenience,
722                                   TALLOC_CTX *mem_ctx,
723                                   struct rap_NetPrintQEnum *r)
724 {
725         struct rap_call *call;
726         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
727         int i;
728
729         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintQEnum))) {
730                 return NT_STATUS_NO_MEMORY;
731         }
732
733         rap_cli_push_word(call, r->in.level);
734         rap_cli_push_rcvbuf(call, r->in.bufsize);
735         rap_cli_expect_multiple_entries(call);
736
737         switch(r->in.level) {
738         case 0:
739                 rap_cli_expect_format(call, "B13");
740                 break;
741         case 1:
742                 rap_cli_expect_format(call, "B13BWWWzzzzzWW");
743                 break;
744         case 2:
745                 rap_cli_expect_format(call, "B13BWWWzzzzzWN");
746                 rap_cli_expect_extra_format(call, "WB21BB16B10zWWzDDz");
747                 break;
748         case 3:
749                 rap_cli_expect_format(call, "zWWWWzzzzWWzzl");
750                 break;
751         case 4:
752                 rap_cli_expect_format(call, "zWWWWzzzzWNzzl");
753                 rap_cli_expect_extra_format(call, "WWzWWDDzz");
754                 /* no mention of extra format in MS-RAP */
755                 break;
756         case 5:
757                 rap_cli_expect_format(call, "z");
758                 break;
759         default:
760                 result = NT_STATUS_INVALID_PARAMETER;
761                 goto done;
762         }
763
764         if (DEBUGLEVEL >= 10) {
765                 NDR_PRINT_IN_DEBUG(rap_NetPrintQEnum, r);
766         }
767
768         result = rap_cli_do_call(tree, iconv_convenience, call);
769
770         if (!NT_STATUS_IS_OK(result))
771                 goto done;
772
773         result = NT_STATUS_INVALID_PARAMETER;
774
775         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
776         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
777         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
778         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
779
780         r->out.info = talloc_zero_array(mem_ctx, union rap_printq_info, r->out.count);
781
782         if (r->out.info == NULL) {
783                 result = NT_STATUS_NO_MEMORY;
784                 goto done;
785         }
786
787         for (i=0; i<r->out.count; i++) {
788                 switch(r->in.level) {
789                 case 0:
790                         result = rap_pull_rap_PrintQueue0(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info0);
791                         break;
792                 case 1:
793                         result = rap_pull_rap_PrintQueue1(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info1);
794                         break;
795                 case 2:
796                         result = rap_pull_rap_PrintQueue2(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info2);
797                         break;
798                 case 3:
799                         result = rap_pull_rap_PrintQueue3(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info3);
800                         break;
801                 case 4:
802                         result = rap_pull_rap_PrintQueue4(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info4);
803                         break;
804                 case 5:
805                         result = rap_pull_rap_PrintQueue5(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info5);
806                         break;
807                 }
808         }
809
810         if (!NT_STATUS_IS_OK(result)) {
811                 goto done;
812         }
813
814         if (DEBUGLEVEL >= 10) {
815                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQEnum, r);
816         }
817
818         result = NT_STATUS_OK;
819
820  done:
821         talloc_free(call);
822         return result;
823 }
824
825 NTSTATUS smbcli_rap_netprintqgetinfo(struct smbcli_tree *tree,
826                                      struct smb_iconv_convenience *iconv_convenience,
827                                      TALLOC_CTX *mem_ctx,
828                                      struct rap_NetPrintQGetInfo *r)
829 {
830         struct rap_call *call;
831         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
832
833         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintQGetInfo))) {
834                 return NT_STATUS_NO_MEMORY;
835         }
836
837         rap_cli_push_string(call, r->in.PrintQueueName);
838         rap_cli_push_word(call, r->in.level);
839         rap_cli_push_rcvbuf(call, r->in.bufsize);
840         rap_cli_expect_word(call);
841
842         switch(r->in.level) {
843         case 0:
844                 rap_cli_expect_format(call, "B13");
845                 break;
846         case 1:
847                 rap_cli_expect_format(call, "B13BWWWzzzzzWW");
848                 break;
849         case 2:
850                 rap_cli_expect_format(call, "B13BWWWzzzzzWN");
851                 rap_cli_expect_extra_format(call, "WB21BB16B10zWWzDDz");
852                 break;
853         case 3:
854                 rap_cli_expect_format(call, "zWWWWzzzzWWzzl");
855                 break;
856         case 4:
857                 rap_cli_expect_format(call, "zWWWWzzzzWNzzl");
858                 rap_cli_expect_extra_format(call, "WWzWWDDzz");
859                 /* no mention of extra format in MS-RAP */
860                 break;
861         case 5:
862                 rap_cli_expect_format(call, "z");
863                 break;
864         default:
865                 result = NT_STATUS_INVALID_PARAMETER;
866                 goto done;
867         }
868
869         if (DEBUGLEVEL >= 10) {
870                 NDR_PRINT_IN_DEBUG(rap_NetPrintQGetInfo, r);
871         }
872
873         result = rap_cli_do_call(tree, iconv_convenience, call);
874
875         if (!NT_STATUS_IS_OK(result))
876                 goto done;
877
878         result = NT_STATUS_INVALID_PARAMETER;
879
880         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
881         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
882         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
883
884         switch(r->in.level) {
885         case 0:
886                 result = rap_pull_rap_PrintQueue0(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info0);
887                 break;
888         case 1:
889                 result = rap_pull_rap_PrintQueue1(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info1);
890                 break;
891         case 2:
892                 result = rap_pull_rap_PrintQueue2(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info2);
893                 break;
894         case 3:
895                 result = rap_pull_rap_PrintQueue3(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info3);
896                 break;
897         case 4:
898                 result = rap_pull_rap_PrintQueue4(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info4);
899                 break;
900         case 5:
901                 result = rap_pull_rap_PrintQueue5(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info5);
902                 break;
903         }
904
905         if (!NT_STATUS_IS_OK(result)) {
906                 goto done;
907         }
908
909         if (DEBUGLEVEL >= 10) {
910                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQGetInfo, r);
911         }
912
913  done:
914         talloc_free(call);
915         return result;
916 }
917
918 NTSTATUS smbcli_rap_netprintjobpause(struct smbcli_tree *tree,
919                                      struct smb_iconv_convenience *iconv_convenience,
920                                      TALLOC_CTX *mem_ctx,
921                                      struct rap_NetPrintJobPause *r)
922 {
923         struct rap_call *call;
924         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
925
926         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintJobPause))) {
927                 return NT_STATUS_NO_MEMORY;
928         }
929
930         rap_cli_push_word(call, r->in.JobID);
931
932         rap_cli_expect_format(call, "W");
933
934         if (DEBUGLEVEL >= 10) {
935                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobPause, r);
936         }
937
938         result = rap_cli_do_call(tree, iconv_convenience, call);
939
940         if (!NT_STATUS_IS_OK(result))
941                 goto done;
942
943         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
944         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
945
946         if (DEBUGLEVEL >= 10) {
947                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobPause, r);
948         }
949
950  done:
951         talloc_free(call);
952         return result;
953 }
954
955 NTSTATUS smbcli_rap_netprintjobcontinue(struct smbcli_tree *tree,
956                                         struct smb_iconv_convenience *iconv_convenience,
957                                         TALLOC_CTX *mem_ctx,
958                                         struct rap_NetPrintJobContinue *r)
959 {
960         struct rap_call *call;
961         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
962
963         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintJobContinue))) {
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_NetPrintJobContinue, r);
973         }
974
975         result = rap_cli_do_call(tree, iconv_convenience, 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_NetPrintJobContinue, r);
985         }
986
987  done:
988         talloc_free(call);
989         return result;
990 }
991
992 NTSTATUS smbcli_rap_netprintjobdelete(struct smbcli_tree *tree,
993                                       struct smb_iconv_convenience *iconv_convenience,
994                                       TALLOC_CTX *mem_ctx,
995                                       struct rap_NetPrintJobDelete *r)
996 {
997         struct rap_call *call;
998         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
999
1000         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintJobDel))) {
1001                 return NT_STATUS_NO_MEMORY;
1002         }
1003
1004         rap_cli_push_word(call, r->in.JobID);
1005
1006         rap_cli_expect_format(call, "W");
1007
1008         if (DEBUGLEVEL >= 10) {
1009                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobDelete, r);
1010         }
1011
1012         result = rap_cli_do_call(tree, iconv_convenience, call);
1013
1014         if (!NT_STATUS_IS_OK(result))
1015                 goto done;
1016
1017         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1018         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1019
1020         if (DEBUGLEVEL >= 10) {
1021                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobDelete, r);
1022         }
1023
1024  done:
1025         talloc_free(call);
1026         return result;
1027 }
1028
1029 NTSTATUS smbcli_rap_netprintqueuepause(struct smbcli_tree *tree,
1030                                        struct smb_iconv_convenience *iconv_convenience,
1031                                        TALLOC_CTX *mem_ctx,
1032                                        struct rap_NetPrintQueuePause *r)
1033 {
1034         struct rap_call *call;
1035         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1036
1037         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintQPause))) {
1038                 return NT_STATUS_NO_MEMORY;
1039         }
1040
1041         rap_cli_push_string(call, r->in.PrintQueueName);
1042
1043         rap_cli_expect_format(call, "");
1044
1045         if (DEBUGLEVEL >= 10) {
1046                 NDR_PRINT_IN_DEBUG(rap_NetPrintQueuePause, r);
1047         }
1048
1049         result = rap_cli_do_call(tree, iconv_convenience, call);
1050
1051         if (!NT_STATUS_IS_OK(result))
1052                 goto done;
1053
1054         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1055         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1056
1057         if (DEBUGLEVEL >= 10) {
1058                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQueuePause, r);
1059         }
1060
1061  done:
1062         talloc_free(call);
1063         return result;
1064 }
1065
1066 NTSTATUS smbcli_rap_netprintqueueresume(struct smbcli_tree *tree,
1067                                         struct smb_iconv_convenience *iconv_convenience,
1068                                         TALLOC_CTX *mem_ctx,
1069                                         struct rap_NetPrintQueueResume *r)
1070 {
1071         struct rap_call *call;
1072         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1073
1074         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintQContinue))) {
1075                 return NT_STATUS_NO_MEMORY;
1076         }
1077
1078         rap_cli_push_string(call, r->in.PrintQueueName);
1079
1080         rap_cli_expect_format(call, "");
1081
1082         if (DEBUGLEVEL >= 10) {
1083                 NDR_PRINT_IN_DEBUG(rap_NetPrintQueueResume, r);
1084         }
1085
1086         result = rap_cli_do_call(tree, iconv_convenience, call);
1087
1088         if (!NT_STATUS_IS_OK(result))
1089                 goto done;
1090
1091         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1092         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1093
1094         if (DEBUGLEVEL >= 10) {
1095                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQueueResume, r);
1096         }
1097
1098  done:
1099         talloc_free(call);
1100         return result;
1101 }
1102
1103 NTSTATUS smbcli_rap_netprintqueuepurge(struct smbcli_tree *tree,
1104                                        struct smb_iconv_convenience *iconv_convenience,
1105                                        TALLOC_CTX *mem_ctx,
1106                                        struct rap_NetPrintQueuePurge *r)
1107 {
1108         struct rap_call *call;
1109         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1110
1111         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintQPurge))) {
1112                 return NT_STATUS_NO_MEMORY;
1113         }
1114
1115         rap_cli_push_string(call, r->in.PrintQueueName);
1116
1117         rap_cli_expect_format(call, "");
1118
1119         if (DEBUGLEVEL >= 10) {
1120                 NDR_PRINT_IN_DEBUG(rap_NetPrintQueuePurge, r);
1121         }
1122
1123         result = rap_cli_do_call(tree, iconv_convenience, call);
1124
1125         if (!NT_STATUS_IS_OK(result))
1126                 goto done;
1127
1128         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1129         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1130
1131         if (DEBUGLEVEL >= 10) {
1132                 NDR_PRINT_OUT_DEBUG(rap_NetPrintQueuePurge, r);
1133         }
1134
1135  done:
1136         talloc_free(call);
1137         return result;
1138 }
1139
1140 NTSTATUS smbcli_rap_netprintjobenum(struct smbcli_tree *tree,
1141                                     struct smb_iconv_convenience *iconv_convenience,
1142                                     TALLOC_CTX *mem_ctx,
1143                                     struct rap_NetPrintJobEnum *r)
1144 {
1145         struct rap_call *call;
1146         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1147         int i;
1148
1149         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintJobEnum))) {
1150                 return NT_STATUS_NO_MEMORY;
1151         }
1152
1153         rap_cli_push_string(call, r->in.PrintQueueName);
1154         rap_cli_push_word(call, r->in.level);
1155         rap_cli_push_rcvbuf(call, r->in.bufsize);
1156         rap_cli_expect_multiple_entries(call);
1157
1158         switch(r->in.level) {
1159         case 0:
1160                 rap_cli_expect_format(call, "W");
1161                 break;
1162         case 1:
1163                 rap_cli_expect_format(call, "WB21BB16B10zWWzDDz");
1164                 break;
1165         case 2:
1166                 rap_cli_expect_format(call, "WWzWWDDzz");
1167                 break;
1168         case 3:
1169                 rap_cli_expect_format(call, "WWzWWDDzzzzzzzzzzlz");
1170                 break;
1171         case 4:
1172                 rap_cli_expect_format(call, "WWzWWDDzzzzzDDDDDDD");
1173                 break;
1174         default:
1175                 result = NT_STATUS_INVALID_PARAMETER;
1176                 goto done;
1177         }
1178
1179         if (DEBUGLEVEL >= 10) {
1180                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobEnum, r);
1181         }
1182
1183         result = rap_cli_do_call(tree, iconv_convenience, call);
1184
1185         if (!NT_STATUS_IS_OK(result))
1186                 goto done;
1187
1188         result = NT_STATUS_INVALID_PARAMETER;
1189
1190         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1191         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1192         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
1193         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1194
1195         r->out.info = talloc_zero_array(mem_ctx, union rap_printj_info, r->out.count);
1196
1197         if (r->out.info == NULL) {
1198                 result = NT_STATUS_NO_MEMORY;
1199                 goto done;
1200         }
1201
1202         result = NT_STATUS_OK;
1203
1204         for (i=0; i<r->out.count; i++) {
1205                 switch(r->in.level) {
1206                 case 0:
1207                         result = rap_pull_rap_JobInfo0(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info0);
1208                         break;
1209                 case 1:
1210                         result = rap_pull_rap_JobInfo1(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info1);
1211                         break;
1212                 case 2:
1213                         result = rap_pull_rap_JobInfo2(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info2);
1214                         break;
1215                 case 3:
1216                         result = rap_pull_rap_JobInfo3(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info3);
1217                         break;
1218                 }
1219         }
1220
1221         if (!NT_STATUS_IS_OK(result)) {
1222                 goto done;
1223         }
1224
1225         if (DEBUGLEVEL >= 10) {
1226                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobEnum, r);
1227         }
1228
1229         result = NT_STATUS_OK;
1230
1231  done:
1232         talloc_free(call);
1233         return result;
1234 }
1235
1236 NTSTATUS smbcli_rap_netprintjobgetinfo(struct smbcli_tree *tree,
1237                                        struct smb_iconv_convenience *iconv_convenience,
1238                                        TALLOC_CTX *mem_ctx,
1239                                        struct rap_NetPrintJobGetInfo *r)
1240 {
1241         struct rap_call *call;
1242         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1243
1244         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintJobGetInfo))) {
1245                 return NT_STATUS_NO_MEMORY;
1246         }
1247
1248         rap_cli_push_word(call, r->in.JobID);
1249         rap_cli_push_word(call, r->in.level);
1250         rap_cli_push_rcvbuf(call, r->in.bufsize);
1251         rap_cli_expect_word(call);
1252
1253         switch(r->in.level) {
1254         case 0:
1255                 rap_cli_expect_format(call, "W");
1256                 break;
1257         case 1:
1258                 rap_cli_expect_format(call, "WB21BB16B10zWWzDDz");
1259                 break;
1260         case 2:
1261                 rap_cli_expect_format(call, "WWzWWDDzz");
1262                 break;
1263         case 3:
1264                 rap_cli_expect_format(call, "WWzWWDDzzzzzzzzzzlz");
1265                 break;
1266         case 4:
1267                 rap_cli_expect_format(call, "WWzWWDDzzzzzDDDDDDD");
1268                 break;
1269         default:
1270                 result = NT_STATUS_INVALID_PARAMETER;
1271                 goto done;
1272         }
1273
1274         if (DEBUGLEVEL >= 10) {
1275                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobGetInfo, r);
1276         }
1277
1278         result = rap_cli_do_call(tree, iconv_convenience, call);
1279
1280         if (!NT_STATUS_IS_OK(result))
1281                 goto done;
1282
1283         result = NT_STATUS_INVALID_PARAMETER;
1284
1285         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1286         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1287         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1288
1289         switch(r->in.level) {
1290         case 0:
1291                 result = rap_pull_rap_JobInfo0(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info0);
1292                 break;
1293         case 1:
1294                 result = rap_pull_rap_JobInfo1(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info1);
1295                 break;
1296         case 2:
1297                 result = rap_pull_rap_JobInfo2(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info2);
1298                 break;
1299         case 3:
1300                 result = rap_pull_rap_JobInfo3(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info3);
1301                 break;
1302         default:
1303                 result = NT_STATUS_NOT_IMPLEMENTED;
1304                 break;
1305         }
1306
1307
1308         if (!NT_STATUS_IS_OK(result)) {
1309                 goto done;
1310         }
1311
1312         if (DEBUGLEVEL >= 10) {
1313                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobGetInfo, r);
1314         }
1315
1316  done:
1317         talloc_free(call);
1318         return result;
1319 }
1320
1321 NTSTATUS smbcli_rap_netprintjobsetinfo(struct smbcli_tree *tree,
1322                                        struct smb_iconv_convenience *iconv_convenience,
1323                                        TALLOC_CTX *mem_ctx,
1324                                        struct rap_NetPrintJobSetInfo *r)
1325 {
1326         struct rap_call *call;
1327         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1328
1329         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintJobSetInfo))) {
1330                 return NT_STATUS_NO_MEMORY;
1331         }
1332
1333         rap_cli_push_word(call, r->in.JobID);
1334         rap_cli_push_word(call, r->in.level);
1335         rap_cli_push_sendbuf(call, r->in.bufsize);
1336         rap_cli_push_param(call, r->in.ParamNum);
1337
1338         switch (r->in.ParamNum) {
1339         case RAP_PARAM_JOBNUM:
1340         case RAP_PARAM_JOBPOSITION:
1341         case RAP_PARAM_JOBSTATUS:
1342                 NDR_GOTO(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r->in.Param.value));
1343                 break;
1344         case RAP_PARAM_USERNAME:
1345         case RAP_PARAM_NOTIFYNAME:
1346         case RAP_PARAM_DATATYPE:
1347         case RAP_PARAM_PARAMETERS_STRING:
1348         case RAP_PARAM_JOBSTATUSSTR:
1349         case RAP_PARAM_JOBCOMMENT:
1350                 NDR_GOTO(ndr_push_string(call->ndr_push_param, NDR_SCALARS, r->in.Param.string));
1351                 break;
1352         case RAP_PARAM_TIMESUBMITTED:
1353         case RAP_PARAM_JOBSIZE:
1354                 NDR_GOTO(ndr_push_uint32(call->ndr_push_param, NDR_SCALARS, r->in.Param.value4));
1355                 break;
1356         default:
1357                 result = NT_STATUS_INVALID_PARAMETER;
1358                 break;
1359         }
1360
1361         /* not really sure if this is correct */
1362         rap_cli_expect_format(call, "WB21BB16B10zWWzDDz");
1363
1364         if (DEBUGLEVEL >= 10) {
1365                 NDR_PRINT_IN_DEBUG(rap_NetPrintJobSetInfo, r);
1366         }
1367
1368         result = rap_cli_do_call(tree, iconv_convenience, call);
1369
1370         if (!NT_STATUS_IS_OK(result))
1371                 goto done;
1372
1373         result = NT_STATUS_INVALID_PARAMETER;
1374
1375         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1376         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1377
1378         result = NT_STATUS_OK;
1379
1380         if (!NT_STATUS_IS_OK(result)) {
1381                 goto done;
1382         }
1383
1384         if (DEBUGLEVEL >= 10) {
1385                 NDR_PRINT_OUT_DEBUG(rap_NetPrintJobSetInfo, r);
1386         }
1387
1388  done:
1389         talloc_free(call);
1390         return result;
1391 }
1392
1393 static NTSTATUS rap_pull_rap_PrintDest0(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintDest0 *r)
1394 {
1395         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->PrintDestName, 9, sizeof(uint8_t), CH_DOS));
1396
1397         return NT_STATUS_OK;
1398 }
1399
1400 static NTSTATUS rap_pull_rap_PrintDest1(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintDest1 *r)
1401 {
1402         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->PrintDestName, 9, sizeof(uint8_t), CH_DOS));
1403         NDR_RETURN(ndr_pull_charset(ndr, NDR_SCALARS, &r->UserName, 21, sizeof(uint8_t), CH_DOS));
1404         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobId));
1405         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Status));
1406         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->StatusStringName));
1407         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Time));
1408
1409         return NT_STATUS_OK;
1410 }
1411
1412 static NTSTATUS rap_pull_rap_PrintDest2(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintDest2 *r)
1413 {
1414         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrinterName));
1415
1416         return NT_STATUS_OK;
1417 }
1418
1419 static NTSTATUS rap_pull_rap_PrintDest3(TALLOC_CTX *mem_ctx, struct ndr_pull *ndr, uint16_t convert, struct rap_PrintDest3 *r)
1420 {
1421         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->PrinterName));
1422         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->UserName));
1423         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->LogAddr));
1424         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->JobId));
1425         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Status));
1426         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->StatusStringName));
1427         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->Comment));
1428         RAP_RETURN(rap_pull_string(mem_ctx, ndr, convert, &r->Drivers));
1429         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Time));
1430         NDR_RETURN(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Pad1));
1431
1432         return NT_STATUS_OK;
1433
1434 }
1435
1436 NTSTATUS smbcli_rap_netprintdestenum(struct smbcli_tree *tree,
1437                                      struct smb_iconv_convenience *iconv_convenience,
1438                                      TALLOC_CTX *mem_ctx,
1439                                      struct rap_NetPrintDestEnum *r)
1440 {
1441         struct rap_call *call;
1442         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1443         int i;
1444
1445         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintDestEnum))) {
1446                 return NT_STATUS_NO_MEMORY;
1447         }
1448
1449         rap_cli_push_word(call, r->in.level);
1450         rap_cli_push_rcvbuf(call, r->in.bufsize);
1451         rap_cli_expect_multiple_entries(call);
1452
1453         switch(r->in.level) {
1454         case 0:
1455                 rap_cli_expect_format(call, "B9");
1456                 break;
1457         case 1:
1458                 rap_cli_expect_format(call, "B9B21WWzW");
1459                 break;
1460         case 2:
1461                 rap_cli_expect_format(call, "z");
1462                 break;
1463         case 3:
1464                 rap_cli_expect_format(call, "zzzWWzzzWW");
1465                 break;
1466         default:
1467                 result = NT_STATUS_INVALID_PARAMETER;
1468                 goto done;
1469         }
1470
1471         if (DEBUGLEVEL >= 10) {
1472                 NDR_PRINT_IN_DEBUG(rap_NetPrintDestEnum, r);
1473         }
1474
1475         result = rap_cli_do_call(tree, iconv_convenience, call);
1476
1477         if (!NT_STATUS_IS_OK(result))
1478                 goto done;
1479
1480         result = NT_STATUS_INVALID_PARAMETER;
1481
1482         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1483         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1484         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.count));
1485         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1486
1487         r->out.info = talloc_zero_array(mem_ctx, union rap_printdest_info, r->out.count);
1488
1489         if (r->out.info == NULL) {
1490                 result = NT_STATUS_NO_MEMORY;
1491                 goto done;
1492         }
1493
1494         result = NT_STATUS_OK;
1495
1496         for (i=0; i<r->out.count; i++) {
1497                 switch(r->in.level) {
1498                 case 0:
1499                         result = rap_pull_rap_PrintDest0(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info0);
1500                         break;
1501                 case 1:
1502                         result = rap_pull_rap_PrintDest1(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info1);
1503                         break;
1504                 case 2:
1505                         result = rap_pull_rap_PrintDest2(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info2);
1506                         break;
1507                 case 3:
1508                         result = rap_pull_rap_PrintDest3(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info[i].info3);
1509                         break;
1510                 }
1511         }
1512
1513         if (!NT_STATUS_IS_OK(result)) {
1514                 goto done;
1515         }
1516
1517         if (DEBUGLEVEL >= 10) {
1518                 NDR_PRINT_OUT_DEBUG(rap_NetPrintDestEnum, r);
1519         }
1520
1521         result = NT_STATUS_OK;
1522
1523  done:
1524         talloc_free(call);
1525         return result;
1526 }
1527
1528 NTSTATUS smbcli_rap_netprintdestgetinfo(struct smbcli_tree *tree,
1529                                         struct smb_iconv_convenience *iconv_convenience,
1530                                         TALLOC_CTX *mem_ctx,
1531                                         struct rap_NetPrintDestGetInfo *r)
1532 {
1533         struct rap_call *call;
1534         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1535
1536         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WPrintDestGetInfo))) {
1537                 return NT_STATUS_NO_MEMORY;
1538         }
1539
1540         rap_cli_push_string(call, r->in.PrintDestName);
1541         rap_cli_push_word(call, r->in.level);
1542         rap_cli_push_rcvbuf(call, r->in.bufsize);
1543         rap_cli_expect_word(call);
1544
1545         switch(r->in.level) {
1546         case 0:
1547                 rap_cli_expect_format(call, "B9");
1548                 break;
1549         case 1:
1550                 rap_cli_expect_format(call, "B9B21WWzW");
1551                 break;
1552         case 2:
1553                 rap_cli_expect_format(call, "z");
1554                 break;
1555         case 3:
1556                 rap_cli_expect_format(call, "zzzWWzzzWW");
1557                 break;
1558         default:
1559                 result = NT_STATUS_INVALID_PARAMETER;
1560                 goto done;
1561         }
1562
1563         if (DEBUGLEVEL >= 10) {
1564                 NDR_PRINT_IN_DEBUG(rap_NetPrintDestGetInfo, r);
1565         }
1566
1567         result = rap_cli_do_call(tree, iconv_convenience, call);
1568
1569         if (!NT_STATUS_IS_OK(result))
1570                 goto done;
1571
1572         result = NT_STATUS_INVALID_PARAMETER;
1573
1574         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1575         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1576         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.available));
1577
1578         switch(r->in.level) {
1579         case 0:
1580                 result = rap_pull_rap_PrintDest0(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info0);
1581                 break;
1582         case 1:
1583                 result = rap_pull_rap_PrintDest1(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info1);
1584                 break;
1585         case 2:
1586                 result = rap_pull_rap_PrintDest2(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info2);
1587                 break;
1588         case 3:
1589                 result = rap_pull_rap_PrintDest3(mem_ctx, call->ndr_pull_data, r->out.convert, &r->out.info.info3);
1590                 break;
1591         }
1592
1593         if (!NT_STATUS_IS_OK(result)) {
1594                 goto done;
1595         }
1596
1597         if (DEBUGLEVEL >= 10) {
1598                 NDR_PRINT_OUT_DEBUG(rap_NetPrintDestGetInfo, r);
1599         }
1600
1601         result = NT_STATUS_OK;
1602
1603  done:
1604         talloc_free(call);
1605         return result;
1606 }
1607
1608 NTSTATUS smbcli_rap_netuserpasswordset2(struct smbcli_tree *tree,
1609                                         struct smb_iconv_convenience *iconv_convenience,
1610                                         TALLOC_CTX *mem_ctx,
1611                                         struct rap_NetUserPasswordSet2 *r)
1612 {
1613         struct rap_call *call;
1614         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1615
1616         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_WUserPasswordSet2))) {
1617                 return NT_STATUS_NO_MEMORY;
1618         }
1619
1620         rap_cli_push_string(call, r->in.UserName);
1621         rap_cli_push_paramdesc(call, 'b');
1622         rap_cli_push_paramdesc(call, '1');
1623         rap_cli_push_paramdesc(call, '6');
1624         ndr_push_charset(call->ndr_push_param, NDR_SCALARS, r->in.OldPassword, 16, sizeof(uint8_t), CH_DOS);
1625         rap_cli_push_paramdesc(call, 'b');
1626         rap_cli_push_paramdesc(call, '1');
1627         rap_cli_push_paramdesc(call, '6');
1628         ndr_push_charset(call->ndr_push_param, NDR_SCALARS, r->in.NewPassword, 16, sizeof(uint8_t), CH_DOS);
1629         rap_cli_push_word(call, r->in.EncryptedPassword);
1630         rap_cli_push_word(call, r->in.RealPasswordLength);
1631
1632         rap_cli_expect_format(call, "");
1633
1634         if (DEBUGLEVEL >= 10) {
1635                 NDR_PRINT_IN_DEBUG(rap_NetUserPasswordSet2, r);
1636         }
1637
1638         result = rap_cli_do_call(tree, iconv_convenience, call);
1639
1640         if (!NT_STATUS_IS_OK(result))
1641                 goto done;
1642
1643         result = NT_STATUS_INVALID_PARAMETER;
1644
1645         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1646         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1647
1648         result = NT_STATUS_OK;
1649
1650         if (!NT_STATUS_IS_OK(result)) {
1651                 goto done;
1652         }
1653
1654         if (DEBUGLEVEL >= 10) {
1655                 NDR_PRINT_OUT_DEBUG(rap_NetUserPasswordSet2, r);
1656         }
1657
1658  done:
1659         talloc_free(call);
1660         return result;
1661 }
1662
1663 NTSTATUS smbcli_rap_netoemchangepassword(struct smbcli_tree *tree,
1664                                          struct smb_iconv_convenience *iconv_convenience,
1665                                          TALLOC_CTX *mem_ctx,
1666                                          struct rap_NetOEMChangePassword *r)
1667 {
1668         struct rap_call *call;
1669         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1670
1671         if (!(call = new_rap_cli_call(mem_ctx, iconv_convenience, RAP_SamOEMChgPasswordUser2_P))) {
1672                 return NT_STATUS_NO_MEMORY;
1673         }
1674
1675         rap_cli_push_string(call, r->in.UserName);
1676         rap_cli_push_sendbuf(call, 532);
1677         ndr_push_array_uint8(call->ndr_push_data, NDR_SCALARS, r->in.crypt_password, 516);
1678         ndr_push_array_uint8(call->ndr_push_data, NDR_SCALARS, r->in.password_hash, 16);
1679
1680         rap_cli_expect_format(call, "B516B16");
1681
1682         if (DEBUGLEVEL >= 10) {
1683                 NDR_PRINT_IN_DEBUG(rap_NetOEMChangePassword, r);
1684         }
1685
1686         result = rap_cli_do_call(tree, iconv_convenience, call);
1687
1688         if (!NT_STATUS_IS_OK(result))
1689                 goto done;
1690
1691         result = NT_STATUS_INVALID_PARAMETER;
1692
1693         NDR_GOTO(ndr_pull_rap_status(call->ndr_pull_param, NDR_SCALARS, &r->out.status));
1694         NDR_GOTO(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &r->out.convert));
1695
1696         result = NT_STATUS_OK;
1697
1698         if (!NT_STATUS_IS_OK(result)) {
1699                 goto done;
1700         }
1701
1702         if (DEBUGLEVEL >= 10) {
1703                 NDR_PRINT_OUT_DEBUG(rap_NetOEMChangePassword, r);
1704         }
1705
1706  done:
1707         talloc_free(call);
1708         return result;
1709 }
1710
1711 static bool test_netservergetinfo(struct torture_context *tctx, 
1712                                   struct smbcli_state *cli)
1713 {
1714         struct rap_WserverGetInfo r;
1715         bool res = true;
1716
1717         r.in.bufsize = 0xffff;
1718
1719         r.in.level = 0;
1720         torture_assert_ntstatus_ok(tctx,
1721                 smbcli_rap_netservergetinfo(cli->tree, lp_iconv_convenience(tctx->lp_ctx), tctx, &r),
1722                 "rap_netservergetinfo level 0 failed");
1723         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
1724                 "rap_netservergetinfo level 0 failed");
1725
1726         r.in.level = 1;
1727         torture_assert_ntstatus_ok(tctx,
1728                 smbcli_rap_netservergetinfo(cli->tree, lp_iconv_convenience(tctx->lp_ctx), tctx, &r),
1729                 "rap_netservergetinfo level 1 failed");
1730         torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
1731                 "rap_netservergetinfo level 1 failed");
1732
1733         return res;
1734 }
1735
1736 bool torture_rap_scan(struct torture_context *torture, struct smbcli_state *cli)
1737 {
1738         int callno;
1739
1740         for (callno = 0; callno < 0xffff; callno++) {
1741                 struct rap_call *call = new_rap_cli_call(torture, lp_iconv_convenience(torture->lp_ctx), callno);
1742                 NTSTATUS result;
1743
1744                 result = rap_cli_do_call(cli->tree, lp_iconv_convenience(torture->lp_ctx), call);
1745
1746                 if (!NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER))
1747                         continue;
1748
1749                 printf("callno %d is RAP call\n", callno);
1750         }
1751
1752         return true;
1753 }
1754
1755 NTSTATUS torture_rap_init(void)
1756 {
1757         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "RAP");
1758         struct torture_suite *suite_basic = torture_suite_create(suite, "BASIC");
1759
1760         torture_suite_add_suite(suite, suite_basic);
1761         torture_suite_add_suite(suite, torture_rap_rpc(suite));
1762         torture_suite_add_suite(suite, torture_rap_printing(suite));
1763
1764         torture_suite_add_1smb_test(suite_basic, "netserverenum", 
1765                                     test_netserverenum);
1766         torture_suite_add_1smb_test(suite_basic, "netshareenum",
1767                                     test_netshareenum);
1768         torture_suite_add_1smb_test(suite_basic, "netservergetinfo",
1769                                     test_netservergetinfo);
1770
1771         torture_suite_add_1smb_test(suite, "SCAN", torture_rap_scan);
1772
1773         suite->description = talloc_strdup(suite, 
1774                                                 "Remote Administration Protocol tests");
1775
1776         torture_register_suite(suite);
1777
1778         return NT_STATUS_OK;
1779 }