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
,
42 struct wbint_userinfo
**pinfo
)
44 struct wbint_userinfo
*info
= NULL
;
45 uint32_t num_info
= 0;
46 uint32_t loop_count
= 0;
47 uint32_t start_idx
= 0;
49 NTSTATUS status
, result
;
50 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
56 uint32_t num_dom_users
;
57 uint32_t max_entries
, max_size
;
58 uint32_t total_size
, returned_size
;
59 union samr_DispInfo disp_info
;
61 dcerpc_get_query_dispinfo_params(loop_count
,
65 status
= dcerpc_samr_QueryDisplayInfo(b
,
76 if (!NT_STATUS_IS_OK(status
)) {
79 if (!NT_STATUS_IS_OK(result
)) {
80 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_info
+= num_dom_users
;
92 info
= talloc_realloc(mem_ctx
,
94 struct wbint_userinfo
,
97 return NT_STATUS_NO_MEMORY
;
100 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
101 uint32_t rid
= disp_info
.info1
.entries
[j
].rid
;
102 struct samr_DispEntryGeneral
*src
;
103 struct wbint_userinfo
*dst
;
105 src
= &(disp_info
.info1
.entries
[j
]);
108 dst
->acct_name
= talloc_strdup(info
,
109 src
->account_name
.string
);
110 if (dst
->acct_name
== NULL
) {
111 return NT_STATUS_NO_MEMORY
;
114 dst
->full_name
= talloc_strdup(info
, src
->full_name
.string
);
115 if ((src
->full_name
.string
!= NULL
) &&
116 (dst
->full_name
== NULL
))
118 return NT_STATUS_NO_MEMORY
;
124 sid_compose(&dst
->user_sid
, domain_sid
, rid
);
126 /* For the moment we set the primary group for
127 every user to be the Domain Users group.
128 There are serious problems with determining
129 the actual primary group for large domains.
130 This should really be made into a 'winbind
131 force group' smb.conf parameter or
132 something like that. */
133 sid_compose(&dst
->group_sid
, domain_sid
,
136 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
138 *pnum_info
= num_info
;
144 /* List all domain groups */
145 NTSTATUS
rpc_enum_dom_groups(TALLOC_CTX
*mem_ctx
,
146 struct rpc_pipe_client
*samr_pipe
,
147 struct policy_handle
*samr_policy
,
149 struct wb_acct_info
**pinfo
)
151 struct wb_acct_info
*info
= NULL
;
153 uint32_t num_info
= 0;
154 NTSTATUS status
, result
;
155 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
160 struct samr_SamArray
*sam_array
= NULL
;
164 /* start is updated by this call. */
165 status
= dcerpc_samr_EnumDomainGroups(b
,
170 0xFFFF, /* buffer size? */
173 if (!NT_STATUS_IS_OK(status
)) {
176 if (!NT_STATUS_IS_OK(result
)) {
177 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
178 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n",
184 info
= talloc_realloc(mem_ctx
,
189 return NT_STATUS_NO_MEMORY
;
192 for (g
= 0; g
< count
; g
++) {
193 fstrcpy(info
[num_info
+ g
].acct_name
,
194 sam_array
->entries
[g
].name
.string
);
196 info
[num_info
+ g
].rid
= sam_array
->entries
[g
].idx
;
200 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
202 *pnum_info
= num_info
;
208 NTSTATUS
rpc_enum_local_groups(TALLOC_CTX
*mem_ctx
,
209 struct rpc_pipe_client
*samr_pipe
,
210 struct policy_handle
*samr_policy
,
212 struct wb_acct_info
**pinfo
)
214 struct wb_acct_info
*info
= NULL
;
215 uint32_t num_info
= 0;
216 NTSTATUS status
, result
;
217 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
222 struct samr_SamArray
*sam_array
= NULL
;
224 uint32_t start
= num_info
;
227 status
= dcerpc_samr_EnumDomainAliases(b
,
232 0xFFFF, /* buffer size? */
235 if (!NT_STATUS_IS_OK(status
)) {
238 if (!NT_STATUS_IS_OK(result
)) {
239 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
244 info
= talloc_realloc(mem_ctx
,
249 return NT_STATUS_NO_MEMORY
;
252 for (g
= 0; g
< count
; g
++) {
253 fstrcpy(info
[num_info
+ g
].acct_name
,
254 sam_array
->entries
[g
].name
.string
);
255 info
[num_info
+ g
].rid
= sam_array
->entries
[g
].idx
;
259 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
261 *pnum_info
= num_info
;
267 /* convert a single name to a sid in a domain */
268 NTSTATUS
rpc_name_to_sid(TALLOC_CTX
*mem_ctx
,
269 struct rpc_pipe_client
*lsa_pipe
,
270 struct policy_handle
*lsa_policy
,
271 const char *domain_name
,
275 enum lsa_SidType
*type
)
277 enum lsa_SidType
*types
= NULL
;
278 struct dom_sid
*sids
= NULL
;
279 char *full_name
= NULL
;
280 const char *names
[1];
281 char *mapped_name
= NULL
;
284 if (name
== NULL
|| name
[0] == '\0') {
285 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
286 } else if (domain_name
== NULL
|| domain_name
[0] == '\0') {
287 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
289 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
292 if (full_name
== NULL
) {
293 return NT_STATUS_NO_MEMORY
;
296 status
= normalize_name_unmap(mem_ctx
, full_name
, &mapped_name
);
297 /* Reset the full_name pointer if we mapped anything */
298 if (NT_STATUS_IS_OK(status
) ||
299 NT_STATUS_EQUAL(status
, NT_STATUS_FILE_RENAMED
)) {
300 full_name
= mapped_name
;
303 DEBUG(3,("name_to_sid: %s for domain %s\n",
304 full_name
? full_name
: "", domain_name
));
306 names
[0] = full_name
;
309 * We don't run into deadlocks here, cause winbind_off() is
310 * called in the main function.
312 status
= rpccli_lsa_lookup_names(lsa_pipe
,
321 if (!NT_STATUS_IS_OK(status
)) {
322 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
327 sid_copy(sid
, &sids
[0]);
333 /* Convert a domain SID to a user or group name */
334 NTSTATUS
rpc_sid_to_name(TALLOC_CTX
*mem_ctx
,
335 struct rpc_pipe_client
*lsa_pipe
,
336 struct policy_handle
*lsa_policy
,
337 struct winbindd_domain
*domain
,
338 const struct dom_sid
*sid
,
341 enum lsa_SidType
*ptype
)
343 char *mapped_name
= NULL
;
344 char **domains
= NULL
;
346 enum lsa_SidType
*types
= NULL
;
350 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
358 if (!NT_STATUS_IS_OK(status
)) {
359 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
364 *ptype
= (enum lsa_SidType
) types
[0];
366 map_status
= normalize_name_map(mem_ctx
,
370 if (NT_STATUS_IS_OK(map_status
) ||
371 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
372 *pname
= talloc_strdup(mem_ctx
, mapped_name
);
373 DEBUG(5,("returning mapped name -- %s\n", *pname
));
375 *pname
= talloc_strdup(mem_ctx
, names
[0]);
377 if ((names
[0] != NULL
) && (*pname
== NULL
)) {
378 return NT_STATUS_NO_MEMORY
;
381 *pdomain_name
= talloc_strdup(mem_ctx
, domains
[0]);
382 if (*pdomain_name
== NULL
) {
383 return NT_STATUS_NO_MEMORY
;
389 /* Convert a bunch of rids to user or group names */
390 NTSTATUS
rpc_rids_to_names(TALLOC_CTX
*mem_ctx
,
391 struct rpc_pipe_client
*lsa_pipe
,
392 struct policy_handle
*lsa_policy
,
393 struct winbindd_domain
*domain
,
394 const struct dom_sid
*sid
,
399 enum lsa_SidType
**ptypes
)
401 enum lsa_SidType
*types
= NULL
;
402 char *domain_name
= NULL
;
403 char **domains
= NULL
;
405 struct dom_sid
*sids
;
410 sids
= talloc_array(mem_ctx
, struct dom_sid
, num_rids
);
412 return NT_STATUS_NO_MEMORY
;
418 for (i
= 0; i
< num_rids
; i
++) {
419 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
420 return NT_STATUS_INTERNAL_ERROR
;
424 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
432 if (!NT_STATUS_IS_OK(status
) &&
433 !NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
434 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
439 for (i
= 0; i
< num_rids
; i
++) {
440 char *mapped_name
= NULL
;
443 if (types
[i
] != SID_NAME_UNKNOWN
) {
444 map_status
= normalize_name_map(mem_ctx
,
448 if (NT_STATUS_IS_OK(map_status
) ||
449 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
450 TALLOC_FREE(names
[i
]);
451 names
[i
] = talloc_strdup(names
, mapped_name
);
452 if (names
[i
] == NULL
) {
453 return NT_STATUS_NO_MEMORY
;
457 domain_name
= domains
[i
];
461 *pdomain_name
= domain_name
;
468 /* Lookup user information from a rid or username. */
469 NTSTATUS
rpc_query_user(TALLOC_CTX
*mem_ctx
,
470 struct rpc_pipe_client
*samr_pipe
,
471 struct policy_handle
*samr_policy
,
472 const struct dom_sid
*domain_sid
,
473 const struct dom_sid
*user_sid
,
474 struct wbint_userinfo
*user_info
)
476 struct policy_handle user_policy
;
477 union samr_UserInfo
*info
= NULL
;
479 NTSTATUS status
, result
;
480 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
482 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
483 return NT_STATUS_UNSUCCESSFUL
;
486 /* Get user handle */
487 status
= dcerpc_samr_OpenUser(b
,
490 SEC_FLAG_MAXIMUM_ALLOWED
,
494 if (!NT_STATUS_IS_OK(status
)) {
497 if (!NT_STATUS_IS_OK(result
)) {
502 status
= dcerpc_samr_QueryUserInfo(b
,
510 dcerpc_samr_Close(b
, mem_ctx
, &user_policy
, &_result
);
512 if (!NT_STATUS_IS_OK(status
)) {
515 if (!NT_STATUS_IS_OK(result
)) {
519 sid_compose(&user_info
->user_sid
, domain_sid
, user_rid
);
520 sid_compose(&user_info
->group_sid
, domain_sid
,
521 info
->info21
.primary_gid
);
523 user_info
->acct_name
= talloc_strdup(user_info
,
524 info
->info21
.account_name
.string
);
525 if (user_info
->acct_name
== NULL
) {
526 return NT_STATUS_NO_MEMORY
;
529 user_info
->full_name
= talloc_strdup(user_info
,
530 info
->info21
.full_name
.string
);
531 if ((info
->info21
.full_name
.string
!= NULL
) &&
532 (user_info
->full_name
== NULL
))
534 return NT_STATUS_NO_MEMORY
;
537 user_info
->homedir
= NULL
;
538 user_info
->shell
= NULL
;
539 user_info
->primary_gid
= (gid_t
)-1;
544 /* Lookup groups a user is a member of. */
545 NTSTATUS
rpc_lookup_usergroups(TALLOC_CTX
*mem_ctx
,
546 struct rpc_pipe_client
*samr_pipe
,
547 struct policy_handle
*samr_policy
,
548 const struct dom_sid
*domain_sid
,
549 const struct dom_sid
*user_sid
,
550 uint32_t *pnum_groups
,
551 struct dom_sid
**puser_grpsids
)
553 struct policy_handle user_policy
;
554 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
555 struct dom_sid
*user_grpsids
= NULL
;
556 uint32_t num_groups
= 0, i
;
558 NTSTATUS status
, result
;
559 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
561 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
562 return NT_STATUS_UNSUCCESSFUL
;
565 /* Get user handle */
566 status
= dcerpc_samr_OpenUser(b
,
569 SEC_FLAG_MAXIMUM_ALLOWED
,
573 if (!NT_STATUS_IS_OK(status
)) {
576 if (!NT_STATUS_IS_OK(result
)) {
580 /* Query user rids */
581 status
= dcerpc_samr_GetGroupsForUser(b
,
588 dcerpc_samr_Close(b
, mem_ctx
, &user_policy
, &_result
);
591 if (!NT_STATUS_IS_OK(status
)) {
594 if (!NT_STATUS_IS_OK(result
)) {
598 num_groups
= rid_array
->count
;
600 user_grpsids
= talloc_array(mem_ctx
, struct dom_sid
, num_groups
);
601 if (user_grpsids
== NULL
) {
602 status
= NT_STATUS_NO_MEMORY
;
606 for (i
= 0; i
< num_groups
; i
++) {
607 sid_compose(&(user_grpsids
[i
]), domain_sid
,
608 rid_array
->rids
[i
].rid
);
611 *pnum_groups
= num_groups
;
613 *puser_grpsids
= user_grpsids
;
618 NTSTATUS
rpc_lookup_useraliases(TALLOC_CTX
*mem_ctx
,
619 struct rpc_pipe_client
*samr_pipe
,
620 struct policy_handle
*samr_policy
,
622 const struct dom_sid
*sids
,
623 uint32_t *pnum_aliases
,
624 uint32_t **palias_rids
)
626 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
627 uint32_t num_query_sids
= 0;
628 uint32_t num_queries
= 1;
629 uint32_t num_aliases
= 0;
630 uint32_t total_sids
= 0;
631 uint32_t *alias_rids
= NULL
;
632 uint32_t rangesize
= MAX_SAM_ENTRIES_W2K
;
634 struct samr_Ids alias_rids_query
;
635 NTSTATUS status
, result
;
636 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
640 struct lsa_SidArray sid_array
;
642 ZERO_STRUCT(sid_array
);
644 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
646 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
647 num_queries
, num_query_sids
));
649 if (num_query_sids
) {
650 sid_array
.sids
= talloc_zero_array(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
651 if (sid_array
.sids
== NULL
) {
652 return NT_STATUS_NO_MEMORY
;
655 sid_array
.sids
= NULL
;
658 for (i
= 0; i
< num_query_sids
; i
++) {
659 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sids
[total_sids
++]);
660 if (sid_array
.sids
[i
].sid
== NULL
) {
661 return NT_STATUS_NO_MEMORY
;
664 sid_array
.num_sids
= num_query_sids
;
667 status
= dcerpc_samr_GetAliasMembership(b
,
673 if (!NT_STATUS_IS_OK(status
)) {
676 if (!NT_STATUS_IS_OK(result
)) {
681 for (i
= 0; i
< alias_rids_query
.count
; i
++) {
682 size_t na
= num_aliases
;
684 if (!add_rid_to_array_unique(mem_ctx
,
685 alias_rids_query
.ids
[i
],
688 return NT_STATUS_NO_MEMORY
;
695 } while (total_sids
< num_sids
);
697 DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
698 "(rangesize: %d)\n", num_aliases
, num_queries
, rangesize
));
700 *pnum_aliases
= num_aliases
;
701 *palias_rids
= alias_rids
;
704 #undef MAX_SAM_ENTRIES_W2K
707 /* Lookup group membership given a rid. */
708 NTSTATUS
rpc_lookup_groupmem(TALLOC_CTX
*mem_ctx
,
709 struct rpc_pipe_client
*samr_pipe
,
710 struct policy_handle
*samr_policy
,
711 const char *domain_name
,
712 const struct dom_sid
*domain_sid
,
713 const struct dom_sid
*group_sid
,
714 enum lsa_SidType type
,
715 uint32_t *pnum_names
,
716 struct dom_sid
**psid_mem
,
718 uint32_t **pname_types
)
720 struct policy_handle group_policy
;
722 uint32_t *rid_mem
= NULL
;
724 uint32_t num_names
= 0;
725 uint32_t total_names
= 0;
726 struct dom_sid
*sid_mem
= NULL
;
728 uint32_t *name_types
= NULL
;
730 struct lsa_Strings tmp_names
;
731 struct samr_Ids tmp_types
;
734 NTSTATUS status
, result
;
735 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
737 if (!sid_peek_check_rid(domain_sid
, group_sid
, &group_rid
)) {
738 return NT_STATUS_UNSUCCESSFUL
;
742 case SID_NAME_DOM_GRP
:
744 struct samr_RidAttrArray
*rids
= NULL
;
746 status
= dcerpc_samr_OpenGroup(b
,
749 SEC_FLAG_MAXIMUM_ALLOWED
,
753 if (!NT_STATUS_IS_OK(status
)) {
756 if (!NT_STATUS_IS_OK(result
)) {
761 * Step #1: Get a list of user rids that are the members of the group.
763 status
= dcerpc_samr_QueryGroupMember(b
,
770 dcerpc_samr_Close(b
, mem_ctx
, &group_policy
, &_result
);
773 if (!NT_STATUS_IS_OK(status
)) {
776 if (!NT_STATUS_IS_OK(result
)) {
781 if (rids
== NULL
|| rids
->count
== 0) {
790 num_names
= rids
->count
;
791 rid_mem
= rids
->rids
;
795 case SID_NAME_WKN_GRP
:
798 struct lsa_SidArray sid_array
;
799 struct lsa_SidPtr sid_ptr
;
800 struct samr_Ids rids_query
;
802 sid_ptr
.sid
= dom_sid_dup(mem_ctx
, group_sid
);
803 if (sid_ptr
.sid
== NULL
) {
804 return NT_STATUS_NO_MEMORY
;
807 sid_array
.num_sids
= 1;
808 sid_array
.sids
= &sid_ptr
;
810 status
= dcerpc_samr_GetAliasMembership(b
,
816 if (!NT_STATUS_IS_OK(status
)) {
819 if (!NT_STATUS_IS_OK(result
)) {
823 if (rids_query
.count
== 0) {
832 num_names
= rids_query
.count
;
833 rid_mem
= rids_query
.ids
;
838 return NT_STATUS_UNSUCCESSFUL
;
842 * Step #2: Convert list of rids into list of usernames.
845 names
= talloc_zero_array(mem_ctx
, char *, num_names
);
846 name_types
= talloc_zero_array(mem_ctx
, uint32_t, num_names
);
847 sid_mem
= talloc_zero_array(mem_ctx
, struct dom_sid
, num_names
);
848 if (names
== NULL
|| name_types
== NULL
|| sid_mem
== NULL
) {
849 return NT_STATUS_NO_MEMORY
;
853 for (j
= 0; j
< num_names
; j
++) {
854 sid_compose(&sid_mem
[j
], domain_sid
, rid_mem
[j
]);
857 status
= dcerpc_samr_LookupRids(b
,
865 if (!NT_STATUS_IS_OK(status
)) {
869 if (!NT_STATUS_IS_OK(result
)) {
870 if (!NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
875 /* Copy result into array. The talloc system will take
876 care of freeing the temporary arrays later on. */
877 if (tmp_names
.count
!= num_names
) {
878 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
880 if (tmp_types
.count
!= num_names
) {
881 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
884 for (r
= 0; r
< tmp_names
.count
; r
++) {
885 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
888 if (total_names
>= num_names
) {
891 names
[total_names
] = fill_domain_username_talloc(names
,
893 tmp_names
.names
[r
].string
,
895 if (names
[total_names
] == NULL
) {
896 return NT_STATUS_NO_MEMORY
;
898 name_types
[total_names
] = tmp_types
.ids
[r
];
902 *pnum_names
= total_names
;
904 *pname_types
= name_types
;
910 /* Find the sequence number for a domain */
911 NTSTATUS
rpc_sequence_number(TALLOC_CTX
*mem_ctx
,
912 struct rpc_pipe_client
*samr_pipe
,
913 struct policy_handle
*samr_policy
,
914 const char *domain_name
,
917 union samr_DomainInfo
*info
= NULL
;
918 bool got_seq_num
= false;
919 NTSTATUS status
, result
;
920 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
922 /* query domain info */
923 status
= dcerpc_samr_QueryDomainInfo(b
,
929 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
930 *pseq
= info
->info8
.sequence_num
;
935 /* retry with info-level 2 in case the dc does not support info-level 8
936 * (like all older samba2 and samba3 dc's) - Guenther */
937 status
= dcerpc_samr_QueryDomainInfo(b
,
943 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
944 *pseq
= info
->general
.sequence_num
;
949 if (!NT_STATUS_IS_OK(status
)) {
957 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
958 domain_name
, (unsigned) *pseq
));
960 DEBUG(10,("domain_sequence_number: failed to get sequence "
961 "number (%u) for domain %s\n",
962 (unsigned) *pseq
, domain_name
));
963 status
= NT_STATUS_OK
;
969 /* Get a list of trusted domains */
970 NTSTATUS
rpc_trusted_domains(TALLOC_CTX
*mem_ctx
,
971 struct rpc_pipe_client
*lsa_pipe
,
972 struct policy_handle
*lsa_policy
,
973 uint32_t *pnum_trusts
,
974 struct netr_DomainTrust
**ptrusts
)
976 struct netr_DomainTrust
*array
= NULL
;
977 uint32_t enum_ctx
= 0;
979 NTSTATUS status
, result
;
980 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
983 struct lsa_DomainList dom_list
;
984 struct lsa_DomainListEx dom_list_ex
;
989 * We don't run into deadlocks here, cause winbind_off() is
990 * called in the main function.
992 status
= dcerpc_lsa_EnumTrustedDomainsEx(b
,
999 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_ERR(result
) &&
1000 dom_list_ex
.count
> 0) {
1001 count
+= dom_list_ex
.count
;
1004 status
= dcerpc_lsa_EnumTrustDom(b
,
1011 if (!NT_STATUS_IS_OK(status
)) {
1014 if (!NT_STATUS_IS_OK(result
)) {
1015 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1020 count
+= dom_list
.count
;
1023 array
= talloc_realloc(mem_ctx
,
1025 struct netr_DomainTrust
,
1027 if (array
== NULL
) {
1028 return NT_STATUS_NO_MEMORY
;
1031 for (i
= 0; i
< count
; i
++) {
1032 struct netr_DomainTrust
*trust
= &array
[i
];
1033 struct dom_sid
*sid
;
1035 ZERO_STRUCTP(trust
);
1037 sid
= talloc(array
, struct dom_sid
);
1039 return NT_STATUS_NO_MEMORY
;
1043 trust
->netbios_name
= talloc_move(array
,
1044 &dom_list_ex
.domains
[i
].netbios_name
.string
);
1045 trust
->dns_name
= talloc_move(array
,
1046 &dom_list_ex
.domains
[i
].domain_name
.string
);
1047 if (dom_list_ex
.domains
[i
].sid
== NULL
) {
1048 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust
->dns_name
));
1049 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1051 sid_copy(sid
, dom_list_ex
.domains
[i
].sid
);
1053 trust
->netbios_name
= talloc_move(array
,
1054 &dom_list
.domains
[i
].name
.string
);
1055 trust
->dns_name
= NULL
;
1057 if (dom_list
.domains
[i
].sid
== NULL
) {
1058 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust
->netbios_name
));
1059 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1062 sid_copy(sid
, dom_list
.domains
[i
].sid
);
1067 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1069 *pnum_trusts
= count
;
1072 return NT_STATUS_OK
;
1075 static NTSTATUS
rpc_try_lookup_sids3(TALLOC_CTX
*mem_ctx
,
1076 struct winbindd_domain
*domain
,
1077 struct rpc_pipe_client
*cli
,
1078 struct lsa_SidArray
*sids
,
1079 struct lsa_RefDomainList
**pdomains
,
1080 struct lsa_TransNameArray
**pnames
)
1082 struct lsa_TransNameArray2 lsa_names2
;
1083 struct lsa_TransNameArray
*names
= *pnames
;
1085 NTSTATUS status
, result
;
1087 ZERO_STRUCT(lsa_names2
);
1088 status
= dcerpc_lsa_LookupSids3(cli
->binding_handle
,
1093 LSA_LOOKUP_NAMES_ALL
,
1095 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
,
1096 LSA_CLIENT_REVISION_2
,
1098 if (!NT_STATUS_IS_OK(status
)) {
1101 if (NT_STATUS_IS_ERR(result
)) {
1104 if (sids
->num_sids
!= lsa_names2
.count
) {
1105 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1108 names
->count
= lsa_names2
.count
;
1109 names
->names
= talloc_array(names
, struct lsa_TranslatedName
,
1111 if (names
->names
== NULL
) {
1112 return NT_STATUS_NO_MEMORY
;
1114 for (i
=0; i
<names
->count
; i
++) {
1115 names
->names
[i
].sid_type
= lsa_names2
.names
[i
].sid_type
;
1116 names
->names
[i
].name
.string
= talloc_move(
1117 names
->names
, &lsa_names2
.names
[i
].name
.string
);
1118 names
->names
[i
].sid_index
= lsa_names2
.names
[i
].sid_index
;
1120 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
1123 if ((*pdomains
) == NULL
) {
1124 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1126 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
1127 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1133 NTSTATUS
rpc_lookup_sids(TALLOC_CTX
*mem_ctx
,
1134 struct winbindd_domain
*domain
,
1135 struct lsa_SidArray
*sids
,
1136 struct lsa_RefDomainList
**pdomains
,
1137 struct lsa_TransNameArray
**pnames
)
1139 struct lsa_TransNameArray
*names
= *pnames
;
1140 struct rpc_pipe_client
*cli
= NULL
;
1141 struct policy_handle lsa_policy
;
1144 NTSTATUS status
, result
;
1146 status
= cm_connect_lsat(domain
, mem_ctx
, &cli
, &lsa_policy
);
1147 if (!NT_STATUS_IS_OK(status
)) {
1151 if (cli
->transport
->transport
== NCACN_IP_TCP
) {
1152 return rpc_try_lookup_sids3(mem_ctx
, domain
, cli
, sids
,
1156 status
= dcerpc_lsa_LookupSids(cli
->binding_handle
, mem_ctx
,
1157 &lsa_policy
, sids
, pdomains
,
1158 names
, LSA_LOOKUP_NAMES_ALL
,
1160 if (!NT_STATUS_IS_OK(status
)) {
1163 if (NT_STATUS_IS_ERR(result
)) {
1167 if (sids
->num_sids
!= names
->count
) {
1168 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1171 for (i
=0; i
< names
->count
; i
++) {
1172 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
1175 if ((*pdomains
) == NULL
) {
1176 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1178 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
1179 return NT_STATUS_INVALID_NETWORK_RESPONSE
;