This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[jra/samba/.git] / source3 / libsmb / cli_samr.c
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    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26
27 /* Opens a SMB connection to the SAMR pipe */
28
29 struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
30                                       struct ntuser_creds *creds)
31 {
32         return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds);
33 }
34
35 /* Connect to SAMR database */
36
37 NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
38                           uint32 access_mask, POLICY_HND *connect_pol)
39 {
40         prs_struct qbuf, rbuf;
41         SAMR_Q_CONNECT q;
42         SAMR_R_CONNECT r;
43         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
44
45         ZERO_STRUCT(q);
46         ZERO_STRUCT(r);
47
48         /* Initialise parse structures */
49
50         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
51         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
52
53         /* Marshall data and send request */
54
55         init_samr_q_connect(&q, cli->desthost, access_mask);
56
57         if (!samr_io_q_connect("", &q, &qbuf, 0) ||
58             !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) {
59                 goto done;
60         }
61
62         /* Unmarshall response */
63
64         if (!samr_io_r_connect("", &r, &rbuf, 0)) {
65                 goto done;
66         }
67
68         /* Return output parameters */
69
70         if (NT_STATUS_IS_OK(result = r.status)) {
71                 *connect_pol = r.connect_pol;
72 #ifdef __INSURE__
73                 connect_pol->marker = malloc(1);
74 #endif
75         }
76
77  done:
78         prs_mem_free(&qbuf);
79         prs_mem_free(&rbuf);
80
81         return result;
82 }
83
84 /* Close SAMR handle */
85
86 NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
87                         POLICY_HND *connect_pol)
88 {
89         prs_struct qbuf, rbuf;
90         SAMR_Q_CLOSE_HND q;
91         SAMR_R_CLOSE_HND r;
92         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
93
94         ZERO_STRUCT(q);
95         ZERO_STRUCT(r);
96
97         /* Initialise parse structures */
98
99         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
100         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
101
102         /* Marshall data and send request */
103
104         init_samr_q_close_hnd(&q, connect_pol);
105
106         if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
107             !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) {
108                 goto done;
109         }
110
111         /* Unmarshall response */
112
113         if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) {
114                 goto done;
115         }
116
117         /* Return output parameters */
118
119         if (NT_STATUS_IS_OK(result = r.status)) {
120 #ifdef __INSURE__
121                 SAFE_FREE(connect_pol->marker);
122 #endif
123                 *connect_pol = r.pol;
124         }
125
126  done:
127         prs_mem_free(&qbuf);
128         prs_mem_free(&rbuf);
129
130         return result;
131 }
132
133 /* Open handle on a domain */
134
135 NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
136                               POLICY_HND *connect_pol, uint32 access_mask, 
137                               const DOM_SID *domain_sid, POLICY_HND *domain_pol)
138 {
139         prs_struct qbuf, rbuf;
140         SAMR_Q_OPEN_DOMAIN q;
141         SAMR_R_OPEN_DOMAIN r;
142         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
143
144         ZERO_STRUCT(q);
145         ZERO_STRUCT(r);
146
147         /* Initialise parse structures */
148
149         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
150         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
151
152         /* Marshall data and send request */
153
154         init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
155
156         if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
157             !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) {
158                 goto done;
159         }
160
161         /* Unmarshall response */
162
163         if (!samr_io_r_open_domain("", &r, &rbuf, 0)) {
164                 goto done;
165         }
166
167         /* Return output parameters */
168
169         if (NT_STATUS_IS_OK(result = r.status)) {
170                 *domain_pol = r.domain_pol;
171 #ifdef __INSURE__
172                 domain_pol->marker = malloc(1);
173 #endif
174         }
175
176  done:
177         prs_mem_free(&qbuf);
178         prs_mem_free(&rbuf);
179
180         return result;
181 }
182
183 /* Open handle on a user */
184
185 NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
186                             POLICY_HND *domain_pol, uint32 access_mask, 
187                             uint32 user_rid, POLICY_HND *user_pol)
188 {
189         prs_struct qbuf, rbuf;
190         SAMR_Q_OPEN_USER q;
191         SAMR_R_OPEN_USER r;
192         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
193
194         ZERO_STRUCT(q);
195         ZERO_STRUCT(r);
196
197         /* Initialise parse structures */
198
199         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
200         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
201
202         /* Marshall data and send request */
203
204         init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
205
206         if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
207             !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) {
208                 goto done;
209         }
210
211         /* Unmarshall response */
212
213         if (!samr_io_r_open_user("", &r, &rbuf, 0)) {
214                 goto done;
215         }
216
217         /* Return output parameters */
218
219         if (NT_STATUS_IS_OK(result = r.status)) {
220                 *user_pol = r.user_pol;
221 #ifdef __INSURE__
222                 user_pol->marker = malloc(1);
223 #endif
224         }
225
226  done:
227         prs_mem_free(&qbuf);
228         prs_mem_free(&rbuf);
229
230         return result;
231 }
232
233 /* Open handle on a group */
234
235 NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
236                              POLICY_HND *domain_pol, uint32 access_mask, 
237                              uint32 group_rid, POLICY_HND *group_pol)
238 {
239         prs_struct qbuf, rbuf;
240         SAMR_Q_OPEN_GROUP q;
241         SAMR_R_OPEN_GROUP r;
242         NTSTATUS result =  NT_STATUS_UNSUCCESSFUL;
243
244         ZERO_STRUCT(q);
245         ZERO_STRUCT(r);
246
247         /* Initialise parse structures */
248
249         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
250         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
251
252         /* Marshall data and send request */
253
254         init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
255
256         if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
257             !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) {
258                 goto done;
259         }
260
261         /* Unmarshall response */
262
263         if (!samr_io_r_open_group("", &r, &rbuf, 0)) {
264                 goto done;
265         }
266
267         /* Return output parameters */
268
269         if (NT_STATUS_IS_OK(result = r.status)) {
270                 *group_pol = r.pol;
271 #ifdef __INSURE__
272                 group_pol->marker = malloc(1);
273 #endif
274         }
275
276  done:
277         prs_mem_free(&qbuf);
278         prs_mem_free(&rbuf);
279
280         return result;
281 }
282
283 /* Query user info */
284
285 NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
286                                  POLICY_HND *user_pol, uint16 switch_value, 
287                                  SAM_USERINFO_CTR **ctr)
288 {
289         prs_struct qbuf, rbuf;
290         SAMR_Q_QUERY_USERINFO q;
291         SAMR_R_QUERY_USERINFO r;
292         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
293
294         ZERO_STRUCT(q);
295         ZERO_STRUCT(r);
296
297         /* Initialise parse structures */
298
299         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
300         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
301
302         /* Marshall data and send request */
303
304         init_samr_q_query_userinfo(&q, user_pol, switch_value);
305
306         if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
307             !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) {
308                 goto done;
309         }
310
311         /* Unmarshall response */
312
313         if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) {
314                 goto done;
315         }
316
317         /* Return output parameters */
318
319         result = r.status;
320         *ctr = r.ctr;
321
322  done:
323         prs_mem_free(&qbuf);
324         prs_mem_free(&rbuf);
325
326         return result;
327 }
328
329 /* Query group info */
330
331 NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
332                                   POLICY_HND *group_pol, uint32 info_level, 
333                                   GROUP_INFO_CTR *ctr)
334 {
335         prs_struct qbuf, rbuf;
336         SAMR_Q_QUERY_GROUPINFO q;
337         SAMR_R_QUERY_GROUPINFO r;
338         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
339
340         ZERO_STRUCT(q);
341         ZERO_STRUCT(r);
342
343         /* Initialise parse structures */
344
345         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
346         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
347
348         /* Marshall data and send request */
349
350         init_samr_q_query_groupinfo(&q, group_pol, info_level);
351
352         if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
353             !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) {
354                 goto done;
355         }
356
357         /* Unmarshall response */
358
359         r.ctr = ctr;
360
361         if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) {
362                 goto done;
363         }
364
365         /* Return output parameters */
366
367         result = r.status;
368
369  done:
370         prs_mem_free(&qbuf);
371         prs_mem_free(&rbuf);
372
373         return result;
374 }
375
376 /* Query user groups */
377
378 NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
379                                    POLICY_HND *user_pol, uint32 *num_groups, 
380                                    DOM_GID **gid)
381 {
382         prs_struct qbuf, rbuf;
383         SAMR_Q_QUERY_USERGROUPS q;
384         SAMR_R_QUERY_USERGROUPS r;
385         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
386
387         ZERO_STRUCT(q);
388         ZERO_STRUCT(r);
389
390         /* Initialise parse structures */
391
392         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
393         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
394
395         /* Marshall data and send request */
396
397         init_samr_q_query_usergroups(&q, user_pol);
398
399         if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
400             !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) {
401                 goto done;
402         }
403
404         /* Unmarshall response */
405
406         if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) {
407                 goto done;
408         }
409
410         /* Return output parameters */
411
412         if (NT_STATUS_IS_OK(result = r.status)) {
413                 *num_groups = r.num_entries;
414                 *gid = r.gid;
415         }
416
417  done:
418         prs_mem_free(&qbuf);
419         prs_mem_free(&rbuf);
420
421         return result;
422 }
423
424 /* Query user aliases */
425
426 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
427                                    POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
428                                    uint32 *num_aliases, uint32 **als_rids)
429 {
430         prs_struct qbuf, rbuf;
431         SAMR_Q_QUERY_USERALIASES q;
432         SAMR_R_QUERY_USERALIASES r;
433         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
434         uint ptr=1;
435         
436         ZERO_STRUCT(q);
437         ZERO_STRUCT(r);
438
439         /* Initialise parse structures */
440
441         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
442         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
443
444         /* Marshall data and send request */
445
446         init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
447
448         if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
449             !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) {
450                 goto done;
451         }
452
453         /* Unmarshall response */
454
455         if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) {
456                 goto done;
457         }
458
459         /* Return output parameters */
460
461         if (NT_STATUS_IS_OK(result = r.status)) {
462                 *num_aliases = r.num_entries;
463                 *als_rids = r.rid;
464         }
465
466  done:
467         prs_mem_free(&qbuf);
468         prs_mem_free(&rbuf);
469
470         return result;
471 }
472
473 /* Query user groups */
474
475 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
476                                  POLICY_HND *group_pol, uint32 *num_mem, 
477                                  uint32 **rid, uint32 **attr)
478 {
479         prs_struct qbuf, rbuf;
480         SAMR_Q_QUERY_GROUPMEM q;
481         SAMR_R_QUERY_GROUPMEM r;
482         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
483
484         ZERO_STRUCT(q);
485         ZERO_STRUCT(r);
486
487         /* Initialise parse structures */
488
489         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
490         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
491
492         /* Marshall data and send request */
493
494         init_samr_q_query_groupmem(&q, group_pol);
495
496         if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
497             !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) {
498                 goto done;
499         }
500
501         /* Unmarshall response */
502
503         if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) {
504                 goto done;
505         }
506
507         /* Return output parameters */
508
509         if (NT_STATUS_IS_OK(result = r.status)) {
510                 *num_mem = r.num_entries;
511                 *rid = r.rid;
512                 *attr = r.attr;
513         }
514
515  done:
516         prs_mem_free(&qbuf);
517         prs_mem_free(&rbuf);
518
519         return result;
520 }
521
522 /* Enumerate domain groups */
523
524 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
525                                   POLICY_HND *pol, uint32 *start_idx, 
526                                   uint32 size, struct acct_info **dom_groups,
527                                   uint32 *num_dom_groups)
528 {
529         prs_struct qbuf, rbuf;
530         SAMR_Q_ENUM_DOM_GROUPS q;
531         SAMR_R_ENUM_DOM_GROUPS r;
532         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
533         uint32 name_idx, i;
534
535         ZERO_STRUCT(q);
536         ZERO_STRUCT(r);
537
538         /* Initialise parse structures */
539
540         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
541         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
542
543         /* Marshall data and send request */
544
545         init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
546
547         if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
548             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) {
549                 goto done;
550         }
551
552         /* Unmarshall response */
553
554         if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) {
555                 goto done;
556         }
557
558         /* Return output parameters */
559
560         result = r.status;
561
562         if (!NT_STATUS_IS_OK(result) &&
563             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
564                 goto done;
565         }
566
567         *num_dom_groups = r.num_entries2;
568
569         if (!((*dom_groups) = (struct acct_info *)
570               talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
571                 result = NT_STATUS_UNSUCCESSFUL;
572                 goto done;
573         }
574
575         memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
576
577         name_idx = 0;
578
579         for (i = 0; i < *num_dom_groups; i++) {
580
581                 (*dom_groups)[i].rid = r.sam[i].rid;
582
583                 if (r.sam[i].hdr_name.buffer) {
584                         unistr2_to_ascii((*dom_groups)[i].acct_name,
585                                          &r.uni_grp_name[name_idx],
586                                          sizeof(fstring) - 1);
587                         name_idx++;
588                 }
589
590                 *start_idx = r.next_idx;
591         }
592
593  done:
594         prs_mem_free(&qbuf);
595         prs_mem_free(&rbuf);
596
597         return result;
598 }
599
600 /* Enumerate domain groups */
601
602 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
603                                   POLICY_HND *pol, uint32 *start_idx, 
604                                   uint32 size, struct acct_info **dom_groups,
605                                   uint32 *num_dom_groups)
606 {
607         prs_struct qbuf, rbuf;
608         SAMR_Q_ENUM_DOM_ALIASES q;
609         SAMR_R_ENUM_DOM_ALIASES r;
610         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
611         uint32 name_idx, i;
612
613         ZERO_STRUCT(q);
614         ZERO_STRUCT(r);
615
616         /* Initialise parse structures */
617
618         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
619         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
620
621         /* Marshall data and send request */
622
623         init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
624
625         if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
626             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
627                 goto done;
628         }
629
630         /* Unmarshall response */
631
632         if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
633                 goto done;
634         }
635
636         /* Return output parameters */
637
638         result = r.status;
639
640         if (!NT_STATUS_IS_OK(result) &&
641             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
642                 goto done;
643         }
644
645         *num_dom_groups = r.num_entries2;
646
647         if (!((*dom_groups) = (struct acct_info *)
648               talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
649                 result = NT_STATUS_UNSUCCESSFUL;
650                 goto done;
651         }
652
653         memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups);
654
655         name_idx = 0;
656
657         for (i = 0; i < *num_dom_groups; i++) {
658
659                 (*dom_groups)[i].rid = r.sam[i].rid;
660
661                 if (r.sam[i].hdr_name.buffer) {
662                         unistr2_to_ascii((*dom_groups)[i].acct_name,
663                                          &r.uni_grp_name[name_idx],
664                                          sizeof(fstring) - 1);
665                         name_idx++;
666                 }
667
668                 *start_idx = r.next_idx;
669         }
670
671  done:
672         prs_mem_free(&qbuf);
673         prs_mem_free(&rbuf);
674
675         return result;
676 }
677
678 /* Query alias members */
679
680 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
681                                  POLICY_HND *alias_pol, uint32 *num_mem, 
682                                  DOM_SID **sids)
683 {
684         prs_struct qbuf, rbuf;
685         SAMR_Q_QUERY_ALIASMEM q;
686         SAMR_R_QUERY_ALIASMEM r;
687         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
688         uint32 i;
689
690         ZERO_STRUCT(q);
691         ZERO_STRUCT(r);
692
693         /* Initialise parse structures */
694
695         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
696         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
697
698         /* Marshall data and send request */
699
700         init_samr_q_query_aliasmem(&q, alias_pol);
701
702         if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
703             !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
704                 goto done;
705         }
706
707         /* Unmarshall response */
708
709         if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
710                 goto done;
711         }
712
713         /* Return output parameters */
714
715         if (!NT_STATUS_IS_OK(result = r.status)) {
716                 goto done;
717         }
718
719         *num_mem = r.num_sids;
720
721         if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
722                 result = NT_STATUS_UNSUCCESSFUL;
723                 goto done;
724         }
725
726         for (i = 0; i < *num_mem; i++) {
727                 (*sids)[i] = r.sid[i].sid;
728         }
729
730  done:
731         prs_mem_free(&qbuf);
732         prs_mem_free(&rbuf);
733
734         return result;
735 }
736
737 /* Open handle on an alias */
738
739 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
740                              POLICY_HND *domain_pol, uint32 access_mask, 
741                              uint32 alias_rid, POLICY_HND *alias_pol)
742 {
743         prs_struct qbuf, rbuf;
744         SAMR_Q_OPEN_ALIAS q;
745         SAMR_R_OPEN_ALIAS r;
746         NTSTATUS result;
747
748         ZERO_STRUCT(q);
749         ZERO_STRUCT(r);
750
751         /* Initialise parse structures */
752
753         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
754         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
755
756         /* Marshall data and send request */
757
758         init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
759
760         if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
761             !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
762                 result = NT_STATUS_UNSUCCESSFUL;
763                 goto done;
764         }
765
766         /* Unmarshall response */
767
768         if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
769                 result = NT_STATUS_UNSUCCESSFUL;
770                 goto done;
771         }
772
773         /* Return output parameters */
774
775         if (NT_STATUS_IS_OK(result = r.status)) {
776                 *alias_pol = r.pol;
777 #ifdef __INSURE__
778                 alias_pol->marker = malloc(1);
779 #endif
780         }
781
782  done:
783         prs_mem_free(&qbuf);
784         prs_mem_free(&rbuf);
785
786         return result;
787 }
788
789 /* Query domain info */
790
791 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
792                                  POLICY_HND *domain_pol, uint16 switch_value,
793                                  SAM_UNK_CTR *ctr)
794 {
795         prs_struct qbuf, rbuf;
796         SAMR_Q_QUERY_DOMAIN_INFO q;
797         SAMR_R_QUERY_DOMAIN_INFO r;
798         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
799
800         ZERO_STRUCT(q);
801         ZERO_STRUCT(r);
802
803         /* Initialise parse structures */
804
805         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
806         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
807
808         /* Marshall data and send request */
809
810         init_samr_q_query_dom_info(&q, domain_pol, switch_value);
811
812         if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
813             !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
814                 goto done;
815         }
816
817         /* Unmarshall response */
818
819         r.ctr = ctr;
820
821         if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
822                 goto done;
823         }
824
825         /* Return output parameters */
826
827         if (!NT_STATUS_IS_OK(result = r.status)) {
828                 goto done;
829         }
830
831  done:
832         prs_mem_free(&qbuf);
833         prs_mem_free(&rbuf);
834
835         return result;
836 }
837
838 /* Query display info */
839
840 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
841                                  POLICY_HND *domain_pol, uint32 *start_idx,
842                                  uint16 switch_value, uint32 *num_entries,
843                                  uint32 max_entries, SAM_DISPINFO_CTR *ctr)
844 {
845         prs_struct qbuf, rbuf;
846         SAMR_Q_QUERY_DISPINFO q;
847         SAMR_R_QUERY_DISPINFO r;
848         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
849
850         ZERO_STRUCT(q);
851         ZERO_STRUCT(r);
852
853         /* Initialise parse structures */
854
855         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
856         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
857
858         /* Marshall data and send request */
859
860         init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
861                                    *start_idx, max_entries);
862
863         if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
864             !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
865                 goto done;
866         }
867
868         /* Unmarshall response */
869
870         r.ctr = ctr;
871
872         if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
873                 goto done;
874         }
875
876         /* Return output parameters */
877
878         result = r.status;
879
880         if (!NT_STATUS_IS_OK(result) &&
881             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
882                 goto done;
883         }
884
885         *num_entries = r.num_entries;
886         *start_idx += r.num_entries;  /* No next_idx in this structure! */
887
888  done:
889         prs_mem_free(&qbuf);
890         prs_mem_free(&rbuf);
891
892         return result;
893 }
894
895 /* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
896    looked up in one packet. */
897
898 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
899                               POLICY_HND *domain_pol, uint32 flags,
900                               uint32 num_rids, uint32 *rids, 
901                               uint32 *num_names, char ***names,
902                               uint32 **name_types)
903 {
904         prs_struct qbuf, rbuf;
905         SAMR_Q_LOOKUP_RIDS q;
906         SAMR_R_LOOKUP_RIDS r;
907         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
908         uint32 i;
909
910         if (num_rids > 1000) {
911                 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
912                           "more than ~1000 rids are looked up at once.\n"));
913         }
914
915         ZERO_STRUCT(q);
916         ZERO_STRUCT(r);
917
918         /* Initialise parse structures */
919
920         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
921         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
922
923         /* Marshall data and send request */
924
925         init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
926                                 num_rids, rids);
927
928         if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
929             !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
930                 goto done;
931         }
932
933         /* Unmarshall response */
934
935         if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
936                 goto done;
937         }
938
939         /* Return output parameters */
940
941         if (!NT_STATUS_IS_OK(result = r.status)) {
942                 goto done;
943         }
944
945         if (r.num_names1 == 0) {
946                 *num_names = 0;
947                 *names = NULL;
948                 goto done;
949         }
950
951         *num_names = r.num_names1;
952         *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
953         *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
954
955         for (i = 0; i < r.num_names1; i++) {
956                 fstring tmp;
957
958                 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
959                 (*names)[i] = talloc_strdup(mem_ctx, tmp);
960                 (*name_types)[i] = r.type[i];
961         }
962
963  done:
964         prs_mem_free(&qbuf);
965         prs_mem_free(&rbuf);
966
967         return result;
968 }
969
970 /* Lookup names */
971
972 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
973                                POLICY_HND *domain_pol, uint32 flags,
974                                uint32 num_names, char **names,
975                                uint32 *num_rids, uint32 **rids,
976                                uint32 **rid_types)
977 {
978         prs_struct qbuf, rbuf;
979         SAMR_Q_LOOKUP_NAMES q;
980         SAMR_R_LOOKUP_NAMES r;
981         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
982         uint32 i;
983
984         ZERO_STRUCT(q);
985         ZERO_STRUCT(r);
986
987         /* Initialise parse structures */
988
989         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
990         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
991
992         /* Marshall data and send request */
993
994         init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
995                                  num_names, names);
996
997         if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
998             !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
999                 goto done;
1000         }
1001
1002         /* Unmarshall response */
1003
1004         if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1005                 goto done;
1006         }
1007
1008         /* Return output parameters */
1009
1010         if (!NT_STATUS_IS_OK(result = r.status)) {
1011                 goto done;
1012         }
1013
1014         if (r.num_rids1 == 0) {
1015                 *num_rids = 0;
1016                 goto done;
1017         }
1018
1019         *num_rids = r.num_rids1;
1020         *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1021         *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1022
1023         for (i = 0; i < r.num_rids1; i++) {
1024                 (*rids)[i] = r.rids[i];
1025                 (*rid_types)[i] = r.types[i];
1026         }
1027
1028  done:
1029         prs_mem_free(&qbuf);
1030         prs_mem_free(&rbuf);
1031
1032         return result;
1033 }
1034
1035 /* Create a domain user */
1036
1037 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1038                                   POLICY_HND *domain_pol, const char *acct_name,
1039                                   uint32 acb_info, uint32 unknown, 
1040                                   POLICY_HND *user_pol, uint32 *rid)
1041 {
1042         prs_struct qbuf, rbuf;
1043         SAMR_Q_CREATE_USER q;
1044         SAMR_R_CREATE_USER r;
1045         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1046
1047         ZERO_STRUCT(q);
1048         ZERO_STRUCT(r);
1049
1050         /* Initialise parse structures */
1051
1052         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1053         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1054
1055         /* Marshall data and send request */
1056
1057         init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1058
1059         if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1060             !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1061                 goto done;
1062         }
1063
1064         /* Unmarshall response */
1065
1066         if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1067                 goto done;
1068         }
1069
1070         /* Return output parameters */
1071
1072         if (!NT_STATUS_IS_OK(result = r.status)) {
1073                 goto done;
1074         }
1075
1076         if (user_pol)
1077                 *user_pol = r.user_pol;
1078
1079         if (rid)
1080                 *rid = r.user_rid;
1081
1082  done:
1083         prs_mem_free(&qbuf);
1084         prs_mem_free(&rbuf);
1085
1086         return result;
1087 }
1088
1089 /* Set userinfo */
1090
1091 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1092                                POLICY_HND *user_pol, uint16 switch_value,
1093                                uchar sess_key[16], SAM_USERINFO_CTR *ctr)
1094 {
1095         prs_struct qbuf, rbuf;
1096         SAMR_Q_SET_USERINFO q;
1097         SAMR_R_SET_USERINFO r;
1098         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1099
1100         ZERO_STRUCT(q);
1101         ZERO_STRUCT(r);
1102
1103         /* Initialise parse structures */
1104
1105         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1106         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1107
1108         /* Marshall data and send request */
1109
1110         q.ctr = ctr;
1111
1112         init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, 
1113                                  ctr->info.id);
1114
1115         if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1116             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1117                 goto done;
1118         }
1119
1120         /* Unmarshall response */
1121
1122         if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1123                 goto done;
1124         }
1125
1126         /* Return output parameters */
1127
1128         if (!NT_STATUS_IS_OK(result = r.status)) {
1129                 goto done;
1130         }
1131
1132  done:
1133         prs_mem_free(&qbuf);
1134         prs_mem_free(&rbuf);
1135
1136         return result;
1137 }
1138
1139 /* Set userinfo2 */
1140
1141 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1142                                 POLICY_HND *user_pol, uint16 switch_value,
1143                                 uchar sess_key[16], SAM_USERINFO_CTR *ctr)
1144 {
1145         prs_struct qbuf, rbuf;
1146         SAMR_Q_SET_USERINFO2 q;
1147         SAMR_R_SET_USERINFO2 r;
1148         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1149
1150         ZERO_STRUCT(q);
1151         ZERO_STRUCT(r);
1152
1153         /* Initialise parse structures */
1154
1155         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1156         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1157
1158         /* Marshall data and send request */
1159
1160         init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1161
1162         if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1163             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1164                 goto done;
1165         }
1166
1167         /* Unmarshall response */
1168
1169         if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1170                 goto done;
1171         }
1172
1173         /* Return output parameters */
1174
1175         if (!NT_STATUS_IS_OK(result = r.status)) {
1176                 goto done;
1177         }
1178
1179  done:
1180         prs_mem_free(&qbuf);
1181         prs_mem_free(&rbuf);
1182
1183         return result;
1184 }
1185
1186 /* Delete domain user */
1187
1188 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1189                                   POLICY_HND *user_pol)
1190 {
1191         prs_struct qbuf, rbuf;
1192         SAMR_Q_DELETE_DOM_USER q;
1193         SAMR_R_DELETE_DOM_USER r;
1194         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1195
1196         ZERO_STRUCT(q);
1197         ZERO_STRUCT(r);
1198
1199         /* Initialise parse structures */
1200
1201         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1202         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1203
1204         /* Marshall data and send request */
1205
1206         init_samr_q_delete_dom_user(&q, user_pol);
1207
1208         if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
1209             !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
1210                 goto done;
1211         }
1212
1213         /* Unmarshall response */
1214
1215         if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
1216                 goto done;
1217         }
1218
1219         /* Return output parameters */
1220
1221         result = r.status;
1222
1223  done:
1224         prs_mem_free(&qbuf);
1225         prs_mem_free(&rbuf);
1226
1227         return result;
1228 }
1229
1230 /* Query user security object */
1231
1232 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1233                                  POLICY_HND *user_pol, uint16 switch_value, 
1234                                  TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
1235 {
1236         prs_struct qbuf, rbuf;
1237         SAMR_Q_QUERY_SEC_OBJ q;
1238         SAMR_R_QUERY_SEC_OBJ r;
1239         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1240
1241         ZERO_STRUCT(q);
1242         ZERO_STRUCT(r);
1243
1244         /* Initialise parse structures */
1245
1246         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1247         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1248
1249         /* Marshall data and send request */
1250
1251         init_samr_q_query_sec_obj(&q, user_pol, switch_value);
1252
1253         if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
1254             !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
1255                 goto done;
1256         }
1257
1258         /* Unmarshall response */
1259
1260         if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
1261                 goto done;
1262         }
1263
1264         /* Return output parameters */
1265
1266         result = r.status;
1267         *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
1268
1269  done:
1270         prs_mem_free(&qbuf);
1271         prs_mem_free(&rbuf);
1272
1273         return result;
1274 }