samr: for correctness, rename samr_RidTypeArray to samr_RidAttrArray.
[samba.git] / source3 / winbindd / winbindd_rpc.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * Winbind rpc backend functions
5  *
6  * Copyright (c) 2000-2003 Tim Potter
7  * Copyright (c) 2001      Andrew Tridgell
8  * Copyright (c) 2005      Volker Lendecke
9  * Copyright (c) 2008      Guenther Deschner (pidl conversion)
10  * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
29
30 #include "librpc/gen_ndr/cli_samr.h"
31 #include "librpc/gen_ndr/srv_samr.h"
32 #include "librpc/gen_ndr/cli_lsa.h"
33 #include "librpc/gen_ndr/srv_lsa.h"
34 #include "rpc_client/cli_samr.h"
35 #include "rpc_client/cli_lsarpc.h"
36 #include "../libcli/security/dom_sid.h"
37
38 /* Query display info for a domain */
39 NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx,
40                              struct rpc_pipe_client *samr_pipe,
41                              struct policy_handle *samr_policy,
42                              const struct dom_sid *domain_sid,
43                              uint32_t *pnum_info,
44                              struct wbint_userinfo **pinfo)
45 {
46         struct wbint_userinfo *info = NULL;
47         uint32_t num_info = 0;
48         uint32_t loop_count = 0;
49         uint32_t start_idx = 0;
50         uint32_t i = 0;
51         NTSTATUS status;
52
53         *pnum_info = 0;
54
55         do {
56                 uint32_t j;
57                 uint32_t num_dom_users;
58                 uint32_t max_entries, max_size;
59                 uint32_t total_size, returned_size;
60                 union samr_DispInfo disp_info;
61
62                 get_query_dispinfo_params(loop_count,
63                                           &max_entries,
64                                           &max_size);
65
66                 status = rpccli_samr_QueryDisplayInfo(samr_pipe,
67                                                       mem_ctx,
68                                                       samr_policy,
69                                                       1, /* level */
70                                                       start_idx,
71                                                       max_entries,
72                                                       max_size,
73                                                       &total_size,
74                                                       &returned_size,
75                                                       &disp_info);
76                 if (!NT_STATUS_IS_OK(status)) {
77                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
78                                 return status;
79                         }
80                 }
81
82                 /* increment required start query values */
83                 start_idx += disp_info.info1.count;
84                 loop_count++;
85                 num_dom_users = disp_info.info1.count;
86
87                 num_info += num_dom_users;
88
89                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
90                                             info,
91                                             struct wbint_userinfo,
92                                             num_info);
93                 if (info == NULL) {
94                         return NT_STATUS_NO_MEMORY;
95                 }
96
97                 for (j = 0; j < num_dom_users; i++, j++) {
98                         uint32_t rid = disp_info.info1.entries[j].rid;
99                         struct samr_DispEntryGeneral *src;
100                         struct wbint_userinfo *dst;
101
102                         src = &(disp_info.info1.entries[j]);
103                         dst = &(info[i]);
104
105                         dst->acct_name = talloc_strdup(info,
106                                                        src->account_name.string);
107                         if (dst->acct_name == NULL) {
108                                 return NT_STATUS_NO_MEMORY;
109                         }
110
111                         dst->full_name = talloc_strdup(info, src->full_name.string);
112                         if (dst->full_name == NULL) {
113                                 return NT_STATUS_NO_MEMORY;
114                         }
115
116                         dst->homedir = NULL;
117                         dst->shell = NULL;
118
119                         sid_compose(&dst->user_sid, domain_sid, rid);
120
121                         /* For the moment we set the primary group for
122                            every user to be the Domain Users group.
123                            There are serious problems with determining
124                            the actual primary group for large domains.
125                            This should really be made into a 'winbind
126                            force group' smb.conf parameter or
127                            something like that. */
128                         sid_compose(&dst->group_sid, domain_sid,
129                                     DOMAIN_RID_USERS);
130                 }
131         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
132
133         *pnum_info = num_info;
134         *pinfo = info;
135
136         return NT_STATUS_OK;
137 }
138
139 /* List all domain groups */
140 NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
141                              struct rpc_pipe_client *samr_pipe,
142                              struct policy_handle *samr_policy,
143                              uint32_t *pnum_info,
144                              struct acct_info **pinfo)
145 {
146         struct acct_info *info = NULL;
147         uint32_t start = 0;
148         uint32_t num_info = 0;
149         NTSTATUS status;
150
151         *pnum_info = 0;
152
153         do {
154                 struct samr_SamArray *sam_array = NULL;
155                 uint32_t count = 0;
156                 uint32_t g;
157
158                 /* start is updated by this call. */
159                 status = rpccli_samr_EnumDomainGroups(samr_pipe,
160                                                       mem_ctx,
161                                                       samr_policy,
162                                                       &start,
163                                                       &sam_array,
164                                                       0xFFFF, /* buffer size? */
165                                                       &count);
166                 if (!NT_STATUS_IS_OK(status)) {
167                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
168                                 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
169                                          nt_errstr(status)));
170                                 return status;
171                         }
172                 }
173
174                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
175                                             info,
176                                             struct acct_info,
177                                             num_info + count);
178                 if (info == NULL) {
179                         return NT_STATUS_NO_MEMORY;
180                 }
181
182                 for (g = 0; g < count; g++) {
183                         fstrcpy(info[num_info + g].acct_name,
184                                 sam_array->entries[g].name.string);
185
186                         info[num_info + g].rid = sam_array->entries[g].idx;
187                 }
188
189                 num_info += count;
190         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
191
192         *pnum_info = num_info;
193         *pinfo = info;
194
195         return NT_STATUS_OK;
196 }
197
198 NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
199                                struct rpc_pipe_client *samr_pipe,
200                                struct policy_handle *samr_policy,
201                                uint32_t *pnum_info,
202                                struct acct_info **pinfo)
203 {
204         struct acct_info *info = NULL;
205         uint32_t num_info = 0;
206         NTSTATUS status;
207
208         *pnum_info = 0;
209
210         do {
211                 struct samr_SamArray *sam_array = NULL;
212                 uint32_t count = 0;
213                 uint32_t start = num_info;
214                 uint32_t g;
215
216                 status = rpccli_samr_EnumDomainAliases(samr_pipe,
217                                                        mem_ctx,
218                                                        samr_policy,
219                                                        &start,
220                                                        &sam_array,
221                                                        0xFFFF, /* buffer size? */
222                                                        &count);
223                 if (!NT_STATUS_IS_OK(status)) {
224                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
225                                 return status;
226                         }
227                 }
228
229                 info = TALLOC_REALLOC_ARRAY(mem_ctx,
230                                             info,
231                                             struct acct_info,
232                                             num_info + count);
233                 if (info == NULL) {
234                         return  NT_STATUS_NO_MEMORY;
235                 }
236
237                 for (g = 0; g < count; g++) {
238                         fstrcpy(info[num_info + g].acct_name,
239                                 sam_array->entries[g].name.string);
240                         info[num_info + g].rid = sam_array->entries[g].idx;
241                 }
242
243                 num_info += count;
244         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
245
246         *pnum_info = num_info;
247         *pinfo = info;
248
249         return NT_STATUS_OK;
250 }
251
252 /* convert a single name to a sid in a domain */
253 NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
254                          struct rpc_pipe_client *lsa_pipe,
255                          struct policy_handle *lsa_policy,
256                          const char *domain_name,
257                          const char *name,
258                          uint32_t flags,
259                          struct dom_sid *sid,
260                          enum lsa_SidType *type)
261 {
262         enum lsa_SidType *types = NULL;
263         struct dom_sid *sids = NULL;
264         char *full_name = NULL;
265         char *mapped_name = NULL;
266         NTSTATUS status;
267
268         if (name == NULL || name[0] == '\0') {
269                 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
270         } else if (domain_name == NULL || domain_name[0] == '\0') {
271                 full_name = talloc_asprintf(mem_ctx, "%s", name);
272         } else {
273                 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
274         }
275
276         if (full_name == NULL) {
277                 return NT_STATUS_NO_MEMORY;
278         }
279
280         status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
281         /* Reset the full_name pointer if we mapped anything */
282         if (NT_STATUS_IS_OK(status) ||
283             NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
284                 full_name = mapped_name;
285         }
286
287         DEBUG(3,("name_to_sid: %s for domain %s\n",
288                  full_name ? full_name : "", domain_name ));
289
290         /*
291          * We don't run into deadlocks here, cause winbind_off() is
292          * called in the main function.
293          */
294         status = rpccli_lsa_lookup_names(lsa_pipe,
295                                          mem_ctx,
296                                          lsa_policy,
297                                          1, /* num_names */
298                                          (const char **) &full_name,
299                                          NULL, /* domains */
300                                          1, /* level */
301                                          &sids,
302                                          &types);
303         if (!NT_STATUS_IS_OK(status)) {
304                 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
305                         nt_errstr(status)));
306                 return status;
307         }
308
309         sid_copy(sid, &sids[0]);
310         *type = types[0];
311
312         return NT_STATUS_OK;
313 }
314
315 /* Convert a domain SID to a user or group name */
316 NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx,
317                          struct rpc_pipe_client *lsa_pipe,
318                          struct policy_handle *lsa_policy,
319                          struct winbindd_domain *domain,
320                          const struct dom_sid *sid,
321                          char **pdomain_name,
322                          char **pname,
323                          enum lsa_SidType *ptype)
324 {
325         char *mapped_name = NULL;
326         char **domains = NULL;
327         char **names = NULL;
328         enum lsa_SidType *types = NULL;
329         NTSTATUS map_status;
330         NTSTATUS status;
331
332         status = rpccli_lsa_lookup_sids(lsa_pipe,
333                                         mem_ctx,
334                                         lsa_policy,
335                                         1, /* num_sids */
336                                         sid,
337                                         &domains,
338                                         &names,
339                                         &types);
340         if (!NT_STATUS_IS_OK(status)) {
341                 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
342                         nt_errstr(status)));
343                 return status;
344         }
345
346         *ptype = (enum lsa_SidType) types[0];
347
348         map_status = normalize_name_map(mem_ctx,
349                                         domain,
350                                         *pname,
351                                         &mapped_name);
352         if (NT_STATUS_IS_OK(map_status) ||
353             NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
354                 *pname = talloc_strdup(mem_ctx, mapped_name);
355                 DEBUG(5,("returning mapped name -- %s\n", *pname));
356         } else {
357                 *pname = talloc_strdup(mem_ctx, names[0]);
358         }
359         if (*pname == NULL) {
360                 return NT_STATUS_NO_MEMORY;
361         }
362
363         *pdomain_name = talloc_strdup(mem_ctx, domains[0]);
364         if (*pdomain_name == NULL) {
365                 return NT_STATUS_NO_MEMORY;
366         }
367
368         return NT_STATUS_OK;
369 }
370
371 /* Convert a bunch of rids to user or group names */
372 NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx,
373                            struct rpc_pipe_client *lsa_pipe,
374                            struct policy_handle *lsa_policy,
375                            struct winbindd_domain *domain,
376                            const struct dom_sid *sid,
377                            uint32_t *rids,
378                            size_t num_rids,
379                            char **pdomain_name,
380                            char ***pnames,
381                            enum lsa_SidType **ptypes)
382 {
383         enum lsa_SidType *types = NULL;
384         char *domain_name = NULL;
385         char **domains = NULL;
386         char **names = NULL;
387         struct dom_sid *sids;
388         size_t i;
389         NTSTATUS status;
390
391         if (num_rids > 0) {
392                 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
393                 if (sids == NULL) {
394                         return NT_STATUS_NO_MEMORY;
395                 }
396         } else {
397                 sids = NULL;
398         }
399
400         for (i = 0; i < num_rids; i++) {
401                 if (!sid_compose(&sids[i], sid, rids[i])) {
402                         return NT_STATUS_INTERNAL_ERROR;
403                 }
404         }
405
406         status = rpccli_lsa_lookup_sids(lsa_pipe,
407                                         mem_ctx,
408                                         lsa_policy,
409                                         num_rids,
410                                         sids,
411                                         &domains,
412                                         &names,
413                                         &types);
414         if (!NT_STATUS_IS_OK(status) &&
415             !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
416                 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
417                         nt_errstr(status)));
418                 return status;
419         }
420
421         for (i = 0; i < num_rids; i++) {
422                 char *mapped_name = NULL;
423                 NTSTATUS map_status;
424
425                 if (types[i] != SID_NAME_UNKNOWN) {
426                         map_status = normalize_name_map(mem_ctx,
427                                                         domain,
428                                                         names[i],
429                                                         &mapped_name);
430                         if (NT_STATUS_IS_OK(map_status) ||
431                             NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
432                                 TALLOC_FREE(names[i]);
433                                 names[i] = talloc_strdup(names, mapped_name);
434                                 if (names[i] == NULL) {
435                                         return NT_STATUS_NO_MEMORY;
436                                 }
437                         }
438
439                         domain_name = domains[i];
440                 }
441         }
442
443         *pdomain_name = domain_name;
444         *ptypes = types;
445         *pnames = names;
446
447         return NT_STATUS_OK;
448 }
449
450 /* Lookup user information from a rid or username. */
451 NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx,
452                         struct rpc_pipe_client *samr_pipe,
453                         struct policy_handle *samr_policy,
454                         const struct dom_sid *domain_sid,
455                         const struct dom_sid *user_sid,
456                         struct wbint_userinfo *user_info)
457 {
458         struct policy_handle user_policy;
459         union samr_UserInfo *info = NULL;
460         uint32_t user_rid;
461         NTSTATUS status;
462
463         if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
464                 return NT_STATUS_UNSUCCESSFUL;
465         }
466
467         /* Get user handle */
468         status = rpccli_samr_OpenUser(samr_pipe,
469                                       mem_ctx,
470                                       samr_policy,
471                                       SEC_FLAG_MAXIMUM_ALLOWED,
472                                       user_rid,
473                                       &user_policy);
474         if (!NT_STATUS_IS_OK(status)) {
475                 return status;
476         }
477
478         /* Get user info */
479         status = rpccli_samr_QueryUserInfo(samr_pipe,
480                                            mem_ctx,
481                                            &user_policy,
482                                            0x15,
483                                            &info);
484
485         rpccli_samr_Close(samr_pipe, mem_ctx, &user_policy);
486
487         if (!NT_STATUS_IS_OK(status)) {
488                 return status;
489         }
490
491         sid_compose(&user_info->user_sid, domain_sid, user_rid);
492         sid_compose(&user_info->group_sid, domain_sid,
493                     info->info21.primary_gid);
494
495         user_info->acct_name = talloc_strdup(user_info,
496                                         info->info21.account_name.string);
497         if (user_info->acct_name == NULL) {
498                 return NT_STATUS_NO_MEMORY;
499         }
500
501         user_info->full_name = talloc_strdup(user_info,
502                                         info->info21.full_name.string);
503         if (user_info->acct_name == NULL) {
504                 return NT_STATUS_NO_MEMORY;
505         }
506
507         user_info->homedir = NULL;
508         user_info->shell = NULL;
509         user_info->primary_gid = (gid_t)-1;
510
511         return NT_STATUS_OK;
512 }
513
514 /* Lookup groups a user is a member of. */
515 NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
516                                struct rpc_pipe_client *samr_pipe,
517                                struct policy_handle *samr_policy,
518                                const struct dom_sid *domain_sid,
519                                const struct dom_sid *user_sid,
520                                uint32_t *pnum_groups,
521                                struct dom_sid **puser_grpsids)
522 {
523         struct policy_handle user_policy;
524         struct samr_RidWithAttributeArray *rid_array = NULL;
525         struct dom_sid *user_grpsids = NULL;
526         uint32_t num_groups = 0, i;
527         uint32_t user_rid;
528         NTSTATUS status;
529
530         if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
531                 return NT_STATUS_UNSUCCESSFUL;
532         }
533
534         /* Get user handle */
535         status = rpccli_samr_OpenUser(samr_pipe,
536                                       mem_ctx,
537                                       samr_policy,
538                                       SEC_FLAG_MAXIMUM_ALLOWED,
539                                       user_rid,
540                                       &user_policy);
541         if (!NT_STATUS_IS_OK(status)) {
542                 return status;
543         }
544
545         /* Query user rids */
546         status = rpccli_samr_GetGroupsForUser(samr_pipe,
547                                               mem_ctx,
548                                               &user_policy,
549                                               &rid_array);
550         num_groups = rid_array->count;
551
552         rpccli_samr_Close(samr_pipe, mem_ctx, &user_policy);
553
554         if (!NT_STATUS_IS_OK(status) || num_groups == 0) {
555                 return status;
556         }
557
558         user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
559         if (user_grpsids == NULL) {
560                 status = NT_STATUS_NO_MEMORY;
561                 return status;
562         }
563
564         for (i = 0; i < num_groups; i++) {
565                 sid_compose(&(user_grpsids[i]), domain_sid,
566                             rid_array->rids[i].rid);
567         }
568
569         *pnum_groups = num_groups;
570
571         *puser_grpsids = user_grpsids;
572
573         return NT_STATUS_OK;
574 }
575
576 NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
577                                 struct rpc_pipe_client *samr_pipe,
578                                 struct policy_handle *samr_policy,
579                                 uint32_t num_sids,
580                                 const struct dom_sid *sids,
581                                 uint32_t *pnum_aliases,
582                                 uint32_t **palias_rids)
583 {
584 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
585         uint32_t num_query_sids = 0;
586         uint32_t num_queries = 1;
587         uint32_t num_aliases = 0;
588         uint32_t total_sids = 0;
589         uint32_t *alias_rids = NULL;
590         uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
591         uint32_t i;
592         struct samr_Ids alias_rids_query;
593         NTSTATUS status;
594
595         do {
596                 /* prepare query */
597                 struct lsa_SidArray sid_array;
598
599                 ZERO_STRUCT(sid_array);
600
601                 num_query_sids = MIN(num_sids - total_sids, rangesize);
602
603                 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
604                         num_queries, num_query_sids));
605
606                 if (num_query_sids) {
607                         sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
608                         if (sid_array.sids == NULL) {
609                                 return NT_STATUS_NO_MEMORY;
610                         }
611                 } else {
612                         sid_array.sids = NULL;
613                 }
614
615                 for (i = 0; i < num_query_sids; i++) {
616                         sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
617                         if (sid_array.sids[i].sid == NULL) {
618                                 return NT_STATUS_NO_MEMORY;
619                         }
620                 }
621                 sid_array.num_sids = num_query_sids;
622
623                 /* do request */
624                 status = rpccli_samr_GetAliasMembership(samr_pipe,
625                                                         mem_ctx,
626                                                         samr_policy,
627                                                         &sid_array,
628                                                         &alias_rids_query);
629                 if (!NT_STATUS_IS_OK(status)) {
630                         return status;
631                 }
632
633                 /* process output */
634                 for (i = 0; i < alias_rids_query.count; i++) {
635                         size_t na = num_aliases;
636
637                         if (!add_rid_to_array_unique(mem_ctx,
638                                                      alias_rids_query.ids[i],
639                                                      &alias_rids,
640                                                      &na)) {
641                                         return NT_STATUS_NO_MEMORY;
642                                 }
643                                 num_aliases = na;
644                 }
645
646                 num_queries++;
647
648         } while (total_sids < num_sids);
649
650         DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
651                   "(rangesize: %d)\n", num_aliases, num_queries, rangesize));
652
653         *pnum_aliases = num_aliases;
654         *palias_rids = alias_rids;
655
656         return NT_STATUS_OK;
657 #undef MAX_SAM_ENTRIES_W2K
658 }
659
660 /* Lookup group membership given a rid.   */
661 NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
662                              struct rpc_pipe_client *samr_pipe,
663                              struct policy_handle *samr_policy,
664                              const char *domain_name,
665                              const struct dom_sid *domain_sid,
666                              const struct dom_sid *group_sid,
667                              enum lsa_SidType type,
668                              uint32_t *pnum_names,
669                              struct dom_sid **psid_mem,
670                              char ***pnames,
671                              uint32_t **pname_types)
672 {
673         struct policy_handle group_policy;
674         uint32_t group_rid;
675         uint32_t *rid_mem = NULL;
676
677         uint32_t num_names = 0;
678         uint32_t total_names = 0;
679         struct dom_sid *sid_mem = NULL;
680         char **names = NULL;
681         uint32_t *name_types = NULL;
682
683         struct lsa_Strings tmp_names;
684         struct samr_Ids tmp_types;
685
686         uint32_t j, r;
687         NTSTATUS status;
688
689         if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
690                 return NT_STATUS_UNSUCCESSFUL;
691         }
692
693         switch(type) {
694         case SID_NAME_DOM_GRP:
695         {
696                 struct samr_RidAttrArray *rids = NULL;
697
698                 status = rpccli_samr_OpenGroup(samr_pipe,
699                                                mem_ctx,
700                                                samr_policy,
701                                                SEC_FLAG_MAXIMUM_ALLOWED,
702                                                group_rid,
703                                                &group_policy);
704                 if (!NT_STATUS_IS_OK(status)) {
705                         return status;
706                 }
707
708                 /*
709                  * Step #1: Get a list of user rids that are the members of the group.
710                  */
711                 status = rpccli_samr_QueryGroupMember(samr_pipe,
712                                                       mem_ctx,
713                                                       &group_policy,
714                                                       &rids);
715
716                 rpccli_samr_Close(samr_pipe, mem_ctx, &group_policy);
717
718                 if (!NT_STATUS_IS_OK(status)) {
719                         return status;
720                 }
721
722                 if (rids == NULL || rids->count == 0) {
723                         pnum_names = 0;
724                         pnames = NULL;
725                         pname_types = NULL;
726                         psid_mem = NULL;
727
728                         return NT_STATUS_OK;
729                 }
730
731                 num_names = rids->count;
732                 rid_mem = rids->rids;
733
734                 break;
735         }
736         case SID_NAME_WKN_GRP:
737         case SID_NAME_ALIAS:
738         {
739                 struct lsa_SidArray sid_array;
740                 struct lsa_SidPtr sid_ptr;
741                 struct samr_Ids rids_query;
742
743                 sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid);
744                 if (sid_ptr.sid == NULL) {
745                         return NT_STATUS_NO_MEMORY;
746                 }
747
748                 sid_array.num_sids = 1;
749                 sid_array.sids = &sid_ptr;
750
751                 status = rpccli_samr_GetAliasMembership(samr_pipe,
752                                                         mem_ctx,
753                                                         samr_policy,
754                                                         &sid_array,
755                                                         &rids_query);
756
757                 if (rids_query.count == 0) {
758                         pnum_names = 0;
759                         pnames = NULL;
760                         pname_types = NULL;
761                         psid_mem = NULL;
762
763                         return NT_STATUS_OK;
764                 }
765
766                 num_names = rids_query.count;
767                 rid_mem = rids_query.ids;
768
769                 break;
770         }
771         default:
772                 return NT_STATUS_UNSUCCESSFUL;
773         }
774
775         /*
776          * Step #2: Convert list of rids into list of usernames.
777          */
778         if (num_names > 0) {
779                 names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names);
780                 name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names);
781                 sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names);
782                 if (names == NULL || name_types == NULL || sid_mem == NULL) {
783                         return NT_STATUS_NO_MEMORY;
784                 }
785         }
786
787         for (j = 0; j < num_names; j++) {
788                 sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
789         }
790
791         status = rpccli_samr_LookupRids(samr_pipe,
792                                         mem_ctx,
793                                         samr_policy,
794                                         num_names,
795                                         rid_mem,
796                                         &tmp_names,
797                                         &tmp_types);
798         if (!NT_STATUS_IS_OK(status)) {
799                 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
800                         return status;
801                 }
802         }
803
804         /* Copy result into array.  The talloc system will take
805            care of freeing the temporary arrays later on. */
806         if (tmp_names.count != tmp_types.count) {
807                 return NT_STATUS_UNSUCCESSFUL;
808         }
809
810         for (r = 0; r < tmp_names.count; r++) {
811                 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
812                         continue;
813                 }
814                 names[total_names] = fill_domain_username_talloc(names,
815                                                                  domain_name,
816                                                                  tmp_names.names[r].string,
817                                                                  true);
818                 if (names[total_names] == NULL) {
819                         return NT_STATUS_NO_MEMORY;
820                 }
821                 name_types[total_names] = tmp_types.ids[r];
822                 total_names++;
823         }
824
825         *pnum_names = total_names;
826         *pnames = names;
827         *pname_types = name_types;
828         *psid_mem = sid_mem;
829
830         return NT_STATUS_OK;
831 }
832
833 /* Find the sequence number for a domain */
834 NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx,
835                              struct rpc_pipe_client *samr_pipe,
836                              struct policy_handle *samr_policy,
837                              const char *domain_name,
838                              uint32_t *pseq)
839 {
840         union samr_DomainInfo *info = NULL;
841         bool got_seq_num = false;
842         NTSTATUS status;
843
844         /* query domain info */
845         status = rpccli_samr_QueryDomainInfo(samr_pipe,
846                                              mem_ctx,
847                                              samr_policy,
848                                              8,
849                                              &info);
850         if (NT_STATUS_IS_OK(status)) {
851                 *pseq = info->info8.sequence_num;
852                 got_seq_num = true;
853                 goto seq_num;
854         }
855
856         /* retry with info-level 2 in case the dc does not support info-level 8
857          * (like all older samba2 and samba3 dc's) - Guenther */
858         status = rpccli_samr_QueryDomainInfo(samr_pipe,
859                                              mem_ctx,
860                                              samr_policy,
861                                              2,
862                                              &info);
863         if (NT_STATUS_IS_OK(status)) {
864                 *pseq = info->general.sequence_num;
865                 got_seq_num = true;
866         }
867
868 seq_num:
869         if (got_seq_num) {
870                 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
871                           domain_name, (unsigned) *pseq));
872         } else {
873                 DEBUG(10,("domain_sequence_number: failed to get sequence "
874                           "number (%u) for domain %s\n",
875                           (unsigned) *pseq, domain_name ));
876                 status = NT_STATUS_OK;
877         }
878
879         return status;
880 }
881
882 /* Get a list of trusted domains */
883 NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
884                              struct rpc_pipe_client *lsa_pipe,
885                              struct policy_handle *lsa_policy,
886                              uint32_t *pnum_trusts,
887                              struct netr_DomainTrust **ptrusts)
888 {
889         struct netr_DomainTrust *array = NULL;
890         uint32_t enum_ctx = 0;
891         uint32_t count = 0;
892         NTSTATUS status;
893
894         do {
895                 struct lsa_DomainList dom_list;
896                 uint32_t start_idx;
897                 uint32_t i;
898
899                 /*
900                  * We don't run into deadlocks here, cause winbind_off() is
901                  * called in the main function.
902                  */
903                 status = rpccli_lsa_EnumTrustDom(lsa_pipe,
904                                                  mem_ctx,
905                                                  lsa_policy,
906                                                  &enum_ctx,
907                                                  &dom_list,
908                                                  (uint32_t) -1);
909                 if (!NT_STATUS_IS_OK(status)) {
910                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
911                                 return status;
912                         }
913                 }
914
915                 start_idx = count;
916                 count += dom_list.count;
917
918                 array = talloc_realloc(mem_ctx,
919                                        array,
920                                        struct netr_DomainTrust,
921                                        count);
922                 if (array == NULL) {
923                         return NT_STATUS_NO_MEMORY;
924                 }
925
926                 for (i = 0; i < dom_list.count; i++) {
927                         struct netr_DomainTrust *trust = &array[i];
928                         struct dom_sid *sid;
929
930                         ZERO_STRUCTP(trust);
931
932                         trust->netbios_name = talloc_move(array,
933                                                           &dom_list.domains[i].name.string);
934                         trust->dns_name = NULL;
935
936                         sid = talloc(array, struct dom_sid);
937                         if (sid == NULL) {
938                                 return NT_STATUS_NO_MEMORY;
939                         }
940                         sid_copy(sid, dom_list.domains[i].sid);
941                         trust->sid = sid;
942                 }
943         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
944
945         *pnum_trusts = count;
946         *ptrusts = array;
947
948         return NT_STATUS_OK;
949 }