1/*
2   Unix SMB/CIFS implementation.
3   RPC pipe client
4   Copyright (C) Tim Potter                        2000-2001,
5   Copyright (C) Andrew Tridgell              1992-1997,2000,
6   Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
7   Copyright (C) Paul Ashton                       1997,2000,
8   Copyright (C) Elrond                                 2000,
9   Copyright (C) Rafal Szczesniak                       2002.
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 2 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software
23   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24*/
25
26#include "includes.h"
27
28/* Connect to SAMR database */
29
30NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
31                          uint32 access_mask, POLICY_HND *connect_pol)
32{
33	prs_struct qbuf, rbuf;
34	SAMR_Q_CONNECT q;
35	SAMR_R_CONNECT r;
36	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
37
38	DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
39
40	ZERO_STRUCT(q);
41	ZERO_STRUCT(r);
42
43	/* Initialise parse structures */
44
45	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
46	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
47
48	/* Marshall data and send request */
49
50	init_samr_q_connect(&q, cli->desthost, access_mask);
51
52	if (!samr_io_q_connect("", &q, &qbuf, 0) ||
53	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT, &qbuf, &rbuf))
54		goto done;
55
56	/* Unmarshall response */
57
58	if (!samr_io_r_connect("", &r, &rbuf, 0))
59		goto done;
60
61	/* Return output parameters */
62
63	if (NT_STATUS_IS_OK(result = r.status)) {
64		*connect_pol = r.connect_pol;
65#ifdef __INSURE__
66		connect_pol->marker = malloc(1);
67#endif
68	}
69
70 done:
71	prs_mem_free(&qbuf);
72	prs_mem_free(&rbuf);
73
74	return result;
75}
76
77/* Connect to SAMR database */
78
79NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
80			   uint32 access_mask, POLICY_HND *connect_pol)
81{
82	prs_struct qbuf, rbuf;
83	SAMR_Q_CONNECT4 q;
84	SAMR_R_CONNECT4 r;
85	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
86
87	DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
88
89	ZERO_STRUCT(q);
90	ZERO_STRUCT(r);
91
92	/* Initialise parse structures */
93
94	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
95	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
96
97	/* Marshall data and send request */
98
99	init_samr_q_connect4(&q, cli->desthost, access_mask);
100
101	if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
102	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT4, &qbuf, &rbuf))
103		goto done;
104
105	/* Unmarshall response */
106
107	if (!samr_io_r_connect4("", &r, &rbuf, 0))
108		goto done;
109
110	/* Return output parameters */
111
112	if (NT_STATUS_IS_OK(result = r.status)) {
113		*connect_pol = r.connect_pol;
114#ifdef __INSURE__
115		connect_pol->marker = malloc(1);
116#endif
117	}
118
119 done:
120	prs_mem_free(&qbuf);
121	prs_mem_free(&rbuf);
122
123	return result;
124}
125
126/* Close SAMR handle */
127
128NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
129                        POLICY_HND *connect_pol)
130{
131	prs_struct qbuf, rbuf;
132	SAMR_Q_CLOSE_HND q;
133	SAMR_R_CLOSE_HND r;
134	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
135
136	DEBUG(10,("cli_samr_close\n"));
137
138	ZERO_STRUCT(q);
139	ZERO_STRUCT(r);
140
141	/* Initialise parse structures */
142
143	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
144	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
145
146	/* Marshall data and send request */
147
148	init_samr_q_close_hnd(&q, connect_pol);
149
150	if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
151	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CLOSE_HND, &qbuf, &rbuf))
152		goto done;
153
154	/* Unmarshall response */
155
156	if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
157		goto done;
158
159	/* Return output parameters */
160
161	if (NT_STATUS_IS_OK(result = r.status)) {
162#ifdef __INSURE__
163		SAFE_FREE(connect_pol->marker);
164#endif
165		*connect_pol = r.pol;
166	}
167
168 done:
169	prs_mem_free(&qbuf);
170	prs_mem_free(&rbuf);
171
172	return result;
173}
174
175/* Open handle on a domain */
176
177NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
178                              POLICY_HND *connect_pol, uint32 access_mask,
179                              const DOM_SID *domain_sid, POLICY_HND *domain_pol)
180{
181	prs_struct qbuf, rbuf;
182	SAMR_Q_OPEN_DOMAIN q;
183	SAMR_R_OPEN_DOMAIN r;
184	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
185
186	DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
187
188	ZERO_STRUCT(q);
189	ZERO_STRUCT(r);
190
191	/* Initialise parse structures */
192
193	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
194	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
195
196	/* Marshall data and send request */
197
198	init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
199
200	if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
201	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
202		goto done;
203
204	/* Unmarshall response */
205
206	if (!samr_io_r_open_domain("", &r, &rbuf, 0))
207		goto done;
208
209	/* Return output parameters */
210
211	if (NT_STATUS_IS_OK(result = r.status)) {
212		*domain_pol = r.domain_pol;
213#ifdef __INSURE__
214		domain_pol->marker = malloc(1);
215#endif
216	}
217
218 done:
219	prs_mem_free(&qbuf);
220	prs_mem_free(&rbuf);
221
222	return result;
223}
224
225/* Open handle on a user */
226
227NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
228                            POLICY_HND *domain_pol, uint32 access_mask,
229                            uint32 user_rid, POLICY_HND *user_pol)
230{
231	prs_struct qbuf, rbuf;
232	SAMR_Q_OPEN_USER q;
233	SAMR_R_OPEN_USER r;
234	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
235
236	DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
237
238	ZERO_STRUCT(q);
239	ZERO_STRUCT(r);
240
241	/* Initialise parse structures */
242
243	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
244	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
245
246	/* Marshall data and send request */
247
248	init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
249
250	if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
251	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_USER, &qbuf, &rbuf))
252		goto done;
253
254	/* Unmarshall response */
255
256	if (!samr_io_r_open_user("", &r, &rbuf, 0))
257		goto done;
258
259	/* Return output parameters */
260
261	if (NT_STATUS_IS_OK(result = r.status)) {
262		*user_pol = r.user_pol;
263#ifdef __INSURE__
264		user_pol->marker = malloc(1);
265#endif
266	}
267
268 done:
269	prs_mem_free(&qbuf);
270	prs_mem_free(&rbuf);
271
272	return result;
273}
274
275/* Open handle on a group */
276
277NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
278                             POLICY_HND *domain_pol, uint32 access_mask,
279                             uint32 group_rid, POLICY_HND *group_pol)
280{
281	prs_struct qbuf, rbuf;
282	SAMR_Q_OPEN_GROUP q;
283	SAMR_R_OPEN_GROUP r;
284	NTSTATUS result =  NT_STATUS_UNSUCCESSFUL;
285
286	DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
287
288	ZERO_STRUCT(q);
289	ZERO_STRUCT(r);
290
291	/* Initialise parse structures */
292
293	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
294	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
295
296	/* Marshall data and send request */
297
298	init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
299
300	if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
301	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_GROUP, &qbuf, &rbuf))
302		goto done;
303
304	/* Unmarshall response */
305
306	if (!samr_io_r_open_group("", &r, &rbuf, 0))
307		goto done;
308
309	/* Return output parameters */
310
311	if (NT_STATUS_IS_OK(result = r.status)) {
312		*group_pol = r.pol;
313#ifdef __INSURE__
314		group_pol->marker = malloc(1);
315#endif
316	}
317
318 done:
319	prs_mem_free(&qbuf);
320	prs_mem_free(&rbuf);
321
322	return result;
323}
324
325/* Create domain group */
326
327NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
328				   POLICY_HND *domain_pol,
329				   const char *group_name,
330				   uint32 access_mask, POLICY_HND *group_pol)
331{
332	prs_struct qbuf, rbuf;
333	SAMR_Q_CREATE_DOM_GROUP q;
334	SAMR_R_CREATE_DOM_GROUP r;
335	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
336
337	DEBUG(10,("cli_samr_create_dom_group\n"));
338
339	ZERO_STRUCT(q);
340	ZERO_STRUCT(r);
341
342	/* Initialise parse structures */
343
344	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
345	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
346
347	/* Marshall data and send request */
348
349	init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask);
350
351	if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) ||
352	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
353		goto done;
354
355	/* Unmarshall response */
356
357	if (!samr_io_r_create_dom_group("", &r, &rbuf, 0))
358		goto done;
359
360	/* Return output parameters */
361
362	result = r.status;
363
364	if (NT_STATUS_IS_OK(result))
365		*group_pol = r.pol;
366
367 done:
368	prs_mem_free(&qbuf);
369	prs_mem_free(&rbuf);
370
371	return result;
372}
373
374/* Add a domain group member */
375
376NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
377			       POLICY_HND *group_pol, uint32 rid)
378{
379	prs_struct qbuf, rbuf;
380	SAMR_Q_ADD_GROUPMEM q;
381	SAMR_R_ADD_GROUPMEM r;
382	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
383
384	DEBUG(10,("cli_samr_add_groupmem\n"));
385
386	ZERO_STRUCT(q);
387	ZERO_STRUCT(r);
388
389	/* Initialise parse structures */
390
391	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
392	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
393
394	/* Marshall data and send request */
395
396	init_samr_q_add_groupmem(&q, group_pol, rid);
397
398	if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) ||
399	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
400		goto done;
401
402	/* Unmarshall response */
403
404	if (!samr_io_r_add_groupmem("", &r, &rbuf, 0))
405		goto done;
406
407	/* Return output parameters */
408
409	result = r.status;
410
411 done:
412	prs_mem_free(&qbuf);
413	prs_mem_free(&rbuf);
414
415	return result;
416}
417
418/* Delete a domain group member */
419
420NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
421			       POLICY_HND *group_pol, uint32 rid)
422{
423	prs_struct qbuf, rbuf;
424	SAMR_Q_DEL_GROUPMEM q;
425	SAMR_R_DEL_GROUPMEM r;
426	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
427
428	DEBUG(10,("cli_samr_del_groupmem\n"));
429
430	ZERO_STRUCT(q);
431	ZERO_STRUCT(r);
432
433	/* Initialise parse structures */
434
435	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
436	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
437
438	/* Marshall data and send request */
439
440	init_samr_q_del_groupmem(&q, group_pol, rid);
441
442	if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) ||
443	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
444		goto done;
445
446	/* Unmarshall response */
447
448	if (!samr_io_r_del_groupmem("", &r, &rbuf, 0))
449		goto done;
450
451	/* Return output parameters */
452
453	result = r.status;
454
455 done:
456	prs_mem_free(&qbuf);
457	prs_mem_free(&rbuf);
458
459	return result;
460}
461
462/* Query user info */
463
464NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
465                                 POLICY_HND *user_pol, uint16 switch_value,
466                                 SAM_USERINFO_CTR **ctr)
467{
468	prs_struct qbuf, rbuf;
469	SAMR_Q_QUERY_USERINFO q;
470	SAMR_R_QUERY_USERINFO r;
471	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
472
473	DEBUG(10,("cli_samr_query_userinfo\n"));
474
475	ZERO_STRUCT(q);
476	ZERO_STRUCT(r);
477
478	/* Initialise parse structures */
479
480	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
481	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
482
483	/* Marshall data and send request */
484
485	init_samr_q_query_userinfo(&q, user_pol, switch_value);
486
487	if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
488	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
489		goto done;
490
491	/* Unmarshall response */
492
493	if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
494		goto done;
495
496	/* Return output parameters */
497
498	result = r.status;
499	*ctr = r.ctr;
500
501 done:
502	prs_mem_free(&qbuf);
503	prs_mem_free(&rbuf);
504
505	return result;
506}
507
508/* Set group info */
509
510NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
511				POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
512{
513	prs_struct qbuf, rbuf;
514	SAMR_Q_SET_GROUPINFO q;
515	SAMR_R_SET_GROUPINFO r;
516	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
517
518	DEBUG(10,("cli_samr_set_groupinfo\n"));
519
520	ZERO_STRUCT(q);
521	ZERO_STRUCT(r);
522
523	/* Initialise parse structures */
524
525	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
526	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
527
528	/* Marshall data and send request */
529
530	init_samr_q_set_groupinfo(&q, group_pol, ctr);
531
532	if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) ||
533	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
534		goto done;
535
536	/* Unmarshall response */
537
538	if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0))
539		goto done;
540
541	/* Return output parameters */
542
543	result = r.status;
544
545 done:
546	prs_mem_free(&qbuf);
547	prs_mem_free(&rbuf);
548
549	return result;
550}
551
552/* Query group info */
553
554NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
555                                  POLICY_HND *group_pol, uint32 info_level,
556                                  GROUP_INFO_CTR **ctr)
557{
558	prs_struct qbuf, rbuf;
559	SAMR_Q_QUERY_GROUPINFO q;
560	SAMR_R_QUERY_GROUPINFO r;
561	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
562
563	DEBUG(10,("cli_samr_query_groupinfo\n"));
564
565	ZERO_STRUCT(q);
566	ZERO_STRUCT(r);
567
568	/* Initialise parse structures */
569
570	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
571	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
572
573	/* Marshall data and send request */
574
575	init_samr_q_query_groupinfo(&q, group_pol, info_level);
576
577	if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
578	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
579		goto done;
580
581	/* Unmarshall response */
582
583	if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
584		goto done;
585
586	*ctr = r.ctr;
587
588	/* Return output parameters */
589
590	result = r.status;
591
592 done:
593	prs_mem_free(&qbuf);
594	prs_mem_free(&rbuf);
595
596	return result;
597}
598
599/* Query user groups */
600
601NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
602                                   POLICY_HND *user_pol, uint32 *num_groups,
603                                   DOM_GID **gid)
604{
605	prs_struct qbuf, rbuf;
606	SAMR_Q_QUERY_USERGROUPS q;
607	SAMR_R_QUERY_USERGROUPS r;
608	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
609
610	DEBUG(10,("cli_samr_query_usergroups\n"));
611
612	ZERO_STRUCT(q);
613	ZERO_STRUCT(r);
614
615	/* Initialise parse structures */
616
617	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
618	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
619
620	/* Marshall data and send request */
621
622	init_samr_q_query_usergroups(&q, user_pol);
623
624	if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
625	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
626		goto done;
627
628	/* Unmarshall response */
629
630	if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
631		goto done;
632
633	/* Return output parameters */
634
635	if (NT_STATUS_IS_OK(result = r.status)) {
636		*num_groups = r.num_entries;
637		*gid = r.gid;
638	}
639
640 done:
641	prs_mem_free(&qbuf);
642	prs_mem_free(&rbuf);
643
644	return result;
645}
646
647/* Set alias info */
648
649NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
650				POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
651{
652	prs_struct qbuf, rbuf;
653	SAMR_Q_SET_ALIASINFO q;
654	SAMR_R_SET_ALIASINFO r;
655	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
656
657	DEBUG(10,("cli_samr_set_aliasinfo\n"));
658
659	ZERO_STRUCT(q);
660	ZERO_STRUCT(r);
661
662	/* Initialise parse structures */
663
664	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
665	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
666
667	/* Marshall data and send request */
668
669	init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
670
671	if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) ||
672	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
673		goto done;
674
675	/* Unmarshall response */
676
677	if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0))
678		goto done;
679
680	/* Return output parameters */
681
682	result = r.status;
683
684 done:
685	prs_mem_free(&qbuf);
686	prs_mem_free(&rbuf);
687
688	return result;
689}
690
691/* Query user aliases */
692
693NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
694                                   POLICY_HND *dom_pol, uint32 num_sids, DOM_SID2 *sid,
695				   uint32 *num_aliases, uint32 **als_rids)
696{
697	prs_struct qbuf, rbuf;
698	SAMR_Q_QUERY_USERALIASES q;
699	SAMR_R_QUERY_USERALIASES r;
700	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
701	int i;
702	uint32 *sid_ptrs;
703
704	DEBUG(10,("cli_samr_query_useraliases\n"));
705
706	ZERO_STRUCT(q);
707	ZERO_STRUCT(r);
708
709	/* Initialise parse structures */
710
711	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
712	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
713
714	sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
715	if (sid_ptrs == NULL)
716		return NT_STATUS_NO_MEMORY;
717
718	for (i=0; i<num_sids; i++)
719		sid_ptrs[i] = 1;
720
721	/* Marshall data and send request */
722
723	init_samr_q_query_useraliases(&q, dom_pol, num_sids, sid_ptrs, sid);
724
725	if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
726	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
727		goto done;
728
729	/* Unmarshall response */
730
731	if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
732		goto done;
733
734	/* Return output parameters */
735
736	if (NT_STATUS_IS_OK(result = r.status)) {
737		*num_aliases = r.num_entries;
738		*als_rids = r.rid;
739	}
740
741 done:
742	prs_mem_free(&qbuf);
743	prs_mem_free(&rbuf);
744
745	return result;
746}
747
748/* Query user groups */
749
750NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
751                                 POLICY_HND *group_pol, uint32 *num_mem,
752                                 uint32 **rid, uint32 **attr)
753{
754	prs_struct qbuf, rbuf;
755	SAMR_Q_QUERY_GROUPMEM q;
756	SAMR_R_QUERY_GROUPMEM r;
757	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
758
759	DEBUG(10,("cli_samr_query_groupmem\n"));
760
761	ZERO_STRUCT(q);
762	ZERO_STRUCT(r);
763
764	/* Initialise parse structures */
765
766	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
767	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
768
769	/* Marshall data and send request */
770
771	init_samr_q_query_groupmem(&q, group_pol);
772
773	if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
774	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
775		goto done;
776
777	/* Unmarshall response */
778
779	if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
780		goto done;
781
782	/* Return output parameters */
783
784	if (NT_STATUS_IS_OK(result = r.status)) {
785		*num_mem = r.num_entries;
786		*rid = r.rid;
787		*attr = r.attr;
788	}
789
790 done:
791	prs_mem_free(&qbuf);
792	prs_mem_free(&rbuf);
793
794	return result;
795}
796
797/**
798 * Enumerate domain users
799 *
800 * @param cli client state structure
801 * @param mem_ctx talloc context
802 * @param pol opened domain policy handle
803 * @param start_idx starting index of enumeration, returns context for
804                    next enumeration
805 * @param acb_mask account control bit mask (to enumerate some particular
806 *                 kind of accounts)
807 * @param size max acceptable size of response
808 * @param dom_users returned array of domain user names
809 * @param rids returned array of domain user RIDs
810 * @param num_dom_users numer returned entries
811 *
812 * @return NTSTATUS returned in rpc response
813 **/
814NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
815                                 POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
816                                 uint32 size, char ***dom_users, uint32 **rids,
817                                 uint32 *num_dom_users)
818{
819	prs_struct qbuf;
820	prs_struct rbuf;
821	SAMR_Q_ENUM_DOM_USERS q;
822	SAMR_R_ENUM_DOM_USERS r;
823	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
824	int i;
825
826	DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
827
828	ZERO_STRUCT(q);
829	ZERO_STRUCT(r);
830
831	/* always init this */
832	*num_dom_users = 0;
833
834	/* Initialise parse structures */
835
836	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
837	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
838
839	/* Fill query structure with parameters */
840
841	init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
842
843	if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
844	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
845		goto done;
846	}
847
848	/* unpack received stream */
849
850	if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
851		goto done;
852
853	result = r.status;
854
855	if (!NT_STATUS_IS_OK(result) &&
856	    NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
857		goto done;
858
859	*start_idx = r.next_idx;
860	*num_dom_users = r.num_entries2;
861
862	if (r.num_entries2) {
863		/* allocate memory needed to return received data */
864		*rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_entries2);
865		if (!*rids) {
866			DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
867			return NT_STATUS_NO_MEMORY;
868		}
869
870		*dom_users = TALLOC_ARRAY(mem_ctx, char*, r.num_entries2);
871		if (!*dom_users) {
872			DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
873			return NT_STATUS_NO_MEMORY;
874		}
875
876		/* fill output buffers with rpc response */
877		for (i = 0; i < r.num_entries2; i++) {
878			fstring conv_buf;
879
880			(*rids)[i] = r.sam[i].rid;
881			unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
882			(*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
883		}
884	}
885
886done:
887	prs_mem_free(&qbuf);
888	prs_mem_free(&rbuf);
889
890	return result;
891}
892
893/* Enumerate domain groups */
894
895NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
896                                  POLICY_HND *pol, uint32 *start_idx,
897                                  uint32 size, struct acct_info **dom_groups,
898                                  uint32 *num_dom_groups)
899{
900	prs_struct qbuf, rbuf;
901	SAMR_Q_ENUM_DOM_GROUPS q;
902	SAMR_R_ENUM_DOM_GROUPS r;
903	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
904	uint32 name_idx, i;
905
906	DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
907
908	ZERO_STRUCT(q);
909	ZERO_STRUCT(r);
910
911	/* Initialise parse structures */
912
913	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
914	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
915
916	/* Marshall data and send request */
917
918	init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
919
920	if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
921	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
922		goto done;
923
924	/* Unmarshall response */
925
926	if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
927		goto done;
928
929	/* Return output parameters */
930
931	result = r.status;
932
933	if (!NT_STATUS_IS_OK(result) &&
934	    NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
935		goto done;
936
937	*num_dom_groups = r.num_entries2;
938
939	if (*num_dom_groups == 0)
940		goto done;
941
942	if (!((*dom_groups) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_groups))) {
943		result = NT_STATUS_NO_MEMORY;
944		goto done;
945	}
946
947	memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
948
949	name_idx = 0;
950
951	for (i = 0; i < *num_dom_groups; i++) {
952
953		(*dom_groups)[i].rid = r.sam[i].rid;
954
955		if (r.sam[i].hdr_name.buffer) {
956			unistr2_to_ascii((*dom_groups)[i].acct_name,
957					 &r.uni_grp_name[name_idx],
958					 sizeof(fstring) - 1);
959			name_idx++;
960		}
961
962		*start_idx = r.next_idx;
963	}
964
965 done:
966	prs_mem_free(&qbuf);
967	prs_mem_free(&rbuf);
968
969	return result;
970}
971
972/* Enumerate domain groups */
973
974NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
975                                  POLICY_HND *pol, uint32 *start_idx,
976                                  uint32 size, struct acct_info **dom_aliases,
977                                  uint32 *num_dom_aliases)
978{
979	prs_struct qbuf, rbuf;
980	SAMR_Q_ENUM_DOM_ALIASES q;
981	SAMR_R_ENUM_DOM_ALIASES r;
982	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
983	uint32 name_idx, i;
984
985	DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
986
987	ZERO_STRUCT(q);
988	ZERO_STRUCT(r);
989
990	/* Initialise parse structures */
991
992	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
993	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
994
995	/* Marshall data and send request */
996
997	init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
998
999	if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
1000	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
1001		goto done;
1002	}
1003
1004	/* Unmarshall response */
1005
1006	if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
1007		goto done;
1008	}
1009
1010	/* Return output parameters */
1011
1012	result = r.status;
1013
1014	if (!NT_STATUS_IS_OK(result) &&
1015	    NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1016		goto done;
1017	}
1018
1019	*num_dom_aliases = r.num_entries2;
1020
1021	if (*num_dom_aliases == 0)
1022		goto done;
1023
1024	if (!((*dom_aliases) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_aliases))) {
1025		result = NT_STATUS_NO_MEMORY;
1026		goto done;
1027	}
1028
1029	memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
1030
1031	name_idx = 0;
1032
1033	for (i = 0; i < *num_dom_aliases; i++) {
1034
1035		(*dom_aliases)[i].rid = r.sam[i].rid;
1036
1037		if (r.sam[i].hdr_name.buffer) {
1038			unistr2_to_ascii((*dom_aliases)[i].acct_name,
1039					 &r.uni_grp_name[name_idx],
1040					 sizeof(fstring) - 1);
1041			name_idx++;
1042		}
1043
1044		*start_idx = r.next_idx;
1045	}
1046
1047 done:
1048	prs_mem_free(&qbuf);
1049	prs_mem_free(&rbuf);
1050
1051	return result;
1052}
1053
1054/* Query alias members */
1055
1056NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1057                                 POLICY_HND *alias_pol, uint32 *num_mem,
1058                                 DOM_SID **sids)
1059{
1060	prs_struct qbuf, rbuf;
1061	SAMR_Q_QUERY_ALIASMEM q;
1062	SAMR_R_QUERY_ALIASMEM r;
1063	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1064	uint32 i;
1065
1066	DEBUG(10,("cli_samr_query_aliasmem\n"));
1067
1068	ZERO_STRUCT(q);
1069	ZERO_STRUCT(r);
1070
1071	/* Initialise parse structures */
1072
1073	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1074	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1075
1076	/* Marshall data and send request */
1077
1078	init_samr_q_query_aliasmem(&q, alias_pol);
1079
1080	if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
1081	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
1082		goto done;
1083	}
1084
1085	/* Unmarshall response */
1086
1087	if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
1088		goto done;
1089	}
1090
1091	/* Return output parameters */
1092
1093	if (!NT_STATUS_IS_OK(result = r.status)) {
1094		goto done;
1095	}
1096
1097	*num_mem = r.num_sids;
1098
1099	if (*num_mem == 0) {
1100		*sids = NULL;
1101		result = NT_STATUS_OK;
1102		goto done;
1103	}
1104
1105	if (!(*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_mem))) {
1106		result = NT_STATUS_UNSUCCESSFUL;
1107		goto done;
1108	}
1109
1110	for (i = 0; i < *num_mem; i++) {
1111		(*sids)[i] = r.sid[i].sid;
1112	}
1113
1114 done:
1115	prs_mem_free(&qbuf);
1116	prs_mem_free(&rbuf);
1117
1118	return result;
1119}
1120
1121/* Open handle on an alias */
1122
1123NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1124                             POLICY_HND *domain_pol, uint32 access_mask,
1125                             uint32 alias_rid, POLICY_HND *alias_pol)
1126{
1127	prs_struct qbuf, rbuf;
1128	SAMR_Q_OPEN_ALIAS q;
1129	SAMR_R_OPEN_ALIAS r;
1130	NTSTATUS result;
1131
1132	DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
1133
1134	ZERO_STRUCT(q);
1135	ZERO_STRUCT(r);
1136
1137	/* Initialise parse structures */
1138
1139	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1140	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1141
1142	/* Marshall data and send request */
1143
1144	init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
1145
1146	if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
1147	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
1148		result = NT_STATUS_UNSUCCESSFUL;
1149		goto done;
1150	}
1151
1152	/* Unmarshall response */
1153
1154	if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
1155		result = NT_STATUS_UNSUCCESSFUL;
1156		goto done;
1157	}
1158
1159	/* Return output parameters */
1160
1161	if (NT_STATUS_IS_OK(result = r.status)) {
1162		*alias_pol = r.pol;
1163#ifdef __INSURE__
1164		alias_pol->marker = malloc(1);
1165#endif
1166	}
1167
1168 done:
1169	prs_mem_free(&qbuf);
1170	prs_mem_free(&rbuf);
1171
1172	return result;
1173}
1174
1175/* Create an alias */
1176
1177NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1178				   POLICY_HND *domain_pol, const char *name,
1179				   POLICY_HND *alias_pol)
1180{
1181	prs_struct qbuf, rbuf;
1182	SAMR_Q_CREATE_DOM_ALIAS q;
1183	SAMR_R_CREATE_DOM_ALIAS r;
1184	NTSTATUS result;
1185
1186	DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
1187
1188	ZERO_STRUCT(q);
1189	ZERO_STRUCT(r);
1190
1191	/* Initialise parse structures */
1192
1193	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1194	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1195
1196	/* Marshall data and send request */
1197
1198	init_samr_q_create_dom_alias(&q, domain_pol, name);
1199
1200	if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
1201	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
1202		result = NT_STATUS_UNSUCCESSFUL;
1203		goto done;
1204	}
1205
1206	/* Unmarshall response */
1207
1208	if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
1209		result = NT_STATUS_UNSUCCESSFUL;
1210		goto done;
1211	}
1212
1213	/* Return output parameters */
1214
1215	if (NT_STATUS_IS_OK(result = r.status)) {
1216		*alias_pol = r.alias_pol;
1217	}
1218
1219 done:
1220	prs_mem_free(&qbuf);
1221	prs_mem_free(&rbuf);
1222
1223	return result;
1224}
1225
1226/* Add an alias member */
1227
1228NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1229			       POLICY_HND *alias_pol, DOM_SID *member)
1230{
1231	prs_struct qbuf, rbuf;
1232	SAMR_Q_ADD_ALIASMEM q;
1233	SAMR_R_ADD_ALIASMEM r;
1234	NTSTATUS result;
1235
1236	DEBUG(10,("cli_samr_add_aliasmem"));
1237
1238	ZERO_STRUCT(q);
1239	ZERO_STRUCT(r);
1240
1241	/* Initialise parse structures */
1242
1243	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1244	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1245
1246	/* Marshall data and send request */
1247
1248	init_samr_q_add_aliasmem(&q, alias_pol, member);
1249
1250	if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
1251	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
1252		result = NT_STATUS_UNSUCCESSFUL;
1253		goto done;
1254	}
1255
1256	/* Unmarshall response */
1257
1258	if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
1259		result = NT_STATUS_UNSUCCESSFUL;
1260		goto done;
1261	}
1262
1263	result = r.status;
1264
1265 done:
1266	prs_mem_free(&qbuf);
1267	prs_mem_free(&rbuf);
1268
1269	return result;
1270}
1271
1272/* Delete an alias member */
1273
1274NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1275			       POLICY_HND *alias_pol, DOM_SID *member)
1276{
1277	prs_struct qbuf, rbuf;
1278 	SAMR_Q_DEL_ALIASMEM q;
1279 	SAMR_R_DEL_ALIASMEM r;
1280 	NTSTATUS result;
1281
1282 	DEBUG(10,("cli_samr_del_aliasmem"));
1283
1284 	ZERO_STRUCT(q);
1285 	ZERO_STRUCT(r);
1286
1287 	/* Initialise parse structures */
1288
1289 	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1290 	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1291
1292 	/* Marshall data and send request */
1293
1294 	init_samr_q_del_aliasmem(&q, alias_pol, member);
1295
1296	if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
1297	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
1298		result = NT_STATUS_UNSUCCESSFUL;
1299		goto done;
1300	}
1301
1302	/* Unmarshall response */
1303
1304	if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
1305		result = NT_STATUS_UNSUCCESSFUL;
1306		goto done;
1307	}
1308
1309	result = r.status;
1310
1311 done:
1312	prs_mem_free(&qbuf);
1313	prs_mem_free(&rbuf);
1314
1315	return result;
1316}
1317
1318/* Query alias info */
1319
1320NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1321				   POLICY_HND *alias_pol, uint16 switch_value,
1322				   ALIAS_INFO_CTR *ctr)
1323{
1324	prs_struct qbuf, rbuf;
1325	SAMR_Q_QUERY_ALIASINFO q;
1326	SAMR_R_QUERY_ALIASINFO r;
1327	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1328
1329	DEBUG(10,("cli_samr_query_dom_info\n"));
1330
1331	ZERO_STRUCT(q);
1332	ZERO_STRUCT(r);
1333
1334	/* Initialise parse structures */
1335
1336	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1337	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1338
1339	/* Marshall data and send request */
1340
1341	init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
1342
1343	if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
1344	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
1345		goto done;
1346	}
1347
1348	/* Unmarshall response */
1349
1350	if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
1351		goto done;
1352	}
1353
1354	/* Return output parameters */
1355
1356	if (!NT_STATUS_IS_OK(result = r.status)) {
1357		goto done;
1358	}
1359
1360	*ctr = r.ctr;
1361
1362 done:
1363	prs_mem_free(&qbuf);
1364	prs_mem_free(&rbuf);
1365
1366	return result;
1367}
1368
1369/* Query domain info */
1370
1371NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1372                                 POLICY_HND *domain_pol, uint16 switch_value,
1373                                 SAM_UNK_CTR *ctr)
1374{
1375	prs_struct qbuf, rbuf;
1376	SAMR_Q_QUERY_DOMAIN_INFO q;
1377	SAMR_R_QUERY_DOMAIN_INFO r;
1378	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1379
1380	DEBUG(10,("cli_samr_query_dom_info\n"));
1381
1382	ZERO_STRUCT(q);
1383	ZERO_STRUCT(r);
1384
1385	/* Initialise parse structures */
1386
1387	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1388	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1389
1390	/* Marshall data and send request */
1391
1392	init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1393
1394	if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1395	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1396		goto done;
1397	}
1398
1399	/* Unmarshall response */
1400
1401	r.ctr = ctr;
1402
1403	if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1404		goto done;
1405	}
1406
1407	/* Return output parameters */
1408
1409	if (!NT_STATUS_IS_OK(result = r.status)) {
1410		goto done;
1411	}
1412
1413 done:
1414	prs_mem_free(&qbuf);
1415	prs_mem_free(&rbuf);
1416
1417	return result;
1418}
1419
1420/* User change password */
1421
1422NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1423				 const char *username,
1424				 const char *newpassword,
1425				 const char *oldpassword )
1426{
1427	prs_struct qbuf, rbuf;
1428	SAMR_Q_CHGPASSWD_USER q;
1429	SAMR_R_CHGPASSWD_USER r;
1430	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1431
1432	uchar new_nt_password[516];
1433	uchar new_lm_password[516];
1434	uchar old_nt_hash[16];
1435	uchar old_lanman_hash[16];
1436	uchar old_nt_hash_enc[16];
1437	uchar old_lanman_hash_enc[16];
1438
1439	uchar new_nt_hash[16];
1440	uchar new_lanman_hash[16];
1441
1442	DEBUG(10,("cli_samr_query_dom_info\n"));
1443
1444	ZERO_STRUCT(q);
1445	ZERO_STRUCT(r);
1446
1447	/* Calculate the MD4 hash (NT compatible) of the password */
1448	E_md4hash(oldpassword, old_nt_hash);
1449	E_md4hash(newpassword, new_nt_hash);
1450
1451	if (lp_client_lanman_auth()
1452	    && E_deshash(newpassword, new_lanman_hash)
1453	    && E_deshash(oldpassword, old_lanman_hash)) {
1454		/* E_deshash returns false for 'long' passwords (> 14
1455		   DOS chars).  This allows us to match Win2k, which
1456		   does not store a LM hash for these passwords (which
1457		   would reduce the effective password length to 14) */
1458
1459		encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1460
1461		SamOEMhash( new_lm_password, old_nt_hash, 516);
1462		E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1463	} else {
1464		ZERO_STRUCT(new_lm_password);
1465		ZERO_STRUCT(old_lanman_hash_enc);
1466	}
1467
1468	encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1469
1470	SamOEMhash( new_nt_password, old_nt_hash, 516);
1471	E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1472
1473	/* Initialise parse structures */
1474
1475	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1476	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1477
1478	/* Marshall data and send request */
1479
1480	init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username,
1481				   new_nt_password,
1482				   old_nt_hash_enc,
1483				   new_lm_password,
1484				   old_lanman_hash_enc);
1485
1486	if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1487	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1488		goto done;
1489	}
1490
1491	/* Unmarshall response */
1492
1493	if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1494		goto done;
1495	}
1496
1497	/* Return output parameters */
1498
1499	if (!NT_STATUS_IS_OK(result = r.status)) {
1500		goto done;
1501	}
1502
1503 done:
1504	prs_mem_free(&qbuf);
1505	prs_mem_free(&rbuf);
1506
1507	return result;
1508}
1509
1510/* This function returns the bizzare set of (max_entries, max_size) required
1511   for the QueryDisplayInfo RPC to actually work against a domain controller
1512   with large (10k and higher) numbers of users.  These values were
1513   obtained by inspection using ethereal and NT4 running User Manager. */
1514
1515void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1516			       uint32 *max_size)
1517{
1518	switch(loop_count) {
1519	case 0:
1520		*max_entries = 512;
1521		*max_size = 16383;
1522		break;
1523	case 1:
1524		*max_entries = 1024;
1525		*max_size = 32766;
1526		break;
1527	case 2:
1528		*max_entries = 2048;
1529		*max_size = 65532;
1530		break;
1531	case 3:
1532		*max_entries = 4096;
1533		*max_size = 131064;
1534		break;
1535	default:              /* loop_count >= 4 */
1536		*max_entries = 4096;
1537		*max_size = 131071;
1538		break;
1539	}
1540}
1541
1542/* Query display info */
1543
1544NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1545                                 POLICY_HND *domain_pol, uint32 *start_idx,
1546                                 uint16 switch_value, uint32 *num_entries,
1547                                 uint32 max_entries, uint32 max_size,
1548				 SAM_DISPINFO_CTR *ctr)
1549{
1550	prs_struct qbuf, rbuf;
1551	SAMR_Q_QUERY_DISPINFO q;
1552	SAMR_R_QUERY_DISPINFO r;
1553	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1554
1555	DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1556
1557	ZERO_STRUCT(q);
1558	ZERO_STRUCT(r);
1559
1560	*num_entries = 0;
1561
1562	/* Initialise parse structures */
1563
1564	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1565	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1566
1567	/* Marshall data and send request */
1568
1569	init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1570				   *start_idx, max_entries, max_size);
1571
1572	if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1573	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1574		goto done;
1575	}
1576
1577	/* Unmarshall response */
1578
1579	r.ctr = ctr;
1580
1581	if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1582		goto done;
1583	}
1584
1585	/* Return output parameters */
1586
1587        result = r.status;
1588
1589	if (!NT_STATUS_IS_OK(result) &&
1590	    NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1591		goto done;
1592	}
1593
1594	*num_entries = r.num_entries;
1595	*start_idx += r.num_entries;  /* No next_idx in this structure! */
1596
1597 done:
1598	prs_mem_free(&qbuf);
1599	prs_mem_free(&rbuf);
1600
1601	return result;
1602}
1603
1604/* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
1605   looked up in one packet. */
1606
1607NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1608                              POLICY_HND *domain_pol,
1609                              uint32 num_rids, uint32 *rids,
1610                              uint32 *num_names, char ***names,
1611                              uint32 **name_types)
1612{
1613	prs_struct qbuf, rbuf;
1614	SAMR_Q_LOOKUP_RIDS q;
1615	SAMR_R_LOOKUP_RIDS r;
1616	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1617	uint32 i;
1618
1619	DEBUG(10,("cli_samr_lookup_rids\n"));
1620
1621        if (num_rids > 1000) {
1622                DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1623                          "more than ~1000 rids are looked up at once.\n"));
1624        }
1625
1626	ZERO_STRUCT(q);
1627	ZERO_STRUCT(r);
1628
1629	/* Initialise parse structures */
1630
1631	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1632	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1633
1634	/* Marshall data and send request */
1635
1636	init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, 1000, num_rids, rids);
1637
1638	if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1639	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1640		goto done;
1641	}
1642
1643	/* Unmarshall response */
1644
1645	if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1646		goto done;
1647	}
1648
1649	/* Return output parameters */
1650
1651	result = r.status;
1652
1653	if (!NT_STATUS_IS_OK(result) &&
1654	    !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1655		goto done;
1656
1657	if (r.num_names1 == 0) {
1658		*num_names = 0;
1659		*names = NULL;
1660		goto done;
1661	}
1662
1663	*num_names = r.num_names1;
1664	*names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1);
1665	*name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1);
1666
1667	for (i = 0; i < r.num_names1; i++) {
1668		fstring tmp;
1669
1670		unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1671		(*names)[i] = talloc_strdup(mem_ctx, tmp);
1672		(*name_types)[i] = r.type[i];
1673	}
1674
1675 done:
1676	prs_mem_free(&qbuf);
1677	prs_mem_free(&rbuf);
1678
1679	return result;
1680}
1681
1682/* Lookup names */
1683
1684NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1685                               POLICY_HND *domain_pol, uint32 flags,
1686                               uint32 num_names, const char **names,
1687                               uint32 *num_rids, uint32 **rids,
1688                               uint32 **rid_types)
1689{
1690	prs_struct qbuf, rbuf;
1691	SAMR_Q_LOOKUP_NAMES q;
1692	SAMR_R_LOOKUP_NAMES r;
1693	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1694	uint32 i;
1695
1696	DEBUG(10,("cli_samr_lookup_names\n"));
1697
1698	ZERO_STRUCT(q);
1699	ZERO_STRUCT(r);
1700
1701	/* Initialise parse structures */
1702
1703	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1704	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1705
1706	/* Marshall data and send request */
1707
1708	init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1709				 num_names, names);
1710
1711	if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1712	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1713		goto done;
1714	}
1715
1716	/* Unmarshall response */
1717
1718	if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1719		goto done;
1720	}
1721
1722	/* Return output parameters */
1723
1724	if (!NT_STATUS_IS_OK(result = r.status)) {
1725		goto done;
1726	}
1727
1728	if (r.num_rids1 == 0) {
1729		*num_rids = 0;
1730		goto done;
1731	}
1732
1733	*num_rids = r.num_rids1;
1734	*rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1735	*rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1736
1737	for (i = 0; i < r.num_rids1; i++) {
1738		(*rids)[i] = r.rids[i];
1739		(*rid_types)[i] = r.types[i];
1740	}
1741
1742 done:
1743	prs_mem_free(&qbuf);
1744	prs_mem_free(&rbuf);
1745
1746	return result;
1747}
1748
1749/* Create a domain user */
1750
1751NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1752                                  POLICY_HND *domain_pol, const char *acct_name,
1753                                  uint32 acb_info, uint32 unknown,
1754                                  POLICY_HND *user_pol, uint32 *rid)
1755{
1756	prs_struct qbuf, rbuf;
1757	SAMR_Q_CREATE_USER q;
1758	SAMR_R_CREATE_USER r;
1759	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1760
1761	DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1762
1763	ZERO_STRUCT(q);
1764	ZERO_STRUCT(r);
1765
1766	/* Initialise parse structures */
1767
1768	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1769	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1770
1771	/* Marshall data and send request */
1772
1773	init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1774
1775	if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1776	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1777		goto done;
1778	}
1779
1780	/* Unmarshall response */
1781
1782	if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1783		goto done;
1784	}
1785
1786	/* Return output parameters */
1787
1788	if (!NT_STATUS_IS_OK(result = r.status)) {
1789		goto done;
1790	}
1791
1792	if (user_pol)
1793		*user_pol = r.user_pol;
1794
1795	if (rid)
1796		*rid = r.user_rid;
1797
1798 done:
1799	prs_mem_free(&qbuf);
1800	prs_mem_free(&rbuf);
1801
1802	return result;
1803}
1804
1805/* Set userinfo */
1806
1807NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1808                               POLICY_HND *user_pol, uint16 switch_value,
1809                               DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1810{
1811	prs_struct qbuf, rbuf;
1812	SAMR_Q_SET_USERINFO q;
1813	SAMR_R_SET_USERINFO r;
1814	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1815
1816	DEBUG(10,("cli_samr_set_userinfo\n"));
1817
1818	ZERO_STRUCT(q);
1819	ZERO_STRUCT(r);
1820
1821	if (!sess_key->length) {
1822		DEBUG(1, ("No user session key\n"));
1823		return NT_STATUS_NO_USER_SESSION_KEY;
1824	}
1825
1826	/* Initialise parse structures */
1827
1828	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1829	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1830
1831	/* Marshall data and send request */
1832
1833	q.ctr = ctr;
1834
1835	init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
1836				 ctr->info.id);
1837
1838	if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1839	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1840		goto done;
1841	}
1842
1843	/* Unmarshall response */
1844
1845	if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1846		goto done;
1847	}
1848
1849	/* Return output parameters */
1850
1851	if (!NT_STATUS_IS_OK(result = r.status)) {
1852		goto done;
1853	}
1854
1855 done:
1856	prs_mem_free(&qbuf);
1857	prs_mem_free(&rbuf);
1858
1859	return result;
1860}
1861
1862/* Set userinfo2 */
1863
1864NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1865                                POLICY_HND *user_pol, uint16 switch_value,
1866                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1867{
1868	prs_struct qbuf, rbuf;
1869	SAMR_Q_SET_USERINFO2 q;
1870	SAMR_R_SET_USERINFO2 r;
1871	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1872
1873	DEBUG(10,("cli_samr_set_userinfo2\n"));
1874
1875	if (!sess_key->length) {
1876		DEBUG(1, ("No user session key\n"));
1877		return NT_STATUS_NO_USER_SESSION_KEY;
1878	}
1879
1880	ZERO_STRUCT(q);
1881	ZERO_STRUCT(r);
1882
1883	/* Initialise parse structures */
1884
1885	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1886	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1887
1888	/* Marshall data and send request */
1889
1890	init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1891
1892	if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1893	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1894		goto done;
1895	}
1896
1897	/* Unmarshall response */
1898
1899	if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1900		goto done;
1901	}
1902
1903	/* Return output parameters */
1904
1905	if (!NT_STATUS_IS_OK(result = r.status)) {
1906		goto done;
1907	}
1908
1909 done:
1910	prs_mem_free(&qbuf);
1911	prs_mem_free(&rbuf);
1912
1913	return result;
1914}
1915
1916/* Delete domain group */
1917
1918NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1919                                  POLICY_HND *group_pol)
1920{
1921	prs_struct qbuf, rbuf;
1922	SAMR_Q_DELETE_DOM_GROUP q;
1923	SAMR_R_DELETE_DOM_GROUP r;
1924	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1925
1926	DEBUG(10,("cli_samr_delete_dom_group\n"));
1927
1928	ZERO_STRUCT(q);
1929	ZERO_STRUCT(r);
1930
1931	/* Initialise parse structures */
1932
1933	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1934	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1935
1936	/* Marshall data and send request */
1937
1938	init_samr_q_delete_dom_group(&q, group_pol);
1939
1940	if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
1941	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
1942		goto done;
1943	}
1944
1945	/* Unmarshall response */
1946
1947	if (!samr_io_r_delete_dom_group("", &r, &rbuf, 0)) {
1948		goto done;
1949	}
1950
1951	/* Return output parameters */
1952
1953	result = r.status;
1954
1955 done:
1956	prs_mem_free(&qbuf);
1957	prs_mem_free(&rbuf);
1958
1959	return result;
1960}
1961
1962/* Delete domain alias */
1963
1964NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1965                                  POLICY_HND *alias_pol)
1966{
1967	prs_struct qbuf, rbuf;
1968	SAMR_Q_DELETE_DOM_ALIAS q;
1969	SAMR_R_DELETE_DOM_ALIAS r;
1970	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1971
1972	DEBUG(10,("cli_samr_delete_dom_alias\n"));
1973
1974	ZERO_STRUCT(q);
1975	ZERO_STRUCT(r);
1976
1977	/* Initialise parse structures */
1978
1979	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1980	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1981
1982	/* Marshall data and send request */
1983
1984	init_samr_q_delete_dom_alias(&q, alias_pol);
1985
1986	if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
1987	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
1988		goto done;
1989	}
1990
1991	/* Unmarshall response */
1992
1993	if (!samr_io_r_delete_dom_alias("", &r, &rbuf, 0)) {
1994		goto done;
1995	}
1996
1997	/* Return output parameters */
1998
1999	result = r.status;
2000
2001 done:
2002	prs_mem_free(&qbuf);
2003	prs_mem_free(&rbuf);
2004
2005	return result;
2006}
2007
2008/* Delete domain user */
2009
2010NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2011                                  POLICY_HND *user_pol)
2012{
2013	prs_struct qbuf, rbuf;
2014	SAMR_Q_DELETE_DOM_USER q;
2015	SAMR_R_DELETE_DOM_USER r;
2016	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2017
2018	DEBUG(10,("cli_samr_delete_dom_user\n"));
2019
2020	ZERO_STRUCT(q);
2021	ZERO_STRUCT(r);
2022
2023	/* Initialise parse structures */
2024
2025	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2026	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2027
2028	/* Marshall data and send request */
2029
2030	init_samr_q_delete_dom_user(&q, user_pol);
2031
2032	if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
2033	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
2034		goto done;
2035	}
2036
2037	/* Unmarshall response */
2038
2039	if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
2040		goto done;
2041	}
2042
2043	/* Return output parameters */
2044
2045	result = r.status;
2046
2047 done:
2048	prs_mem_free(&qbuf);
2049	prs_mem_free(&rbuf);
2050
2051	return result;
2052}
2053
2054/* Remove foreign SID */
2055
2056NTSTATUS cli_samr_remove_sid_foreign_domain(struct cli_state *cli,
2057					    TALLOC_CTX *mem_ctx,
2058					    POLICY_HND *user_pol,
2059					    DOM_SID *sid)
2060{
2061	prs_struct qbuf, rbuf;
2062	SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q;
2063	SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r;
2064	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2065
2066	DEBUG(10,("cli_samr_remove_sid_foreign_domain\n"));
2067
2068	ZERO_STRUCT(q);
2069	ZERO_STRUCT(r);
2070
2071	/* Initialise parse structures */
2072
2073	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2074	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2075
2076	/* Marshall data and send request */
2077
2078	init_samr_q_remove_sid_foreign_domain(&q, user_pol, sid);
2079
2080	if (!samr_io_q_remove_sid_foreign_domain("", &q, &qbuf, 0) ||
2081	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN, &qbuf, &rbuf)) {
2082		goto done;
2083	}
2084
2085	/* Unmarshall response */
2086
2087	if (!samr_io_r_remove_sid_foreign_domain("", &r, &rbuf, 0)) {
2088		goto done;
2089	}
2090
2091	/* Return output parameters */
2092
2093	result = r.status;
2094
2095 done:
2096	prs_mem_free(&qbuf);
2097	prs_mem_free(&rbuf);
2098
2099	return result;
2100}
2101
2102/* Query user security object */
2103
2104NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2105                                 POLICY_HND *user_pol, uint16 switch_value,
2106                                 TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
2107{
2108	prs_struct qbuf, rbuf;
2109	SAMR_Q_QUERY_SEC_OBJ q;
2110	SAMR_R_QUERY_SEC_OBJ r;
2111	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2112
2113	DEBUG(10,("cli_samr_query_sec_obj\n"));
2114
2115	ZERO_STRUCT(q);
2116	ZERO_STRUCT(r);
2117
2118	/* Initialise parse structures */
2119
2120	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2121	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2122
2123	/* Marshall data and send request */
2124
2125	init_samr_q_query_sec_obj(&q, user_pol, switch_value);
2126
2127	if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
2128	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
2129		goto done;
2130	}
2131
2132	/* Unmarshall response */
2133
2134	if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
2135		goto done;
2136	}
2137
2138	/* Return output parameters */
2139
2140	result = r.status;
2141	*sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
2142
2143 done:
2144	prs_mem_free(&qbuf);
2145	prs_mem_free(&rbuf);
2146
2147	return result;
2148}
2149
2150/* Get domain password info */
2151
2152NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2153				 uint16 *unk_0, uint16 *unk_1)
2154{
2155	prs_struct qbuf, rbuf;
2156	SAMR_Q_GET_DOM_PWINFO q;
2157	SAMR_R_GET_DOM_PWINFO r;
2158	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2159
2160	DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2161
2162	ZERO_STRUCT(q);
2163	ZERO_STRUCT(r);
2164
2165	/* Initialise parse structures */
2166
2167	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2168	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2169
2170	/* Marshall data and send request */
2171
2172	init_samr_q_get_dom_pwinfo(&q, cli->desthost);
2173
2174	if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
2175	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
2176		goto done;
2177
2178	/* Unmarshall response */
2179
2180	if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
2181		goto done;
2182
2183	/* Return output parameters */
2184
2185	result = r.status;
2186
2187	if (NT_STATUS_IS_OK(result)) {
2188		if (unk_0)
2189			*unk_0 = r.unk_0;
2190		if (unk_1)
2191			*unk_1 = r.unk_1;
2192	}
2193
2194 done:
2195	prs_mem_free(&qbuf);
2196	prs_mem_free(&rbuf);
2197
2198	return result;
2199}
2200
2201/* Lookup Domain Name */
2202
2203NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2204				POLICY_HND *user_pol, char *domain_name,
2205				DOM_SID *sid)
2206{
2207	prs_struct qbuf, rbuf;
2208	SAMR_Q_LOOKUP_DOMAIN q;
2209	SAMR_R_LOOKUP_DOMAIN r;
2210	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2211
2212	DEBUG(10,("cli_samr_lookup_domain\n"));
2213
2214	ZERO_STRUCT(q);
2215	ZERO_STRUCT(r);
2216
2217	/* Initialise parse structures */
2218
2219	prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2220	prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2221
2222	/* Marshall data and send request */
2223
2224	init_samr_q_lookup_domain(&q, user_pol, domain_name);
2225
2226	if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
2227	    !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
2228		goto done;
2229
2230	/* Unmarshall response */
2231
2232	if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
2233		goto done;
2234
2235	/* Return output parameters */
2236
2237	result = r.status;
2238
2239	if (NT_STATUS_IS_OK(result))
2240		sid_copy(sid, &r.dom_sid.sid);
2241
2242 done:
2243	prs_mem_free(&qbuf);
2244	prs_mem_free(&rbuf);
2245
2246	return result;
2247}
2248