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"
29 #include "rpc_client/rpc_client.h"
30 #include "librpc/gen_ndr/ndr_samr_c.h"
31 #include "librpc/gen_ndr/ndr_lsa_c.h"
32 #include "rpc_client/cli_samr.h"
33 #include "rpc_client/cli_lsarpc.h"
34 #include "../libcli/security/security.h"
36 /* Query display info for a domain */
37 NTSTATUS
rpc_query_user_list(TALLOC_CTX
*mem_ctx
,
38 struct rpc_pipe_client
*samr_pipe
,
39 struct policy_handle
*samr_policy
,
40 const struct dom_sid
*domain_sid
,
43 uint32_t *rids
= NULL
;
44 uint32_t num_rids
= 0;
45 uint32_t loop_count
= 0;
46 uint32_t start_idx
= 0;
48 NTSTATUS status
, result
;
49 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
55 uint32_t num_dom_users
;
56 uint32_t max_entries
, max_size
;
57 uint32_t total_size
, returned_size
;
58 union samr_DispInfo disp_info
;
60 dcerpc_get_query_dispinfo_params(loop_count
,
64 status
= dcerpc_samr_QueryDisplayInfo(b
,
75 if (!NT_STATUS_IS_OK(status
)) {
78 if (!NT_STATUS_IS_OK(result
)) {
79 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
85 /* increment required start query values */
86 start_idx
+= disp_info
.info1
.count
;
88 num_dom_users
= disp_info
.info1
.count
;
90 num_rids
+= num_dom_users
;
91 /* If there are no user to enumerate we're done */
96 rids
= talloc_realloc(mem_ctx
, rids
, uint32_t, num_rids
);
98 return NT_STATUS_NO_MEMORY
;
101 for (j
= 0; j
< num_dom_users
; j
++) {
102 rids
[i
++] = disp_info
.info1
.entries
[j
].rid
;
104 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
111 /* List all domain groups */
112 NTSTATUS
rpc_enum_dom_groups(TALLOC_CTX
*mem_ctx
,
113 struct rpc_pipe_client
*samr_pipe
,
114 struct policy_handle
*samr_policy
,
116 struct wb_acct_info
**pinfo
)
118 struct wb_acct_info
*info
= NULL
;
120 uint32_t num_info
= 0;
121 NTSTATUS status
, result
;
122 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
127 struct samr_SamArray
*sam_array
= NULL
;
131 /* start is updated by this call. */
132 status
= dcerpc_samr_EnumDomainGroups(b
,
137 0xFFFF, /* buffer size? */
140 if (!NT_STATUS_IS_OK(status
)) {
143 if (!NT_STATUS_IS_OK(result
)) {
144 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
145 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
151 info
= talloc_realloc(mem_ctx
,
156 return NT_STATUS_NO_MEMORY
;
159 for (g
= 0; g
< count
; g
++) {
160 struct wb_acct_info
*i
= &info
[num_info
+ g
];
162 fstrcpy(i
->acct_name
,
163 sam_array
->entries
[g
].name
.string
);
164 fstrcpy(i
->acct_desc
, "");
165 i
->rid
= sam_array
->entries
[g
].idx
;
169 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
171 *pnum_info
= num_info
;
177 NTSTATUS
rpc_enum_local_groups(TALLOC_CTX
*mem_ctx
,
178 struct rpc_pipe_client
*samr_pipe
,
179 struct policy_handle
*samr_policy
,
181 struct wb_acct_info
**pinfo
)
183 struct wb_acct_info
*info
= NULL
;
184 uint32_t num_info
= 0;
185 NTSTATUS status
, result
;
186 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
191 struct samr_SamArray
*sam_array
= NULL
;
193 uint32_t start
= num_info
;
196 status
= dcerpc_samr_EnumDomainAliases(b
,
201 0xFFFF, /* buffer size? */
204 if (!NT_STATUS_IS_OK(status
)) {
207 if (!NT_STATUS_IS_OK(result
)) {
208 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
213 info
= talloc_realloc(mem_ctx
,
218 return NT_STATUS_NO_MEMORY
;
221 for (g
= 0; g
< count
; g
++) {
222 struct wb_acct_info
*i
= &info
[num_info
+ g
];
224 fstrcpy(i
->acct_name
,
225 sam_array
->entries
[g
].name
.string
);
226 fstrcpy(i
->acct_desc
, "");
227 i
->rid
= sam_array
->entries
[g
].idx
;
231 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
233 *pnum_info
= num_info
;
239 /* convert a single name to a sid in a domain */
240 NTSTATUS
rpc_name_to_sid(TALLOC_CTX
*mem_ctx
,
241 struct rpc_pipe_client
*lsa_pipe
,
242 struct policy_handle
*lsa_policy
,
243 const char *domain_name
,
247 enum lsa_SidType
*type
)
249 enum lsa_SidType
*types
= NULL
;
250 struct dom_sid
*sids
= NULL
;
251 char *full_name
= NULL
;
252 const char *names
[1];
253 char *mapped_name
= NULL
;
256 if (name
== NULL
|| name
[0] == '\0') {
257 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
258 } else if (domain_name
== NULL
|| domain_name
[0] == '\0') {
259 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
261 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
264 if (full_name
== NULL
) {
265 return NT_STATUS_NO_MEMORY
;
268 status
= normalize_name_unmap(mem_ctx
, full_name
, &mapped_name
);
269 /* Reset the full_name pointer if we mapped anything */
270 if (NT_STATUS_IS_OK(status
) ||
271 NT_STATUS_EQUAL(status
, NT_STATUS_FILE_RENAMED
)) {
272 full_name
= mapped_name
;
275 DEBUG(3,("name_to_sid: %s for domain %s\n",
276 full_name
? full_name
: "", domain_name
));
278 names
[0] = full_name
;
281 * We don't run into deadlocks here, cause winbind_off() is
282 * called in the main function.
284 status
= rpccli_lsa_lookup_names(lsa_pipe
,
293 if (!NT_STATUS_IS_OK(status
)) {
294 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
299 sid_copy(sid
, &sids
[0]);
305 /* Convert a domain SID to a user or group name */
306 NTSTATUS
rpc_sid_to_name(TALLOC_CTX
*mem_ctx
,
307 struct rpc_pipe_client
*lsa_pipe
,
308 struct policy_handle
*lsa_policy
,
309 struct winbindd_domain
*domain
,
310 const struct dom_sid
*sid
,
313 enum lsa_SidType
*ptype
)
315 char *mapped_name
= NULL
;
316 char **domains
= NULL
;
318 enum lsa_SidType
*types
= NULL
;
322 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
330 if (!NT_STATUS_IS_OK(status
)) {
331 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
336 *ptype
= (enum lsa_SidType
) types
[0];
338 map_status
= normalize_name_map(mem_ctx
,
342 if (NT_STATUS_IS_OK(map_status
) ||
343 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
344 *pname
= talloc_strdup(mem_ctx
, mapped_name
);
345 DEBUG(5,("returning mapped name -- %s\n", *pname
));
347 *pname
= talloc_strdup(mem_ctx
, names
[0]);
349 if ((names
[0] != NULL
) && (*pname
== NULL
)) {
350 return NT_STATUS_NO_MEMORY
;
353 *pdomain_name
= talloc_strdup(mem_ctx
, domains
[0]);
354 if (*pdomain_name
== NULL
) {
355 return NT_STATUS_NO_MEMORY
;
361 /* Convert a bunch of rids to user or group names */
362 NTSTATUS
rpc_rids_to_names(TALLOC_CTX
*mem_ctx
,
363 struct rpc_pipe_client
*lsa_pipe
,
364 struct policy_handle
*lsa_policy
,
365 struct winbindd_domain
*domain
,
366 const struct dom_sid
*sid
,
371 enum lsa_SidType
**ptypes
)
373 enum lsa_SidType
*types
= NULL
;
374 char *domain_name
= NULL
;
375 char **domains
= NULL
;
377 struct dom_sid
*sids
;
382 sids
= talloc_array(mem_ctx
, struct dom_sid
, num_rids
);
384 return NT_STATUS_NO_MEMORY
;
390 for (i
= 0; i
< num_rids
; i
++) {
391 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
392 return NT_STATUS_INTERNAL_ERROR
;
396 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
404 if (!NT_STATUS_IS_OK(status
) &&
405 !NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
406 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
411 for (i
= 0; i
< num_rids
; i
++) {
412 char *mapped_name
= NULL
;
415 if (types
[i
] != SID_NAME_UNKNOWN
) {
416 map_status
= normalize_name_map(mem_ctx
,
420 if (NT_STATUS_IS_OK(map_status
) ||
421 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
422 TALLOC_FREE(names
[i
]);
423 names
[i
] = talloc_strdup(names
, mapped_name
);
424 if (names
[i
] == NULL
) {
425 return NT_STATUS_NO_MEMORY
;
429 domain_name
= domains
[i
];
433 *pdomain_name
= domain_name
;
440 NTSTATUS
rpc_lookup_useraliases(TALLOC_CTX
*mem_ctx
,
441 struct rpc_pipe_client
*samr_pipe
,
442 struct policy_handle
*samr_policy
,
444 const struct dom_sid
*sids
,
445 uint32_t *pnum_aliases
,
446 uint32_t **palias_rids
)
448 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
449 uint32_t num_query_sids
= 0;
450 uint32_t num_queries
= 1;
451 uint32_t num_aliases
= 0;
452 uint32_t total_sids
= 0;
453 uint32_t *alias_rids
= NULL
;
454 uint32_t rangesize
= MAX_SAM_ENTRIES_W2K
;
456 struct samr_Ids alias_rids_query
;
457 NTSTATUS status
, result
;
458 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
462 struct lsa_SidArray sid_array
;
464 ZERO_STRUCT(sid_array
);
466 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
468 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
469 num_queries
, num_query_sids
));
471 if (num_query_sids
) {
472 sid_array
.sids
= talloc_zero_array(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
473 if (sid_array
.sids
== NULL
) {
474 return NT_STATUS_NO_MEMORY
;
477 sid_array
.sids
= NULL
;
480 for (i
= 0; i
< num_query_sids
; i
++) {
481 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sids
[total_sids
++]);
482 if (sid_array
.sids
[i
].sid
== NULL
) {
483 return NT_STATUS_NO_MEMORY
;
486 sid_array
.num_sids
= num_query_sids
;
489 status
= dcerpc_samr_GetAliasMembership(b
,
495 if (!NT_STATUS_IS_OK(status
)) {
498 if (!NT_STATUS_IS_OK(result
)) {
503 for (i
= 0; i
< alias_rids_query
.count
; i
++) {
504 size_t na
= num_aliases
;
506 if (!add_rid_to_array_unique(mem_ctx
,
507 alias_rids_query
.ids
[i
],
510 return NT_STATUS_NO_MEMORY
;
517 } while (total_sids
< num_sids
);
519 DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
520 "(rangesize: %d)\n", num_aliases
, num_queries
, rangesize
));
522 *pnum_aliases
= num_aliases
;
523 *palias_rids
= alias_rids
;
526 #undef MAX_SAM_ENTRIES_W2K
529 /* Lookup group membership given a rid. */
530 NTSTATUS
rpc_lookup_groupmem(TALLOC_CTX
*mem_ctx
,
531 struct rpc_pipe_client
*samr_pipe
,
532 struct policy_handle
*samr_policy
,
533 const char *domain_name
,
534 const struct dom_sid
*domain_sid
,
535 const struct dom_sid
*group_sid
,
536 enum lsa_SidType type
,
537 uint32_t *pnum_names
,
538 struct dom_sid
**psid_mem
,
540 uint32_t **pname_types
)
542 struct policy_handle group_policy
;
544 uint32_t *rid_mem
= NULL
;
546 uint32_t num_names
= 0;
547 uint32_t total_names
= 0;
548 struct dom_sid
*sid_mem
= NULL
;
550 uint32_t *name_types
= NULL
;
552 struct lsa_Strings tmp_names
;
553 struct samr_Ids tmp_types
;
556 NTSTATUS status
, result
;
557 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
559 if (!sid_peek_check_rid(domain_sid
, group_sid
, &group_rid
)) {
560 return NT_STATUS_UNSUCCESSFUL
;
564 case SID_NAME_DOM_GRP
:
566 struct samr_RidAttrArray
*rids
= NULL
;
568 status
= dcerpc_samr_OpenGroup(b
,
571 SEC_FLAG_MAXIMUM_ALLOWED
,
575 if (!NT_STATUS_IS_OK(status
)) {
578 if (!NT_STATUS_IS_OK(result
)) {
583 * Step #1: Get a list of user rids that are the members of the group.
585 status
= dcerpc_samr_QueryGroupMember(b
,
592 dcerpc_samr_Close(b
, mem_ctx
, &group_policy
, &_result
);
595 if (!NT_STATUS_IS_OK(status
)) {
598 if (!NT_STATUS_IS_OK(result
)) {
603 if (rids
== NULL
|| rids
->count
== 0) {
612 num_names
= rids
->count
;
613 rid_mem
= rids
->rids
;
617 case SID_NAME_WKN_GRP
:
620 struct lsa_SidArray sid_array
;
621 struct lsa_SidPtr sid_ptr
;
622 struct samr_Ids rids_query
;
624 sid_ptr
.sid
= dom_sid_dup(mem_ctx
, group_sid
);
625 if (sid_ptr
.sid
== NULL
) {
626 return NT_STATUS_NO_MEMORY
;
629 sid_array
.num_sids
= 1;
630 sid_array
.sids
= &sid_ptr
;
632 status
= dcerpc_samr_GetAliasMembership(b
,
638 if (!NT_STATUS_IS_OK(status
)) {
641 if (!NT_STATUS_IS_OK(result
)) {
645 if (rids_query
.count
== 0) {
654 num_names
= rids_query
.count
;
655 rid_mem
= rids_query
.ids
;
660 return NT_STATUS_UNSUCCESSFUL
;
664 * Step #2: Convert list of rids into list of usernames.
667 names
= talloc_zero_array(mem_ctx
, char *, num_names
);
668 name_types
= talloc_zero_array(mem_ctx
, uint32_t, num_names
);
669 sid_mem
= talloc_zero_array(mem_ctx
, struct dom_sid
, num_names
);
670 if (names
== NULL
|| name_types
== NULL
|| sid_mem
== NULL
) {
671 return NT_STATUS_NO_MEMORY
;
675 for (j
= 0; j
< num_names
; j
++) {
676 sid_compose(&sid_mem
[j
], domain_sid
, rid_mem
[j
]);
679 status
= dcerpc_samr_LookupRids(b
,
687 if (!NT_STATUS_IS_OK(status
)) {
691 if (!NT_STATUS_IS_OK(result
)) {
692 if (!NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
697 /* Copy result into array. The talloc system will take
698 care of freeing the temporary arrays later on. */
699 if (tmp_names
.count
!= num_names
) {
700 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
702 if (tmp_types
.count
!= num_names
) {
703 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
706 for (r
= 0; r
< tmp_names
.count
; r
++) {
707 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
710 if (total_names
>= num_names
) {
713 names
[total_names
] = fill_domain_username_talloc(names
,
715 tmp_names
.names
[r
].string
,
717 if (names
[total_names
] == NULL
) {
718 return NT_STATUS_NO_MEMORY
;
720 name_types
[total_names
] = tmp_types
.ids
[r
];
724 *pnum_names
= total_names
;
726 *pname_types
= name_types
;
732 /* Find the sequence number for a domain */
733 NTSTATUS
rpc_sequence_number(TALLOC_CTX
*mem_ctx
,
734 struct rpc_pipe_client
*samr_pipe
,
735 struct policy_handle
*samr_policy
,
736 const char *domain_name
,
739 union samr_DomainInfo
*info
= NULL
;
740 bool got_seq_num
= false;
741 NTSTATUS status
, result
;
742 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
744 /* query domain info */
745 status
= dcerpc_samr_QueryDomainInfo(b
,
751 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
752 *pseq
= info
->info8
.sequence_num
;
757 /* retry with info-level 2 in case the dc does not support info-level 8
758 * (like all older samba2 and samba3 dc's) - Guenther */
759 status
= dcerpc_samr_QueryDomainInfo(b
,
765 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
766 *pseq
= info
->general
.sequence_num
;
771 if (!NT_STATUS_IS_OK(status
)) {
779 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
780 domain_name
, (unsigned) *pseq
));
782 DEBUG(10,("domain_sequence_number: failed to get sequence "
783 "number (%u) for domain %s\n",
784 (unsigned) *pseq
, domain_name
));
785 status
= NT_STATUS_OK
;
791 /* Get a list of trusted domains */
792 NTSTATUS
rpc_trusted_domains(TALLOC_CTX
*mem_ctx
,
793 struct rpc_pipe_client
*lsa_pipe
,
794 struct policy_handle
*lsa_policy
,
795 uint32_t *pnum_trusts
,
796 struct netr_DomainTrust
**ptrusts
)
798 struct netr_DomainTrust
*array
= NULL
;
799 uint32_t enum_ctx
= 0;
801 NTSTATUS status
, result
;
802 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
805 struct lsa_DomainList dom_list
;
806 struct lsa_DomainListEx dom_list_ex
;
811 * We don't run into deadlocks here, cause winbind_off() is
812 * called in the main function.
814 status
= dcerpc_lsa_EnumTrustedDomainsEx(b
,
821 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_ERR(result
) &&
822 dom_list_ex
.count
> 0) {
823 count
+= dom_list_ex
.count
;
826 status
= dcerpc_lsa_EnumTrustDom(b
,
833 if (!NT_STATUS_IS_OK(status
)) {
836 if (!NT_STATUS_IS_OK(result
)) {
837 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
842 count
+= dom_list
.count
;
845 array
= talloc_realloc(mem_ctx
,
847 struct netr_DomainTrust
,
850 return NT_STATUS_NO_MEMORY
;
853 for (i
= 0; i
< count
; i
++) {
854 struct netr_DomainTrust
*trust
= &array
[i
];
859 sid
= talloc(array
, struct dom_sid
);
861 return NT_STATUS_NO_MEMORY
;
865 trust
->netbios_name
= talloc_move(array
,
866 &dom_list_ex
.domains
[i
].netbios_name
.string
);
867 trust
->dns_name
= talloc_move(array
,
868 &dom_list_ex
.domains
[i
].domain_name
.string
);
869 if (dom_list_ex
.domains
[i
].sid
== NULL
) {
870 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust
->dns_name
));
871 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
873 sid_copy(sid
, dom_list_ex
.domains
[i
].sid
);
875 trust
->netbios_name
= talloc_move(array
,
876 &dom_list
.domains
[i
].name
.string
);
877 trust
->dns_name
= NULL
;
879 if (dom_list
.domains
[i
].sid
== NULL
) {
880 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust
->netbios_name
));
881 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
884 sid_copy(sid
, dom_list
.domains
[i
].sid
);
889 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
891 *pnum_trusts
= count
;
897 static NTSTATUS
rpc_try_lookup_sids3(TALLOC_CTX
*mem_ctx
,
898 struct winbindd_domain
*domain
,
899 struct rpc_pipe_client
*cli
,
900 struct lsa_SidArray
*sids
,
901 struct lsa_RefDomainList
**pdomains
,
902 struct lsa_TransNameArray
**pnames
)
904 struct lsa_TransNameArray2 lsa_names2
;
905 struct lsa_TransNameArray
*names
= *pnames
;
906 uint32_t i
, count
= 0;
907 NTSTATUS status
, result
;
909 ZERO_STRUCT(lsa_names2
);
910 status
= dcerpc_lsa_LookupSids3(cli
->binding_handle
,
915 LSA_LOOKUP_NAMES_ALL
,
917 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
,
918 LSA_CLIENT_REVISION_2
,
920 if (!NT_STATUS_IS_OK(status
)) {
923 if (NT_STATUS_IS_ERR(result
)) {
926 if (sids
->num_sids
!= lsa_names2
.count
) {
927 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
930 names
->count
= lsa_names2
.count
;
931 names
->names
= talloc_array(names
, struct lsa_TranslatedName
,
933 if (names
->names
== NULL
) {
934 return NT_STATUS_NO_MEMORY
;
936 for (i
=0; i
<names
->count
; i
++) {
937 names
->names
[i
].sid_type
= lsa_names2
.names
[i
].sid_type
;
938 names
->names
[i
].name
.string
= talloc_move(
939 names
->names
, &lsa_names2
.names
[i
].name
.string
);
940 names
->names
[i
].sid_index
= lsa_names2
.names
[i
].sid_index
;
942 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
945 if ((*pdomains
) == NULL
) {
946 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
948 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
949 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
955 NTSTATUS
rpc_lookup_sids(TALLOC_CTX
*mem_ctx
,
956 struct winbindd_domain
*domain
,
957 struct lsa_SidArray
*sids
,
958 struct lsa_RefDomainList
**pdomains
,
959 struct lsa_TransNameArray
**pnames
)
961 struct lsa_TransNameArray
*names
= *pnames
;
962 struct rpc_pipe_client
*cli
= NULL
;
963 struct policy_handle lsa_policy
;
966 NTSTATUS status
, result
;
968 status
= cm_connect_lsat(domain
, mem_ctx
, &cli
, &lsa_policy
);
969 if (!NT_STATUS_IS_OK(status
)) {
973 if (cli
->transport
->transport
== NCACN_IP_TCP
) {
974 return rpc_try_lookup_sids3(mem_ctx
, domain
, cli
, sids
,
978 status
= dcerpc_lsa_LookupSids(cli
->binding_handle
, mem_ctx
,
979 &lsa_policy
, sids
, pdomains
,
980 names
, LSA_LOOKUP_NAMES_ALL
,
982 if (!NT_STATUS_IS_OK(status
)) {
985 if (NT_STATUS_IS_ERR(result
)) {
989 if (sids
->num_sids
!= names
->count
) {
990 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
993 for (i
=0; i
< names
->count
; i
++) {
994 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
997 if ((*pdomains
) == NULL
) {
998 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1000 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
1001 return NT_STATUS_INVALID_NETWORK_RESPONSE
;