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
;
123 dst
->primary_gid
= (gid_t
)-1;
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 struct wb_acct_info
*i
= &info
[num_info
+ g
];
195 fstrcpy(i
->acct_name
,
196 sam_array
->entries
[g
].name
.string
);
197 fstrcpy(i
->acct_desc
, "");
198 i
->rid
= sam_array
->entries
[g
].idx
;
202 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
204 *pnum_info
= num_info
;
210 NTSTATUS
rpc_enum_local_groups(TALLOC_CTX
*mem_ctx
,
211 struct rpc_pipe_client
*samr_pipe
,
212 struct policy_handle
*samr_policy
,
214 struct wb_acct_info
**pinfo
)
216 struct wb_acct_info
*info
= NULL
;
217 uint32_t num_info
= 0;
218 NTSTATUS status
, result
;
219 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
224 struct samr_SamArray
*sam_array
= NULL
;
226 uint32_t start
= num_info
;
229 status
= dcerpc_samr_EnumDomainAliases(b
,
234 0xFFFF, /* buffer size? */
237 if (!NT_STATUS_IS_OK(status
)) {
240 if (!NT_STATUS_IS_OK(result
)) {
241 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
246 info
= talloc_realloc(mem_ctx
,
251 return NT_STATUS_NO_MEMORY
;
254 for (g
= 0; g
< count
; g
++) {
255 struct wb_acct_info
*i
= &info
[num_info
+ g
];
257 fstrcpy(i
->acct_name
,
258 sam_array
->entries
[g
].name
.string
);
259 fstrcpy(i
->acct_desc
, "");
260 i
->rid
= sam_array
->entries
[g
].idx
;
264 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
266 *pnum_info
= num_info
;
272 /* convert a single name to a sid in a domain */
273 NTSTATUS
rpc_name_to_sid(TALLOC_CTX
*mem_ctx
,
274 struct rpc_pipe_client
*lsa_pipe
,
275 struct policy_handle
*lsa_policy
,
276 const char *domain_name
,
280 enum lsa_SidType
*type
)
282 enum lsa_SidType
*types
= NULL
;
283 struct dom_sid
*sids
= NULL
;
284 char *full_name
= NULL
;
285 const char *names
[1];
286 char *mapped_name
= NULL
;
289 if (name
== NULL
|| name
[0] == '\0') {
290 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
291 } else if (domain_name
== NULL
|| domain_name
[0] == '\0') {
292 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
294 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
297 if (full_name
== NULL
) {
298 return NT_STATUS_NO_MEMORY
;
301 status
= normalize_name_unmap(mem_ctx
, full_name
, &mapped_name
);
302 /* Reset the full_name pointer if we mapped anything */
303 if (NT_STATUS_IS_OK(status
) ||
304 NT_STATUS_EQUAL(status
, NT_STATUS_FILE_RENAMED
)) {
305 full_name
= mapped_name
;
308 DEBUG(3,("name_to_sid: %s for domain %s\n",
309 full_name
? full_name
: "", domain_name
));
311 names
[0] = full_name
;
314 * We don't run into deadlocks here, cause winbind_off() is
315 * called in the main function.
317 status
= rpccli_lsa_lookup_names(lsa_pipe
,
326 if (!NT_STATUS_IS_OK(status
)) {
327 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
332 sid_copy(sid
, &sids
[0]);
338 /* Convert a domain SID to a user or group name */
339 NTSTATUS
rpc_sid_to_name(TALLOC_CTX
*mem_ctx
,
340 struct rpc_pipe_client
*lsa_pipe
,
341 struct policy_handle
*lsa_policy
,
342 struct winbindd_domain
*domain
,
343 const struct dom_sid
*sid
,
346 enum lsa_SidType
*ptype
)
348 char *mapped_name
= NULL
;
349 char **domains
= NULL
;
351 enum lsa_SidType
*types
= NULL
;
355 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
363 if (!NT_STATUS_IS_OK(status
)) {
364 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
369 *ptype
= (enum lsa_SidType
) types
[0];
371 map_status
= normalize_name_map(mem_ctx
,
375 if (NT_STATUS_IS_OK(map_status
) ||
376 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
377 *pname
= talloc_strdup(mem_ctx
, mapped_name
);
378 DEBUG(5,("returning mapped name -- %s\n", *pname
));
380 *pname
= talloc_strdup(mem_ctx
, names
[0]);
382 if ((names
[0] != NULL
) && (*pname
== NULL
)) {
383 return NT_STATUS_NO_MEMORY
;
386 *pdomain_name
= talloc_strdup(mem_ctx
, domains
[0]);
387 if (*pdomain_name
== NULL
) {
388 return NT_STATUS_NO_MEMORY
;
394 /* Convert a bunch of rids to user or group names */
395 NTSTATUS
rpc_rids_to_names(TALLOC_CTX
*mem_ctx
,
396 struct rpc_pipe_client
*lsa_pipe
,
397 struct policy_handle
*lsa_policy
,
398 struct winbindd_domain
*domain
,
399 const struct dom_sid
*sid
,
404 enum lsa_SidType
**ptypes
)
406 enum lsa_SidType
*types
= NULL
;
407 char *domain_name
= NULL
;
408 char **domains
= NULL
;
410 struct dom_sid
*sids
;
415 sids
= talloc_array(mem_ctx
, struct dom_sid
, num_rids
);
417 return NT_STATUS_NO_MEMORY
;
423 for (i
= 0; i
< num_rids
; i
++) {
424 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
425 return NT_STATUS_INTERNAL_ERROR
;
429 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
437 if (!NT_STATUS_IS_OK(status
) &&
438 !NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
439 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
444 for (i
= 0; i
< num_rids
; i
++) {
445 char *mapped_name
= NULL
;
448 if (types
[i
] != SID_NAME_UNKNOWN
) {
449 map_status
= normalize_name_map(mem_ctx
,
453 if (NT_STATUS_IS_OK(map_status
) ||
454 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
455 TALLOC_FREE(names
[i
]);
456 names
[i
] = talloc_strdup(names
, mapped_name
);
457 if (names
[i
] == NULL
) {
458 return NT_STATUS_NO_MEMORY
;
462 domain_name
= domains
[i
];
466 *pdomain_name
= domain_name
;
473 /* Lookup user information from a rid or username. */
474 NTSTATUS
rpc_query_user(TALLOC_CTX
*mem_ctx
,
475 struct rpc_pipe_client
*samr_pipe
,
476 struct policy_handle
*samr_policy
,
477 const struct dom_sid
*domain_sid
,
478 const struct dom_sid
*user_sid
,
479 struct wbint_userinfo
*user_info
)
481 struct policy_handle user_policy
;
482 union samr_UserInfo
*info
= NULL
;
484 NTSTATUS status
, result
;
485 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
487 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
488 return NT_STATUS_UNSUCCESSFUL
;
491 /* Get user handle */
492 status
= dcerpc_samr_OpenUser(b
,
495 SEC_FLAG_MAXIMUM_ALLOWED
,
499 if (!NT_STATUS_IS_OK(status
)) {
502 if (!NT_STATUS_IS_OK(result
)) {
507 status
= dcerpc_samr_QueryUserInfo(b
,
515 dcerpc_samr_Close(b
, mem_ctx
, &user_policy
, &_result
);
517 if (!NT_STATUS_IS_OK(status
)) {
520 if (!NT_STATUS_IS_OK(result
)) {
524 sid_compose(&user_info
->user_sid
, domain_sid
, user_rid
);
525 sid_compose(&user_info
->group_sid
, domain_sid
,
526 info
->info21
.primary_gid
);
528 user_info
->acct_name
= talloc_strdup(user_info
,
529 info
->info21
.account_name
.string
);
530 if (user_info
->acct_name
== NULL
) {
531 return NT_STATUS_NO_MEMORY
;
534 user_info
->full_name
= talloc_strdup(user_info
,
535 info
->info21
.full_name
.string
);
536 if ((info
->info21
.full_name
.string
!= NULL
) &&
537 (user_info
->full_name
== NULL
))
539 return NT_STATUS_NO_MEMORY
;
542 user_info
->homedir
= NULL
;
543 user_info
->shell
= NULL
;
544 user_info
->primary_gid
= (gid_t
)-1;
549 /* Lookup groups a user is a member of. */
550 NTSTATUS
rpc_lookup_usergroups(TALLOC_CTX
*mem_ctx
,
551 struct rpc_pipe_client
*samr_pipe
,
552 struct policy_handle
*samr_policy
,
553 const struct dom_sid
*domain_sid
,
554 const struct dom_sid
*user_sid
,
555 uint32_t *pnum_groups
,
556 struct dom_sid
**puser_grpsids
)
558 struct policy_handle user_policy
;
559 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
560 struct dom_sid
*user_grpsids
= NULL
;
561 uint32_t num_groups
= 0, i
;
563 NTSTATUS status
, result
;
564 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
566 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
567 return NT_STATUS_UNSUCCESSFUL
;
570 /* Get user handle */
571 status
= dcerpc_samr_OpenUser(b
,
574 SEC_FLAG_MAXIMUM_ALLOWED
,
578 if (!NT_STATUS_IS_OK(status
)) {
581 if (!NT_STATUS_IS_OK(result
)) {
585 /* Query user rids */
586 status
= dcerpc_samr_GetGroupsForUser(b
,
593 dcerpc_samr_Close(b
, mem_ctx
, &user_policy
, &_result
);
596 if (!NT_STATUS_IS_OK(status
)) {
599 if (!NT_STATUS_IS_OK(result
)) {
603 num_groups
= rid_array
->count
;
605 user_grpsids
= talloc_array(mem_ctx
, struct dom_sid
, num_groups
);
606 if (user_grpsids
== NULL
) {
607 status
= NT_STATUS_NO_MEMORY
;
611 for (i
= 0; i
< num_groups
; i
++) {
612 sid_compose(&(user_grpsids
[i
]), domain_sid
,
613 rid_array
->rids
[i
].rid
);
616 *pnum_groups
= num_groups
;
618 *puser_grpsids
= user_grpsids
;
623 NTSTATUS
rpc_lookup_useraliases(TALLOC_CTX
*mem_ctx
,
624 struct rpc_pipe_client
*samr_pipe
,
625 struct policy_handle
*samr_policy
,
627 const struct dom_sid
*sids
,
628 uint32_t *pnum_aliases
,
629 uint32_t **palias_rids
)
631 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
632 uint32_t num_query_sids
= 0;
633 uint32_t num_queries
= 1;
634 uint32_t num_aliases
= 0;
635 uint32_t total_sids
= 0;
636 uint32_t *alias_rids
= NULL
;
637 uint32_t rangesize
= MAX_SAM_ENTRIES_W2K
;
639 struct samr_Ids alias_rids_query
;
640 NTSTATUS status
, result
;
641 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
645 struct lsa_SidArray sid_array
;
647 ZERO_STRUCT(sid_array
);
649 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
651 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
652 num_queries
, num_query_sids
));
654 if (num_query_sids
) {
655 sid_array
.sids
= talloc_zero_array(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
656 if (sid_array
.sids
== NULL
) {
657 return NT_STATUS_NO_MEMORY
;
660 sid_array
.sids
= NULL
;
663 for (i
= 0; i
< num_query_sids
; i
++) {
664 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sids
[total_sids
++]);
665 if (sid_array
.sids
[i
].sid
== NULL
) {
666 return NT_STATUS_NO_MEMORY
;
669 sid_array
.num_sids
= num_query_sids
;
672 status
= dcerpc_samr_GetAliasMembership(b
,
678 if (!NT_STATUS_IS_OK(status
)) {
681 if (!NT_STATUS_IS_OK(result
)) {
686 for (i
= 0; i
< alias_rids_query
.count
; i
++) {
687 size_t na
= num_aliases
;
689 if (!add_rid_to_array_unique(mem_ctx
,
690 alias_rids_query
.ids
[i
],
693 return NT_STATUS_NO_MEMORY
;
700 } while (total_sids
< num_sids
);
702 DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
703 "(rangesize: %d)\n", num_aliases
, num_queries
, rangesize
));
705 *pnum_aliases
= num_aliases
;
706 *palias_rids
= alias_rids
;
709 #undef MAX_SAM_ENTRIES_W2K
712 /* Lookup group membership given a rid. */
713 NTSTATUS
rpc_lookup_groupmem(TALLOC_CTX
*mem_ctx
,
714 struct rpc_pipe_client
*samr_pipe
,
715 struct policy_handle
*samr_policy
,
716 const char *domain_name
,
717 const struct dom_sid
*domain_sid
,
718 const struct dom_sid
*group_sid
,
719 enum lsa_SidType type
,
720 uint32_t *pnum_names
,
721 struct dom_sid
**psid_mem
,
723 uint32_t **pname_types
)
725 struct policy_handle group_policy
;
727 uint32_t *rid_mem
= NULL
;
729 uint32_t num_names
= 0;
730 uint32_t total_names
= 0;
731 struct dom_sid
*sid_mem
= NULL
;
733 uint32_t *name_types
= NULL
;
735 struct lsa_Strings tmp_names
;
736 struct samr_Ids tmp_types
;
739 NTSTATUS status
, result
;
740 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
742 if (!sid_peek_check_rid(domain_sid
, group_sid
, &group_rid
)) {
743 return NT_STATUS_UNSUCCESSFUL
;
747 case SID_NAME_DOM_GRP
:
749 struct samr_RidAttrArray
*rids
= NULL
;
751 status
= dcerpc_samr_OpenGroup(b
,
754 SEC_FLAG_MAXIMUM_ALLOWED
,
758 if (!NT_STATUS_IS_OK(status
)) {
761 if (!NT_STATUS_IS_OK(result
)) {
766 * Step #1: Get a list of user rids that are the members of the group.
768 status
= dcerpc_samr_QueryGroupMember(b
,
775 dcerpc_samr_Close(b
, mem_ctx
, &group_policy
, &_result
);
778 if (!NT_STATUS_IS_OK(status
)) {
781 if (!NT_STATUS_IS_OK(result
)) {
786 if (rids
== NULL
|| rids
->count
== 0) {
795 num_names
= rids
->count
;
796 rid_mem
= rids
->rids
;
800 case SID_NAME_WKN_GRP
:
803 struct lsa_SidArray sid_array
;
804 struct lsa_SidPtr sid_ptr
;
805 struct samr_Ids rids_query
;
807 sid_ptr
.sid
= dom_sid_dup(mem_ctx
, group_sid
);
808 if (sid_ptr
.sid
== NULL
) {
809 return NT_STATUS_NO_MEMORY
;
812 sid_array
.num_sids
= 1;
813 sid_array
.sids
= &sid_ptr
;
815 status
= dcerpc_samr_GetAliasMembership(b
,
821 if (!NT_STATUS_IS_OK(status
)) {
824 if (!NT_STATUS_IS_OK(result
)) {
828 if (rids_query
.count
== 0) {
837 num_names
= rids_query
.count
;
838 rid_mem
= rids_query
.ids
;
843 return NT_STATUS_UNSUCCESSFUL
;
847 * Step #2: Convert list of rids into list of usernames.
850 names
= talloc_zero_array(mem_ctx
, char *, num_names
);
851 name_types
= talloc_zero_array(mem_ctx
, uint32_t, num_names
);
852 sid_mem
= talloc_zero_array(mem_ctx
, struct dom_sid
, num_names
);
853 if (names
== NULL
|| name_types
== NULL
|| sid_mem
== NULL
) {
854 return NT_STATUS_NO_MEMORY
;
858 for (j
= 0; j
< num_names
; j
++) {
859 sid_compose(&sid_mem
[j
], domain_sid
, rid_mem
[j
]);
862 status
= dcerpc_samr_LookupRids(b
,
870 if (!NT_STATUS_IS_OK(status
)) {
874 if (!NT_STATUS_IS_OK(result
)) {
875 if (!NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
880 /* Copy result into array. The talloc system will take
881 care of freeing the temporary arrays later on. */
882 if (tmp_names
.count
!= num_names
) {
883 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
885 if (tmp_types
.count
!= num_names
) {
886 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
889 for (r
= 0; r
< tmp_names
.count
; r
++) {
890 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
893 if (total_names
>= num_names
) {
896 names
[total_names
] = fill_domain_username_talloc(names
,
898 tmp_names
.names
[r
].string
,
900 if (names
[total_names
] == NULL
) {
901 return NT_STATUS_NO_MEMORY
;
903 name_types
[total_names
] = tmp_types
.ids
[r
];
907 *pnum_names
= total_names
;
909 *pname_types
= name_types
;
915 /* Find the sequence number for a domain */
916 NTSTATUS
rpc_sequence_number(TALLOC_CTX
*mem_ctx
,
917 struct rpc_pipe_client
*samr_pipe
,
918 struct policy_handle
*samr_policy
,
919 const char *domain_name
,
922 union samr_DomainInfo
*info
= NULL
;
923 bool got_seq_num
= false;
924 NTSTATUS status
, result
;
925 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
927 /* query domain info */
928 status
= dcerpc_samr_QueryDomainInfo(b
,
934 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
935 *pseq
= info
->info8
.sequence_num
;
940 /* retry with info-level 2 in case the dc does not support info-level 8
941 * (like all older samba2 and samba3 dc's) - Guenther */
942 status
= dcerpc_samr_QueryDomainInfo(b
,
948 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
949 *pseq
= info
->general
.sequence_num
;
954 if (!NT_STATUS_IS_OK(status
)) {
962 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
963 domain_name
, (unsigned) *pseq
));
965 DEBUG(10,("domain_sequence_number: failed to get sequence "
966 "number (%u) for domain %s\n",
967 (unsigned) *pseq
, domain_name
));
968 status
= NT_STATUS_OK
;
974 /* Get a list of trusted domains */
975 NTSTATUS
rpc_trusted_domains(TALLOC_CTX
*mem_ctx
,
976 struct rpc_pipe_client
*lsa_pipe
,
977 struct policy_handle
*lsa_policy
,
978 uint32_t *pnum_trusts
,
979 struct netr_DomainTrust
**ptrusts
)
981 struct netr_DomainTrust
*array
= NULL
;
982 uint32_t enum_ctx
= 0;
984 NTSTATUS status
, result
;
985 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
988 struct lsa_DomainList dom_list
;
989 struct lsa_DomainListEx dom_list_ex
;
994 * We don't run into deadlocks here, cause winbind_off() is
995 * called in the main function.
997 status
= dcerpc_lsa_EnumTrustedDomainsEx(b
,
1004 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_ERR(result
) &&
1005 dom_list_ex
.count
> 0) {
1006 count
+= dom_list_ex
.count
;
1009 status
= dcerpc_lsa_EnumTrustDom(b
,
1016 if (!NT_STATUS_IS_OK(status
)) {
1019 if (!NT_STATUS_IS_OK(result
)) {
1020 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1025 count
+= dom_list
.count
;
1028 array
= talloc_realloc(mem_ctx
,
1030 struct netr_DomainTrust
,
1032 if (array
== NULL
) {
1033 return NT_STATUS_NO_MEMORY
;
1036 for (i
= 0; i
< count
; i
++) {
1037 struct netr_DomainTrust
*trust
= &array
[i
];
1038 struct dom_sid
*sid
;
1040 ZERO_STRUCTP(trust
);
1042 sid
= talloc(array
, struct dom_sid
);
1044 return NT_STATUS_NO_MEMORY
;
1048 trust
->netbios_name
= talloc_move(array
,
1049 &dom_list_ex
.domains
[i
].netbios_name
.string
);
1050 trust
->dns_name
= talloc_move(array
,
1051 &dom_list_ex
.domains
[i
].domain_name
.string
);
1052 if (dom_list_ex
.domains
[i
].sid
== NULL
) {
1053 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust
->dns_name
));
1054 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1056 sid_copy(sid
, dom_list_ex
.domains
[i
].sid
);
1058 trust
->netbios_name
= talloc_move(array
,
1059 &dom_list
.domains
[i
].name
.string
);
1060 trust
->dns_name
= NULL
;
1062 if (dom_list
.domains
[i
].sid
== NULL
) {
1063 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust
->netbios_name
));
1064 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1067 sid_copy(sid
, dom_list
.domains
[i
].sid
);
1072 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1074 *pnum_trusts
= count
;
1077 return NT_STATUS_OK
;
1080 static NTSTATUS
rpc_try_lookup_sids3(TALLOC_CTX
*mem_ctx
,
1081 struct winbindd_domain
*domain
,
1082 struct rpc_pipe_client
*cli
,
1083 struct lsa_SidArray
*sids
,
1084 struct lsa_RefDomainList
**pdomains
,
1085 struct lsa_TransNameArray
**pnames
)
1087 struct lsa_TransNameArray2 lsa_names2
;
1088 struct lsa_TransNameArray
*names
= *pnames
;
1089 uint32_t i
, count
= 0;
1090 NTSTATUS status
, result
;
1092 ZERO_STRUCT(lsa_names2
);
1093 status
= dcerpc_lsa_LookupSids3(cli
->binding_handle
,
1098 LSA_LOOKUP_NAMES_ALL
,
1100 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
,
1101 LSA_CLIENT_REVISION_2
,
1103 if (!NT_STATUS_IS_OK(status
)) {
1106 if (NT_STATUS_IS_ERR(result
)) {
1109 if (sids
->num_sids
!= lsa_names2
.count
) {
1110 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1113 names
->count
= lsa_names2
.count
;
1114 names
->names
= talloc_array(names
, struct lsa_TranslatedName
,
1116 if (names
->names
== NULL
) {
1117 return NT_STATUS_NO_MEMORY
;
1119 for (i
=0; i
<names
->count
; i
++) {
1120 names
->names
[i
].sid_type
= lsa_names2
.names
[i
].sid_type
;
1121 names
->names
[i
].name
.string
= talloc_move(
1122 names
->names
, &lsa_names2
.names
[i
].name
.string
);
1123 names
->names
[i
].sid_index
= lsa_names2
.names
[i
].sid_index
;
1125 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
1128 if ((*pdomains
) == NULL
) {
1129 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1131 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
1132 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1138 NTSTATUS
rpc_lookup_sids(TALLOC_CTX
*mem_ctx
,
1139 struct winbindd_domain
*domain
,
1140 struct lsa_SidArray
*sids
,
1141 struct lsa_RefDomainList
**pdomains
,
1142 struct lsa_TransNameArray
**pnames
)
1144 struct lsa_TransNameArray
*names
= *pnames
;
1145 struct rpc_pipe_client
*cli
= NULL
;
1146 struct policy_handle lsa_policy
;
1149 NTSTATUS status
, result
;
1151 status
= cm_connect_lsat(domain
, mem_ctx
, &cli
, &lsa_policy
);
1152 if (!NT_STATUS_IS_OK(status
)) {
1156 if (cli
->transport
->transport
== NCACN_IP_TCP
) {
1157 return rpc_try_lookup_sids3(mem_ctx
, domain
, cli
, sids
,
1161 status
= dcerpc_lsa_LookupSids(cli
->binding_handle
, mem_ctx
,
1162 &lsa_policy
, sids
, pdomains
,
1163 names
, LSA_LOOKUP_NAMES_ALL
,
1165 if (!NT_STATUS_IS_OK(status
)) {
1168 if (NT_STATUS_IS_ERR(result
)) {
1172 if (sids
->num_sids
!= names
->count
) {
1173 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1176 for (i
=0; i
< names
->count
; i
++) {
1177 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
1180 if ((*pdomains
) == NULL
) {
1181 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1183 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
1184 return NT_STATUS_INVALID_NETWORK_RESPONSE
;