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/>.
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
,
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;
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
,
66 status
= rpccli_samr_QueryDisplayInfo(samr_pipe
,
76 if (!NT_STATUS_IS_OK(status
)) {
77 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
82 /* increment required start query values */
83 start_idx
+= disp_info
.info1
.count
;
85 num_dom_users
= disp_info
.info1
.count
;
87 num_info
+= num_dom_users
;
89 info
= TALLOC_REALLOC_ARRAY(mem_ctx
,
91 struct wbint_userinfo
,
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
]);
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
;
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
,
133 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
135 *pnum_info
= num_info
;
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
,
146 struct acct_info
**pinfo
)
148 struct acct_info
*info
= NULL
;
150 uint32_t num_info
= 0;
156 struct samr_SamArray
*sam_array
= NULL
;
160 /* start is updated by this call. */
161 status
= rpccli_samr_EnumDomainGroups(samr_pipe
,
166 0xFFFF, /* buffer size? */
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",
176 info
= TALLOC_REALLOC_ARRAY(mem_ctx
,
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
;
192 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
194 *pnum_info
= num_info
;
200 NTSTATUS
rpc_enum_local_groups(TALLOC_CTX
*mem_ctx
,
201 struct rpc_pipe_client
*samr_pipe
,
202 struct policy_handle
*samr_policy
,
204 struct acct_info
**pinfo
)
206 struct acct_info
*info
= NULL
;
207 uint32_t num_info
= 0;
213 struct samr_SamArray
*sam_array
= NULL
;
215 uint32_t start
= num_info
;
218 status
= rpccli_samr_EnumDomainAliases(samr_pipe
,
223 0xFFFF, /* buffer size? */
225 if (!NT_STATUS_IS_OK(status
)) {
226 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
231 info
= TALLOC_REALLOC_ARRAY(mem_ctx
,
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
;
246 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
248 *pnum_info
= num_info
;
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
,
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
;
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
);
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
,
300 (const char **) &full_name
,
305 if (!NT_STATUS_IS_OK(status
)) {
306 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
311 sid_copy(sid
, &sids
[0]);
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
,
325 enum lsa_SidType
*ptype
)
327 char *mapped_name
= NULL
;
328 char **domains
= NULL
;
330 enum lsa_SidType
*types
= NULL
;
334 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
342 if (!NT_STATUS_IS_OK(status
)) {
343 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
348 *ptype
= (enum lsa_SidType
) types
[0];
350 map_status
= normalize_name_map(mem_ctx
,
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
));
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
;
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
,
383 enum lsa_SidType
**ptypes
)
385 enum lsa_SidType
*types
= NULL
;
386 char *domain_name
= NULL
;
387 char **domains
= NULL
;
389 struct dom_sid
*sids
;
394 sids
= TALLOC_ARRAY(mem_ctx
, struct dom_sid
, num_rids
);
396 return NT_STATUS_NO_MEMORY
;
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
,
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",
423 for (i
= 0; i
< num_rids
; i
++) {
424 char *mapped_name
= NULL
;
427 if (types
[i
] != SID_NAME_UNKNOWN
) {
428 map_status
= normalize_name_map(mem_ctx
,
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
;
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
;
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
,
473 SEC_FLAG_MAXIMUM_ALLOWED
,
476 if (!NT_STATUS_IS_OK(status
)) {
481 status
= rpccli_samr_QueryUserInfo(samr_pipe
,
487 rpccli_samr_Close(samr_pipe
, mem_ctx
, &user_policy
);
489 if (!NT_STATUS_IS_OK(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;
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
;
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
,
542 SEC_FLAG_MAXIMUM_ALLOWED
,
545 if (!NT_STATUS_IS_OK(status
)) {
549 /* Query user rids */
550 status
= rpccli_samr_GetGroupsForUser(samr_pipe
,
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) {
562 user_grpsids
= TALLOC_ARRAY(mem_ctx
, struct dom_sid
, num_groups
);
563 if (user_grpsids
== NULL
) {
564 status
= NT_STATUS_NO_MEMORY
;
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
;
580 NTSTATUS
rpc_lookup_useraliases(TALLOC_CTX
*mem_ctx
,
581 struct rpc_pipe_client
*samr_pipe
,
582 struct policy_handle
*samr_policy
,
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
;
596 struct samr_Ids alias_rids_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
;
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
;
628 status
= rpccli_samr_GetAliasMembership(samr_pipe
,
633 if (!NT_STATUS_IS_OK(status
)) {
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
],
645 return NT_STATUS_NO_MEMORY
;
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
;
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
,
675 uint32_t **pname_types
)
677 struct policy_handle group_policy
;
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
;
685 uint32_t *name_types
= NULL
;
687 struct lsa_Strings tmp_names
;
688 struct samr_Ids tmp_types
;
693 if (!sid_peek_check_rid(domain_sid
, group_sid
, &group_rid
)) {
694 return NT_STATUS_UNSUCCESSFUL
;
698 case SID_NAME_DOM_GRP
:
700 struct samr_RidAttrArray
*rids
= NULL
;
702 status
= rpccli_samr_OpenGroup(samr_pipe
,
705 SEC_FLAG_MAXIMUM_ALLOWED
,
708 if (!NT_STATUS_IS_OK(status
)) {
713 * Step #1: Get a list of user rids that are the members of the group.
715 status
= rpccli_samr_QueryGroupMember(samr_pipe
,
720 rpccli_samr_Close(samr_pipe
, mem_ctx
, &group_policy
);
722 if (!NT_STATUS_IS_OK(status
)) {
726 if (rids
== NULL
|| rids
->count
== 0) {
735 num_names
= rids
->count
;
736 rid_mem
= rids
->rids
;
740 case SID_NAME_WKN_GRP
:
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
,
761 if (rids_query
.count
== 0) {
770 num_names
= rids_query
.count
;
771 rid_mem
= rids_query
.ids
;
776 return NT_STATUS_UNSUCCESSFUL
;
780 * Step #2: Convert list of rids into list of usernames.
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
,
802 if (!NT_STATUS_IS_OK(status
)) {
803 if (!NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
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
) {
818 names
[total_names
] = fill_domain_username_talloc(names
,
820 tmp_names
.names
[r
].string
,
822 if (names
[total_names
] == NULL
) {
823 return NT_STATUS_NO_MEMORY
;
825 name_types
[total_names
] = tmp_types
.ids
[r
];
829 *pnum_names
= total_names
;
831 *pname_types
= name_types
;
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
,
844 union samr_DomainInfo
*info
= NULL
;
845 bool got_seq_num
= false;
848 /* query domain info */
849 status
= rpccli_samr_QueryDomainInfo(samr_pipe
,
854 if (NT_STATUS_IS_OK(status
)) {
855 *pseq
= info
->info8
.sequence_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
,
867 if (NT_STATUS_IS_OK(status
)) {
868 *pseq
= info
->general
.sequence_num
;
874 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
875 domain_name
, (unsigned) *pseq
));
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
;
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;
899 struct lsa_DomainList dom_list
;
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
,
913 if (!NT_STATUS_IS_OK(status
)) {
914 if (!NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
920 count
+= dom_list
.count
;
922 array
= talloc_realloc(mem_ctx
,
924 struct netr_DomainTrust
,
927 return NT_STATUS_NO_MEMORY
;
930 for (i
= 0; i
< dom_list
.count
; i
++) {
931 struct netr_DomainTrust
*trust
= &array
[i
];
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
);
942 return NT_STATUS_NO_MEMORY
;
944 sid_copy(sid
, dom_list
.domains
[i
].sid
);
947 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
949 *pnum_trusts
= count
;