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 char *mapped_name
= NULL
;
283 if (name
== NULL
|| name
[0] == '\0') {
284 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
285 } else if (domain_name
== NULL
|| domain_name
[0] == '\0') {
286 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
288 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
291 if (full_name
== NULL
) {
292 return NT_STATUS_NO_MEMORY
;
295 status
= normalize_name_unmap(mem_ctx
, full_name
, &mapped_name
);
296 /* Reset the full_name pointer if we mapped anything */
297 if (NT_STATUS_IS_OK(status
) ||
298 NT_STATUS_EQUAL(status
, NT_STATUS_FILE_RENAMED
)) {
299 full_name
= mapped_name
;
302 DEBUG(3,("name_to_sid: %s for domain %s\n",
303 full_name
? full_name
: "", domain_name
));
306 * We don't run into deadlocks here, cause winbind_off() is
307 * called in the main function.
309 status
= rpccli_lsa_lookup_names(lsa_pipe
,
313 (const char **) &full_name
,
318 if (!NT_STATUS_IS_OK(status
)) {
319 DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
324 sid_copy(sid
, &sids
[0]);
330 /* Convert a domain SID to a user or group name */
331 NTSTATUS
rpc_sid_to_name(TALLOC_CTX
*mem_ctx
,
332 struct rpc_pipe_client
*lsa_pipe
,
333 struct policy_handle
*lsa_policy
,
334 struct winbindd_domain
*domain
,
335 const struct dom_sid
*sid
,
338 enum lsa_SidType
*ptype
)
340 char *mapped_name
= NULL
;
341 char **domains
= NULL
;
343 enum lsa_SidType
*types
= NULL
;
347 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
355 if (!NT_STATUS_IS_OK(status
)) {
356 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n",
361 *ptype
= (enum lsa_SidType
) types
[0];
363 map_status
= normalize_name_map(mem_ctx
,
367 if (NT_STATUS_IS_OK(map_status
) ||
368 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
369 *pname
= talloc_strdup(mem_ctx
, mapped_name
);
370 DEBUG(5,("returning mapped name -- %s\n", *pname
));
372 *pname
= talloc_strdup(mem_ctx
, names
[0]);
374 if (*pname
== NULL
) {
375 return NT_STATUS_NO_MEMORY
;
378 *pdomain_name
= talloc_strdup(mem_ctx
, domains
[0]);
379 if (*pdomain_name
== NULL
) {
380 return NT_STATUS_NO_MEMORY
;
386 /* Convert a bunch of rids to user or group names */
387 NTSTATUS
rpc_rids_to_names(TALLOC_CTX
*mem_ctx
,
388 struct rpc_pipe_client
*lsa_pipe
,
389 struct policy_handle
*lsa_policy
,
390 struct winbindd_domain
*domain
,
391 const struct dom_sid
*sid
,
396 enum lsa_SidType
**ptypes
)
398 enum lsa_SidType
*types
= NULL
;
399 char *domain_name
= NULL
;
400 char **domains
= NULL
;
402 struct dom_sid
*sids
;
407 sids
= talloc_array(mem_ctx
, struct dom_sid
, num_rids
);
409 return NT_STATUS_NO_MEMORY
;
415 for (i
= 0; i
< num_rids
; i
++) {
416 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
417 return NT_STATUS_INTERNAL_ERROR
;
421 status
= rpccli_lsa_lookup_sids(lsa_pipe
,
429 if (!NT_STATUS_IS_OK(status
) &&
430 !NT_STATUS_EQUAL(status
, STATUS_SOME_UNMAPPED
)) {
431 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n",
436 for (i
= 0; i
< num_rids
; i
++) {
437 char *mapped_name
= NULL
;
440 if (types
[i
] != SID_NAME_UNKNOWN
) {
441 map_status
= normalize_name_map(mem_ctx
,
445 if (NT_STATUS_IS_OK(map_status
) ||
446 NT_STATUS_EQUAL(map_status
, NT_STATUS_FILE_RENAMED
)) {
447 TALLOC_FREE(names
[i
]);
448 names
[i
] = talloc_strdup(names
, mapped_name
);
449 if (names
[i
] == NULL
) {
450 return NT_STATUS_NO_MEMORY
;
454 domain_name
= domains
[i
];
458 *pdomain_name
= domain_name
;
465 /* Lookup user information from a rid or username. */
466 NTSTATUS
rpc_query_user(TALLOC_CTX
*mem_ctx
,
467 struct rpc_pipe_client
*samr_pipe
,
468 struct policy_handle
*samr_policy
,
469 const struct dom_sid
*domain_sid
,
470 const struct dom_sid
*user_sid
,
471 struct wbint_userinfo
*user_info
)
473 struct policy_handle user_policy
;
474 union samr_UserInfo
*info
= NULL
;
476 NTSTATUS status
, result
;
477 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
479 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
480 return NT_STATUS_UNSUCCESSFUL
;
483 /* Get user handle */
484 status
= dcerpc_samr_OpenUser(b
,
487 SEC_FLAG_MAXIMUM_ALLOWED
,
491 if (!NT_STATUS_IS_OK(status
)) {
494 if (!NT_STATUS_IS_OK(result
)) {
499 status
= dcerpc_samr_QueryUserInfo(b
,
507 dcerpc_samr_Close(b
, mem_ctx
, &user_policy
, &_result
);
509 if (!NT_STATUS_IS_OK(status
)) {
512 if (!NT_STATUS_IS_OK(result
)) {
516 sid_compose(&user_info
->user_sid
, domain_sid
, user_rid
);
517 sid_compose(&user_info
->group_sid
, domain_sid
,
518 info
->info21
.primary_gid
);
520 user_info
->acct_name
= talloc_strdup(user_info
,
521 info
->info21
.account_name
.string
);
522 if (user_info
->acct_name
== NULL
) {
523 return NT_STATUS_NO_MEMORY
;
526 user_info
->full_name
= talloc_strdup(user_info
,
527 info
->info21
.full_name
.string
);
528 if ((info
->info21
.full_name
.string
!= NULL
) &&
529 (user_info
->acct_name
== NULL
))
531 return NT_STATUS_NO_MEMORY
;
534 user_info
->homedir
= NULL
;
535 user_info
->shell
= NULL
;
536 user_info
->primary_gid
= (gid_t
)-1;
541 /* Lookup groups a user is a member of. */
542 NTSTATUS
rpc_lookup_usergroups(TALLOC_CTX
*mem_ctx
,
543 struct rpc_pipe_client
*samr_pipe
,
544 struct policy_handle
*samr_policy
,
545 const struct dom_sid
*domain_sid
,
546 const struct dom_sid
*user_sid
,
547 uint32_t *pnum_groups
,
548 struct dom_sid
**puser_grpsids
)
550 struct policy_handle user_policy
;
551 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
552 struct dom_sid
*user_grpsids
= NULL
;
553 uint32_t num_groups
= 0, i
;
555 NTSTATUS status
, result
;
556 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
558 if (!sid_peek_check_rid(domain_sid
, user_sid
, &user_rid
)) {
559 return NT_STATUS_UNSUCCESSFUL
;
562 /* Get user handle */
563 status
= dcerpc_samr_OpenUser(b
,
566 SEC_FLAG_MAXIMUM_ALLOWED
,
570 if (!NT_STATUS_IS_OK(status
)) {
573 if (!NT_STATUS_IS_OK(result
)) {
577 /* Query user rids */
578 status
= dcerpc_samr_GetGroupsForUser(b
,
583 num_groups
= rid_array
->count
;
587 dcerpc_samr_Close(b
, mem_ctx
, &user_policy
, &_result
);
590 if (!NT_STATUS_IS_OK(status
)) {
593 if (!NT_STATUS_IS_OK(result
) || num_groups
== 0) {
597 user_grpsids
= talloc_array(mem_ctx
, struct dom_sid
, num_groups
);
598 if (user_grpsids
== NULL
) {
599 status
= NT_STATUS_NO_MEMORY
;
603 for (i
= 0; i
< num_groups
; i
++) {
604 sid_compose(&(user_grpsids
[i
]), domain_sid
,
605 rid_array
->rids
[i
].rid
);
608 *pnum_groups
= num_groups
;
610 *puser_grpsids
= user_grpsids
;
615 NTSTATUS
rpc_lookup_useraliases(TALLOC_CTX
*mem_ctx
,
616 struct rpc_pipe_client
*samr_pipe
,
617 struct policy_handle
*samr_policy
,
619 const struct dom_sid
*sids
,
620 uint32_t *pnum_aliases
,
621 uint32_t **palias_rids
)
623 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
624 uint32_t num_query_sids
= 0;
625 uint32_t num_queries
= 1;
626 uint32_t num_aliases
= 0;
627 uint32_t total_sids
= 0;
628 uint32_t *alias_rids
= NULL
;
629 uint32_t rangesize
= MAX_SAM_ENTRIES_W2K
;
631 struct samr_Ids alias_rids_query
;
632 NTSTATUS status
, result
;
633 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
637 struct lsa_SidArray sid_array
;
639 ZERO_STRUCT(sid_array
);
641 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
643 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
644 num_queries
, num_query_sids
));
646 if (num_query_sids
) {
647 sid_array
.sids
= talloc_zero_array(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
648 if (sid_array
.sids
== NULL
) {
649 return NT_STATUS_NO_MEMORY
;
652 sid_array
.sids
= NULL
;
655 for (i
= 0; i
< num_query_sids
; i
++) {
656 sid_array
.sids
[i
].sid
= dom_sid_dup(mem_ctx
, &sids
[total_sids
++]);
657 if (sid_array
.sids
[i
].sid
== NULL
) {
658 return NT_STATUS_NO_MEMORY
;
661 sid_array
.num_sids
= num_query_sids
;
664 status
= dcerpc_samr_GetAliasMembership(b
,
670 if (!NT_STATUS_IS_OK(status
)) {
673 if (!NT_STATUS_IS_OK(result
)) {
678 for (i
= 0; i
< alias_rids_query
.count
; i
++) {
679 size_t na
= num_aliases
;
681 if (!add_rid_to_array_unique(mem_ctx
,
682 alias_rids_query
.ids
[i
],
685 return NT_STATUS_NO_MEMORY
;
692 } while (total_sids
< num_sids
);
694 DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries "
695 "(rangesize: %d)\n", num_aliases
, num_queries
, rangesize
));
697 *pnum_aliases
= num_aliases
;
698 *palias_rids
= alias_rids
;
701 #undef MAX_SAM_ENTRIES_W2K
704 /* Lookup group membership given a rid. */
705 NTSTATUS
rpc_lookup_groupmem(TALLOC_CTX
*mem_ctx
,
706 struct rpc_pipe_client
*samr_pipe
,
707 struct policy_handle
*samr_policy
,
708 const char *domain_name
,
709 const struct dom_sid
*domain_sid
,
710 const struct dom_sid
*group_sid
,
711 enum lsa_SidType type
,
712 uint32_t *pnum_names
,
713 struct dom_sid
**psid_mem
,
715 uint32_t **pname_types
)
717 struct policy_handle group_policy
;
719 uint32_t *rid_mem
= NULL
;
721 uint32_t num_names
= 0;
722 uint32_t total_names
= 0;
723 struct dom_sid
*sid_mem
= NULL
;
725 uint32_t *name_types
= NULL
;
727 struct lsa_Strings tmp_names
;
728 struct samr_Ids tmp_types
;
731 NTSTATUS status
, result
;
732 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
734 if (!sid_peek_check_rid(domain_sid
, group_sid
, &group_rid
)) {
735 return NT_STATUS_UNSUCCESSFUL
;
739 case SID_NAME_DOM_GRP
:
741 struct samr_RidAttrArray
*rids
= NULL
;
743 status
= dcerpc_samr_OpenGroup(b
,
746 SEC_FLAG_MAXIMUM_ALLOWED
,
750 if (!NT_STATUS_IS_OK(status
)) {
753 if (!NT_STATUS_IS_OK(result
)) {
758 * Step #1: Get a list of user rids that are the members of the group.
760 status
= dcerpc_samr_QueryGroupMember(b
,
767 dcerpc_samr_Close(b
, mem_ctx
, &group_policy
, &_result
);
770 if (!NT_STATUS_IS_OK(status
)) {
773 if (!NT_STATUS_IS_OK(result
)) {
778 if (rids
== NULL
|| rids
->count
== 0) {
787 num_names
= rids
->count
;
788 rid_mem
= rids
->rids
;
792 case SID_NAME_WKN_GRP
:
795 struct lsa_SidArray sid_array
;
796 struct lsa_SidPtr sid_ptr
;
797 struct samr_Ids rids_query
;
799 sid_ptr
.sid
= dom_sid_dup(mem_ctx
, group_sid
);
800 if (sid_ptr
.sid
== NULL
) {
801 return NT_STATUS_NO_MEMORY
;
804 sid_array
.num_sids
= 1;
805 sid_array
.sids
= &sid_ptr
;
807 status
= dcerpc_samr_GetAliasMembership(b
,
813 if (!NT_STATUS_IS_OK(status
)) {
816 if (!NT_STATUS_IS_OK(result
)) {
820 if (rids_query
.count
== 0) {
829 num_names
= rids_query
.count
;
830 rid_mem
= rids_query
.ids
;
835 return NT_STATUS_UNSUCCESSFUL
;
839 * Step #2: Convert list of rids into list of usernames.
842 names
= talloc_zero_array(mem_ctx
, char *, num_names
);
843 name_types
= talloc_zero_array(mem_ctx
, uint32_t, num_names
);
844 sid_mem
= talloc_zero_array(mem_ctx
, struct dom_sid
, num_names
);
845 if (names
== NULL
|| name_types
== NULL
|| sid_mem
== NULL
) {
846 return NT_STATUS_NO_MEMORY
;
850 for (j
= 0; j
< num_names
; j
++) {
851 sid_compose(&sid_mem
[j
], domain_sid
, rid_mem
[j
]);
854 status
= dcerpc_samr_LookupRids(b
,
862 if (!NT_STATUS_IS_OK(status
)) {
866 if (!NT_STATUS_IS_OK(result
)) {
867 if (!NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
872 /* Copy result into array. The talloc system will take
873 care of freeing the temporary arrays later on. */
874 if (tmp_names
.count
!= tmp_types
.count
) {
875 return NT_STATUS_UNSUCCESSFUL
;
878 for (r
= 0; r
< tmp_names
.count
; r
++) {
879 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
882 names
[total_names
] = fill_domain_username_talloc(names
,
884 tmp_names
.names
[r
].string
,
886 if (names
[total_names
] == NULL
) {
887 return NT_STATUS_NO_MEMORY
;
889 name_types
[total_names
] = tmp_types
.ids
[r
];
893 *pnum_names
= total_names
;
895 *pname_types
= name_types
;
901 /* Find the sequence number for a domain */
902 NTSTATUS
rpc_sequence_number(TALLOC_CTX
*mem_ctx
,
903 struct rpc_pipe_client
*samr_pipe
,
904 struct policy_handle
*samr_policy
,
905 const char *domain_name
,
908 union samr_DomainInfo
*info
= NULL
;
909 bool got_seq_num
= false;
910 NTSTATUS status
, result
;
911 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
913 /* query domain info */
914 status
= dcerpc_samr_QueryDomainInfo(b
,
920 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
921 *pseq
= info
->info8
.sequence_num
;
926 /* retry with info-level 2 in case the dc does not support info-level 8
927 * (like all older samba2 and samba3 dc's) - Guenther */
928 status
= dcerpc_samr_QueryDomainInfo(b
,
934 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
935 *pseq
= info
->general
.sequence_num
;
940 if (!NT_STATUS_IS_OK(status
)) {
948 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
949 domain_name
, (unsigned) *pseq
));
951 DEBUG(10,("domain_sequence_number: failed to get sequence "
952 "number (%u) for domain %s\n",
953 (unsigned) *pseq
, domain_name
));
954 status
= NT_STATUS_OK
;
960 /* Get a list of trusted domains */
961 NTSTATUS
rpc_trusted_domains(TALLOC_CTX
*mem_ctx
,
962 struct rpc_pipe_client
*lsa_pipe
,
963 struct policy_handle
*lsa_policy
,
964 uint32_t *pnum_trusts
,
965 struct netr_DomainTrust
**ptrusts
)
967 struct netr_DomainTrust
*array
= NULL
;
968 uint32_t enum_ctx
= 0;
970 NTSTATUS status
, result
;
971 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
974 struct lsa_DomainList dom_list
;
975 struct lsa_DomainListEx dom_list_ex
;
980 * We don't run into deadlocks here, cause winbind_off() is
981 * called in the main function.
983 status
= dcerpc_lsa_EnumTrustedDomainsEx(b
,
990 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_ERR(result
) &&
991 dom_list_ex
.count
> 0) {
992 count
+= dom_list_ex
.count
;
995 status
= dcerpc_lsa_EnumTrustDom(b
,
1002 if (!NT_STATUS_IS_OK(status
)) {
1005 if (!NT_STATUS_IS_OK(result
)) {
1006 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1011 count
+= dom_list
.count
;
1014 array
= talloc_realloc(mem_ctx
,
1016 struct netr_DomainTrust
,
1018 if (array
== NULL
) {
1019 return NT_STATUS_NO_MEMORY
;
1022 for (i
= 0; i
< count
; i
++) {
1023 struct netr_DomainTrust
*trust
= &array
[i
];
1024 struct dom_sid
*sid
;
1026 ZERO_STRUCTP(trust
);
1028 sid
= talloc(array
, struct dom_sid
);
1030 return NT_STATUS_NO_MEMORY
;
1034 trust
->netbios_name
= talloc_move(array
,
1035 &dom_list_ex
.domains
[i
].netbios_name
.string
);
1036 trust
->dns_name
= talloc_move(array
,
1037 &dom_list_ex
.domains
[i
].domain_name
.string
);
1039 sid_copy(sid
, dom_list_ex
.domains
[i
].sid
);
1041 trust
->netbios_name
= talloc_move(array
,
1042 &dom_list
.domains
[i
].name
.string
);
1043 trust
->dns_name
= NULL
;
1045 sid_copy(sid
, dom_list
.domains
[i
].sid
);
1050 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1052 *pnum_trusts
= count
;
1055 return NT_STATUS_OK
;
1058 static NTSTATUS
rpc_try_lookup_sids3(TALLOC_CTX
*mem_ctx
,
1059 struct winbindd_domain
*domain
,
1060 struct lsa_SidArray
*sids
,
1061 struct lsa_RefDomainList
**pdomains
,
1062 struct lsa_TransNameArray
**pnames
)
1064 struct lsa_TransNameArray2 lsa_names2
;
1065 struct lsa_TransNameArray
*names
;
1067 struct rpc_pipe_client
*cli
;
1068 NTSTATUS status
, result
;
1070 status
= cm_connect_lsa_tcp(domain
, talloc_tos(), &cli
);
1071 if (!NT_STATUS_IS_OK(status
)) {
1072 domain
->can_do_ncacn_ip_tcp
= false;
1076 ZERO_STRUCT(lsa_names2
);
1077 status
= dcerpc_lsa_LookupSids3(cli
->binding_handle
,
1082 LSA_LOOKUP_NAMES_ALL
,
1084 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES
,
1085 LSA_CLIENT_REVISION_2
,
1087 if (!NT_STATUS_IS_OK(status
)) {
1090 if (NT_STATUS_IS_ERR(result
)) {
1093 names
= talloc_zero(mem_ctx
, struct lsa_TransNameArray
);
1094 if (names
== NULL
) {
1095 return NT_STATUS_NO_MEMORY
;
1097 names
->count
= lsa_names2
.count
;
1098 names
->names
= talloc_array(names
, struct lsa_TranslatedName
,
1100 if (names
->names
== NULL
) {
1101 return NT_STATUS_NO_MEMORY
;
1103 for (i
=0; i
<names
->count
; i
++) {
1104 names
->names
[i
].sid_type
= lsa_names2
.names
[i
].sid_type
;
1105 names
->names
[i
].name
.string
= talloc_move(
1106 names
->names
, &lsa_names2
.names
[i
].name
.string
);
1107 names
->names
[i
].sid_index
= lsa_names2
.names
[i
].sid_index
;
1113 NTSTATUS
rpc_lookup_sids(TALLOC_CTX
*mem_ctx
,
1114 struct winbindd_domain
*domain
,
1115 struct lsa_SidArray
*sids
,
1116 struct lsa_RefDomainList
**pdomains
,
1117 struct lsa_TransNameArray
**pnames
)
1119 struct lsa_TransNameArray
*names
;
1120 struct rpc_pipe_client
*cli
= NULL
;
1121 struct policy_handle lsa_policy
;
1123 NTSTATUS status
, result
;
1125 if (domain
->can_do_ncacn_ip_tcp
) {
1126 status
= rpc_try_lookup_sids3(mem_ctx
, domain
, sids
,
1128 if (!NT_STATUS_IS_ERR(status
)) {
1133 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1134 if (!NT_STATUS_IS_OK(status
)) {
1138 names
= talloc_zero(mem_ctx
, struct lsa_TransNameArray
);
1139 if (names
== NULL
) {
1140 return NT_STATUS_NO_MEMORY
;
1142 status
= dcerpc_lsa_LookupSids(cli
->binding_handle
, mem_ctx
,
1143 &lsa_policy
, sids
, pdomains
,
1144 names
, LSA_LOOKUP_NAMES_ALL
,
1146 if (!NT_STATUS_IS_OK(status
)) {
1149 if (NT_STATUS_IS_ERR(result
)) {