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