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