s4:sam.py - assign valid values when performing the special-attributes constraint...
[Samba.git] / source3 / winbindd / winbindd_rpc.c
blob47d8f34e1bb75650fdbb92f21fcf5a5ea7843267
1 /*
2 * Unix SMB/CIFS implementation.
4 * Winbind rpc backend functions
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>
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.
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.
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/>.
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
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/security.h"
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)
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;
53 *pnum_info = 0;
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;
62 get_query_dispinfo_params(loop_count,
63 &max_entries,
64 &max_size);
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;
82 /* increment required start query values */
83 start_idx += disp_info.info1.count;
84 loop_count++;
85 num_dom_users = disp_info.info1.count;
87 num_info += num_dom_users;
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;
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;
102 src = &(disp_info.info1.entries[j]);
103 dst = &(info[i]);
105 dst->acct_name = talloc_strdup(info,
106 src->account_name.string);
107 if (dst->acct_name == NULL) {
108 return NT_STATUS_NO_MEMORY;
111 dst->full_name = talloc_strdup(info, src->full_name.string);
112 if ((src->full_name.string != NULL) &&
113 (dst->full_name == NULL))
115 return NT_STATUS_NO_MEMORY;
118 dst->homedir = NULL;
119 dst->shell = NULL;
121 sid_compose(&dst->user_sid, domain_sid, rid);
123 /* For the moment we set the primary group for
124 every user to be the Domain Users group.
125 There are serious problems with determining
126 the actual primary group for large domains.
127 This should really be made into a 'winbind
128 force group' smb.conf parameter or
129 something like that. */
130 sid_compose(&dst->group_sid, domain_sid,
131 DOMAIN_RID_USERS);
133 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
135 *pnum_info = num_info;
136 *pinfo = info;
138 return NT_STATUS_OK;
141 /* List all domain groups */
142 NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx,
143 struct rpc_pipe_client *samr_pipe,
144 struct policy_handle *samr_policy,
145 uint32_t *pnum_info,
146 struct acct_info **pinfo)
148 struct acct_info *info = NULL;
149 uint32_t start = 0;
150 uint32_t num_info = 0;
151 NTSTATUS status;
153 *pnum_info = 0;
155 do {
156 struct samr_SamArray *sam_array = NULL;
157 uint32_t count = 0;
158 uint32_t g;
160 /* start is updated by this call. */
161 status = rpccli_samr_EnumDomainGroups(samr_pipe,
162 mem_ctx,
163 samr_policy,
164 &start,
165 &sam_array,
166 0xFFFF, /* buffer size? */
167 &count);
168 if (!NT_STATUS_IS_OK(status)) {
169 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
170 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
171 nt_errstr(status)));
172 return status;
176 info = TALLOC_REALLOC_ARRAY(mem_ctx,
177 info,
178 struct acct_info,
179 num_info + count);
180 if (info == NULL) {
181 return NT_STATUS_NO_MEMORY;
184 for (g = 0; g < count; g++) {
185 fstrcpy(info[num_info + g].acct_name,
186 sam_array->entries[g].name.string);
188 info[num_info + g].rid = sam_array->entries[g].idx;
191 num_info += count;
192 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
194 *pnum_info = num_info;
195 *pinfo = info;
197 return NT_STATUS_OK;
200 NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx,
201 struct rpc_pipe_client *samr_pipe,
202 struct policy_handle *samr_policy,
203 uint32_t *pnum_info,
204 struct acct_info **pinfo)
206 struct acct_info *info = NULL;
207 uint32_t num_info = 0;
208 NTSTATUS status;
210 *pnum_info = 0;
212 do {
213 struct samr_SamArray *sam_array = NULL;
214 uint32_t count = 0;
215 uint32_t start = num_info;
216 uint32_t g;
218 status = rpccli_samr_EnumDomainAliases(samr_pipe,
219 mem_ctx,
220 samr_policy,
221 &start,
222 &sam_array,
223 0xFFFF, /* buffer size? */
224 &count);
225 if (!NT_STATUS_IS_OK(status)) {
226 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
227 return status;
231 info = TALLOC_REALLOC_ARRAY(mem_ctx,
232 info,
233 struct acct_info,
234 num_info + count);
235 if (info == NULL) {
236 return NT_STATUS_NO_MEMORY;
239 for (g = 0; g < count; g++) {
240 fstrcpy(info[num_info + g].acct_name,
241 sam_array->entries[g].name.string);
242 info[num_info + g].rid = sam_array->entries[g].idx;
245 num_info += count;
246 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
248 *pnum_info = num_info;
249 *pinfo = info;
251 return NT_STATUS_OK;
254 /* convert a single name to a sid in a domain */
255 NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
256 struct rpc_pipe_client *lsa_pipe,
257 struct policy_handle *lsa_policy,
258 const char *domain_name,
259 const char *name,
260 uint32_t flags,
261 struct dom_sid *sid,
262 enum lsa_SidType *type)
264 enum lsa_SidType *types = NULL;
265 struct dom_sid *sids = NULL;
266 char *full_name = NULL;
267 char *mapped_name = NULL;
268 NTSTATUS status;
270 if (name == NULL || name[0] == '\0') {
271 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
272 } else if (domain_name == NULL || domain_name[0] == '\0') {
273 full_name = talloc_asprintf(mem_ctx, "%s", name);
274 } else {
275 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
278 if (full_name == NULL) {
279 return NT_STATUS_NO_MEMORY;
282 status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
283 /* Reset the full_name pointer if we mapped anything */
284 if (NT_STATUS_IS_OK(status) ||
285 NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
286 full_name = mapped_name;
289 DEBUG(3,("name_to_sid: %s for domain %s\n",
290 full_name ? full_name : "", domain_name ));
293 * We don't run into deadlocks here, cause winbind_off() is
294 * called in the main function.
296 status = rpccli_lsa_lookup_names(lsa_pipe,
297 mem_ctx,
298 lsa_policy,
299 1, /* num_names */
300 (const char **) &full_name,
301 NULL, /* domains */
302 1, /* level */
303 &sids,
304 &types);
305 if (!NT_STATUS_IS_OK(status)) {
306 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
307 nt_errstr(status)));
308 return status;
311 sid_copy(sid, &sids[0]);
312 *type = types[0];
314 return NT_STATUS_OK;
317 /* Convert a domain SID to a user or group name */
318 NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx,
319 struct rpc_pipe_client *lsa_pipe,
320 struct policy_handle *lsa_policy,
321 struct winbindd_domain *domain,
322 const struct dom_sid *sid,
323 char **pdomain_name,
324 char **pname,
325 enum lsa_SidType *ptype)
327 char *mapped_name = NULL;
328 char **domains = NULL;
329 char **names = NULL;
330 enum lsa_SidType *types = NULL;
331 NTSTATUS map_status;
332 NTSTATUS status;
334 status = rpccli_lsa_lookup_sids(lsa_pipe,
335 mem_ctx,
336 lsa_policy,
337 1, /* num_sids */
338 sid,
339 &domains,
340 &names,
341 &types);
342 if (!NT_STATUS_IS_OK(status)) {
343 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
344 nt_errstr(status)));
345 return status;
348 *ptype = (enum lsa_SidType) types[0];
350 map_status = normalize_name_map(mem_ctx,
351 domain,
352 *pname,
353 &mapped_name);
354 if (NT_STATUS_IS_OK(map_status) ||
355 NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
356 *pname = talloc_strdup(mem_ctx, mapped_name);
357 DEBUG(5,("returning mapped name -- %s\n", *pname));
358 } else {
359 *pname = talloc_strdup(mem_ctx, names[0]);
361 if (*pname == NULL) {
362 return NT_STATUS_NO_MEMORY;
365 *pdomain_name = talloc_strdup(mem_ctx, domains[0]);
366 if (*pdomain_name == NULL) {
367 return NT_STATUS_NO_MEMORY;
370 return NT_STATUS_OK;
373 /* Convert a bunch of rids to user or group names */
374 NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx,
375 struct rpc_pipe_client *lsa_pipe,
376 struct policy_handle *lsa_policy,
377 struct winbindd_domain *domain,
378 const struct dom_sid *sid,
379 uint32_t *rids,
380 size_t num_rids,
381 char **pdomain_name,
382 char ***pnames,
383 enum lsa_SidType **ptypes)
385 enum lsa_SidType *types = NULL;
386 char *domain_name = NULL;
387 char **domains = NULL;
388 char **names = NULL;
389 struct dom_sid *sids;
390 size_t i;
391 NTSTATUS status;
393 if (num_rids > 0) {
394 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
395 if (sids == NULL) {
396 return NT_STATUS_NO_MEMORY;
398 } else {
399 sids = NULL;
402 for (i = 0; i < num_rids; i++) {
403 if (!sid_compose(&sids[i], sid, rids[i])) {
404 return NT_STATUS_INTERNAL_ERROR;
408 status = rpccli_lsa_lookup_sids(lsa_pipe,
409 mem_ctx,
410 lsa_policy,
411 num_rids,
412 sids,
413 &domains,
414 &names,
415 &types);
416 if (!NT_STATUS_IS_OK(status) &&
417 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
418 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
419 nt_errstr(status)));
420 return status;
423 for (i = 0; i < num_rids; i++) {
424 char *mapped_name = NULL;
425 NTSTATUS map_status;
427 if (types[i] != SID_NAME_UNKNOWN) {
428 map_status = normalize_name_map(mem_ctx,
429 domain,
430 names[i],
431 &mapped_name);
432 if (NT_STATUS_IS_OK(map_status) ||
433 NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) {
434 TALLOC_FREE(names[i]);
435 names[i] = talloc_strdup(names, mapped_name);
436 if (names[i] == NULL) {
437 return NT_STATUS_NO_MEMORY;
441 domain_name = domains[i];
445 *pdomain_name = domain_name;
446 *ptypes = types;
447 *pnames = names;
449 return NT_STATUS_OK;
452 /* Lookup user information from a rid or username. */
453 NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx,
454 struct rpc_pipe_client *samr_pipe,
455 struct policy_handle *samr_policy,
456 const struct dom_sid *domain_sid,
457 const struct dom_sid *user_sid,
458 struct wbint_userinfo *user_info)
460 struct policy_handle user_policy;
461 union samr_UserInfo *info = NULL;
462 uint32_t user_rid;
463 NTSTATUS status;
465 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
466 return NT_STATUS_UNSUCCESSFUL;
469 /* Get user handle */
470 status = rpccli_samr_OpenUser(samr_pipe,
471 mem_ctx,
472 samr_policy,
473 SEC_FLAG_MAXIMUM_ALLOWED,
474 user_rid,
475 &user_policy);
476 if (!NT_STATUS_IS_OK(status)) {
477 return status;
480 /* Get user info */
481 status = rpccli_samr_QueryUserInfo(samr_pipe,
482 mem_ctx,
483 &user_policy,
484 0x15,
485 &info);
487 rpccli_samr_Close(samr_pipe, mem_ctx, &user_policy);
489 if (!NT_STATUS_IS_OK(status)) {
490 return status;
493 sid_compose(&user_info->user_sid, domain_sid, user_rid);
494 sid_compose(&user_info->group_sid, domain_sid,
495 info->info21.primary_gid);
497 user_info->acct_name = talloc_strdup(user_info,
498 info->info21.account_name.string);
499 if (user_info->acct_name == NULL) {
500 return NT_STATUS_NO_MEMORY;
503 user_info->full_name = talloc_strdup(user_info,
504 info->info21.full_name.string);
505 if ((info->info21.full_name.string != NULL) &&
506 (user_info->acct_name == NULL))
508 return NT_STATUS_NO_MEMORY;
511 user_info->homedir = NULL;
512 user_info->shell = NULL;
513 user_info->primary_gid = (gid_t)-1;
515 return NT_STATUS_OK;
518 /* Lookup groups a user is a member of. */
519 NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx,
520 struct rpc_pipe_client *samr_pipe,
521 struct policy_handle *samr_policy,
522 const struct dom_sid *domain_sid,
523 const struct dom_sid *user_sid,
524 uint32_t *pnum_groups,
525 struct dom_sid **puser_grpsids)
527 struct policy_handle user_policy;
528 struct samr_RidWithAttributeArray *rid_array = NULL;
529 struct dom_sid *user_grpsids = NULL;
530 uint32_t num_groups = 0, i;
531 uint32_t user_rid;
532 NTSTATUS status;
534 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
535 return NT_STATUS_UNSUCCESSFUL;
538 /* Get user handle */
539 status = rpccli_samr_OpenUser(samr_pipe,
540 mem_ctx,
541 samr_policy,
542 SEC_FLAG_MAXIMUM_ALLOWED,
543 user_rid,
544 &user_policy);
545 if (!NT_STATUS_IS_OK(status)) {
546 return status;
549 /* Query user rids */
550 status = rpccli_samr_GetGroupsForUser(samr_pipe,
551 mem_ctx,
552 &user_policy,
553 &rid_array);
554 num_groups = rid_array->count;
556 rpccli_samr_Close(samr_pipe, mem_ctx, &user_policy);
558 if (!NT_STATUS_IS_OK(status) || num_groups == 0) {
559 return status;
562 user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups);
563 if (user_grpsids == NULL) {
564 status = NT_STATUS_NO_MEMORY;
565 return status;
568 for (i = 0; i < num_groups; i++) {
569 sid_compose(&(user_grpsids[i]), domain_sid,
570 rid_array->rids[i].rid);
573 *pnum_groups = num_groups;
575 *puser_grpsids = user_grpsids;
577 return NT_STATUS_OK;
580 NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx,
581 struct rpc_pipe_client *samr_pipe,
582 struct policy_handle *samr_policy,
583 uint32_t num_sids,
584 const struct dom_sid *sids,
585 uint32_t *pnum_aliases,
586 uint32_t **palias_rids)
588 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
589 uint32_t num_query_sids = 0;
590 uint32_t num_queries = 1;
591 uint32_t num_aliases = 0;
592 uint32_t total_sids = 0;
593 uint32_t *alias_rids = NULL;
594 uint32_t rangesize = MAX_SAM_ENTRIES_W2K;
595 uint32_t i;
596 struct samr_Ids alias_rids_query;
597 NTSTATUS status;
599 do {
600 /* prepare query */
601 struct lsa_SidArray sid_array;
603 ZERO_STRUCT(sid_array);
605 num_query_sids = MIN(num_sids - total_sids, rangesize);
607 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
608 num_queries, num_query_sids));
610 if (num_query_sids) {
611 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
612 if (sid_array.sids == NULL) {
613 return NT_STATUS_NO_MEMORY;
615 } else {
616 sid_array.sids = NULL;
619 for (i = 0; i < num_query_sids; i++) {
620 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]);
621 if (sid_array.sids[i].sid == NULL) {
622 return NT_STATUS_NO_MEMORY;
625 sid_array.num_sids = num_query_sids;
627 /* do request */
628 status = rpccli_samr_GetAliasMembership(samr_pipe,
629 mem_ctx,
630 samr_policy,
631 &sid_array,
632 &alias_rids_query);
633 if (!NT_STATUS_IS_OK(status)) {
634 return status;
637 /* process output */
638 for (i = 0; i < alias_rids_query.count; i++) {
639 size_t na = num_aliases;
641 if (!add_rid_to_array_unique(mem_ctx,
642 alias_rids_query.ids[i],
643 &alias_rids,
644 &na)) {
645 return NT_STATUS_NO_MEMORY;
647 num_aliases = na;
650 num_queries++;
652 } while (total_sids < num_sids);
654 DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
655 "(rangesize: %d)\n", num_aliases, num_queries, rangesize));
657 *pnum_aliases = num_aliases;
658 *palias_rids = alias_rids;
660 return NT_STATUS_OK;
661 #undef MAX_SAM_ENTRIES_W2K
664 /* Lookup group membership given a rid. */
665 NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
666 struct rpc_pipe_client *samr_pipe,
667 struct policy_handle *samr_policy,
668 const char *domain_name,
669 const struct dom_sid *domain_sid,
670 const struct dom_sid *group_sid,
671 enum lsa_SidType type,
672 uint32_t *pnum_names,
673 struct dom_sid **psid_mem,
674 char ***pnames,
675 uint32_t **pname_types)
677 struct policy_handle group_policy;
678 uint32_t group_rid;
679 uint32_t *rid_mem = NULL;
681 uint32_t num_names = 0;
682 uint32_t total_names = 0;
683 struct dom_sid *sid_mem = NULL;
684 char **names = NULL;
685 uint32_t *name_types = NULL;
687 struct lsa_Strings tmp_names;
688 struct samr_Ids tmp_types;
690 uint32_t j, r;
691 NTSTATUS status;
693 if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) {
694 return NT_STATUS_UNSUCCESSFUL;
697 switch(type) {
698 case SID_NAME_DOM_GRP:
700 struct samr_RidAttrArray *rids = NULL;
702 status = rpccli_samr_OpenGroup(samr_pipe,
703 mem_ctx,
704 samr_policy,
705 SEC_FLAG_MAXIMUM_ALLOWED,
706 group_rid,
707 &group_policy);
708 if (!NT_STATUS_IS_OK(status)) {
709 return status;
713 * Step #1: Get a list of user rids that are the members of the group.
715 status = rpccli_samr_QueryGroupMember(samr_pipe,
716 mem_ctx,
717 &group_policy,
718 &rids);
720 rpccli_samr_Close(samr_pipe, mem_ctx, &group_policy);
722 if (!NT_STATUS_IS_OK(status)) {
723 return status;
726 if (rids == NULL || rids->count == 0) {
727 pnum_names = 0;
728 pnames = NULL;
729 pname_types = NULL;
730 psid_mem = NULL;
732 return NT_STATUS_OK;
735 num_names = rids->count;
736 rid_mem = rids->rids;
738 break;
740 case SID_NAME_WKN_GRP:
741 case SID_NAME_ALIAS:
743 struct lsa_SidArray sid_array;
744 struct lsa_SidPtr sid_ptr;
745 struct samr_Ids rids_query;
747 sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid);
748 if (sid_ptr.sid == NULL) {
749 return NT_STATUS_NO_MEMORY;
752 sid_array.num_sids = 1;
753 sid_array.sids = &sid_ptr;
755 status = rpccli_samr_GetAliasMembership(samr_pipe,
756 mem_ctx,
757 samr_policy,
758 &sid_array,
759 &rids_query);
761 if (rids_query.count == 0) {
762 pnum_names = 0;
763 pnames = NULL;
764 pname_types = NULL;
765 psid_mem = NULL;
767 return NT_STATUS_OK;
770 num_names = rids_query.count;
771 rid_mem = rids_query.ids;
773 break;
775 default:
776 return NT_STATUS_UNSUCCESSFUL;
780 * Step #2: Convert list of rids into list of usernames.
782 if (num_names > 0) {
783 names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names);
784 name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names);
785 sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names);
786 if (names == NULL || name_types == NULL || sid_mem == NULL) {
787 return NT_STATUS_NO_MEMORY;
791 for (j = 0; j < num_names; j++) {
792 sid_compose(&sid_mem[j], domain_sid, rid_mem[j]);
795 status = rpccli_samr_LookupRids(samr_pipe,
796 mem_ctx,
797 samr_policy,
798 num_names,
799 rid_mem,
800 &tmp_names,
801 &tmp_types);
802 if (!NT_STATUS_IS_OK(status)) {
803 if (!NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) {
804 return status;
808 /* Copy result into array. The talloc system will take
809 care of freeing the temporary arrays later on. */
810 if (tmp_names.count != tmp_types.count) {
811 return NT_STATUS_UNSUCCESSFUL;
814 for (r = 0; r < tmp_names.count; r++) {
815 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
816 continue;
818 names[total_names] = fill_domain_username_talloc(names,
819 domain_name,
820 tmp_names.names[r].string,
821 true);
822 if (names[total_names] == NULL) {
823 return NT_STATUS_NO_MEMORY;
825 name_types[total_names] = tmp_types.ids[r];
826 total_names++;
829 *pnum_names = total_names;
830 *pnames = names;
831 *pname_types = name_types;
832 *psid_mem = sid_mem;
834 return NT_STATUS_OK;
837 /* Find the sequence number for a domain */
838 NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx,
839 struct rpc_pipe_client *samr_pipe,
840 struct policy_handle *samr_policy,
841 const char *domain_name,
842 uint32_t *pseq)
844 union samr_DomainInfo *info = NULL;
845 bool got_seq_num = false;
846 NTSTATUS status;
848 /* query domain info */
849 status = rpccli_samr_QueryDomainInfo(samr_pipe,
850 mem_ctx,
851 samr_policy,
853 &info);
854 if (NT_STATUS_IS_OK(status)) {
855 *pseq = info->info8.sequence_num;
856 got_seq_num = true;
857 goto seq_num;
860 /* retry with info-level 2 in case the dc does not support info-level 8
861 * (like all older samba2 and samba3 dc's) - Guenther */
862 status = rpccli_samr_QueryDomainInfo(samr_pipe,
863 mem_ctx,
864 samr_policy,
866 &info);
867 if (NT_STATUS_IS_OK(status)) {
868 *pseq = info->general.sequence_num;
869 got_seq_num = true;
872 seq_num:
873 if (got_seq_num) {
874 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
875 domain_name, (unsigned) *pseq));
876 } else {
877 DEBUG(10,("domain_sequence_number: failed to get sequence "
878 "number (%u) for domain %s\n",
879 (unsigned) *pseq, domain_name ));
880 status = NT_STATUS_OK;
883 return status;
886 /* Get a list of trusted domains */
887 NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx,
888 struct rpc_pipe_client *lsa_pipe,
889 struct policy_handle *lsa_policy,
890 uint32_t *pnum_trusts,
891 struct netr_DomainTrust **ptrusts)
893 struct netr_DomainTrust *array = NULL;
894 uint32_t enum_ctx = 0;
895 uint32_t count = 0;
896 NTSTATUS status;
898 do {
899 struct lsa_DomainList dom_list;
900 uint32_t start_idx;
901 uint32_t i;
904 * We don't run into deadlocks here, cause winbind_off() is
905 * called in the main function.
907 status = rpccli_lsa_EnumTrustDom(lsa_pipe,
908 mem_ctx,
909 lsa_policy,
910 &enum_ctx,
911 &dom_list,
912 (uint32_t) -1);
913 if (!NT_STATUS_IS_OK(status)) {
914 if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
915 return status;
919 start_idx = count;
920 count += dom_list.count;
922 array = talloc_realloc(mem_ctx,
923 array,
924 struct netr_DomainTrust,
925 count);
926 if (array == NULL) {
927 return NT_STATUS_NO_MEMORY;
930 for (i = 0; i < dom_list.count; i++) {
931 struct netr_DomainTrust *trust = &array[i];
932 struct dom_sid *sid;
934 ZERO_STRUCTP(trust);
936 trust->netbios_name = talloc_move(array,
937 &dom_list.domains[i].name.string);
938 trust->dns_name = NULL;
940 sid = talloc(array, struct dom_sid);
941 if (sid == NULL) {
942 return NT_STATUS_NO_MEMORY;
944 sid_copy(sid, dom_list.domains[i].sid);
945 trust->sid = sid;
947 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
949 *pnum_trusts = count;
950 *ptrusts = array;
952 return NT_STATUS_OK;