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 ((names
[0] != NULL
) && (*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
->full_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
,
585 dcerpc_samr_Close(b
, mem_ctx
, &user_policy
, &_result
);
588 if (!NT_STATUS_IS_OK(status
)) {
591 if (!NT_STATUS_IS_OK(result
)) {
595 num_groups
= rid_array
->count
;
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
!= num_names
) {
875 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
877 if (tmp_types
.count
!= num_names
) {
878 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
881 for (r
= 0; r
< tmp_names
.count
; r
++) {
882 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
885 if (total_names
>= num_names
) {
888 names
[total_names
] = fill_domain_username_talloc(names
,
890 tmp_names
.names
[r
].string
,
892 if (names
[total_names
] == NULL
) {
893 return NT_STATUS_NO_MEMORY
;
895 name_types
[total_names
] = tmp_types
.ids
[r
];
899 *pnum_names
= total_names
;
901 *pname_types
= name_types
;
907 /* Find the sequence number for a domain */
908 NTSTATUS
rpc_sequence_number(TALLOC_CTX
*mem_ctx
,
909 struct rpc_pipe_client
*samr_pipe
,
910 struct policy_handle
*samr_policy
,
911 const char *domain_name
,
914 union samr_DomainInfo
*info
= NULL
;
915 bool got_seq_num
= false;
916 NTSTATUS status
, result
;
917 struct dcerpc_binding_handle
*b
= samr_pipe
->binding_handle
;
919 /* query domain info */
920 status
= dcerpc_samr_QueryDomainInfo(b
,
926 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
927 *pseq
= info
->info8
.sequence_num
;
932 /* retry with info-level 2 in case the dc does not support info-level 8
933 * (like all older samba2 and samba3 dc's) - Guenther */
934 status
= dcerpc_samr_QueryDomainInfo(b
,
940 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
941 *pseq
= info
->general
.sequence_num
;
946 if (!NT_STATUS_IS_OK(status
)) {
954 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
955 domain_name
, (unsigned) *pseq
));
957 DEBUG(10,("domain_sequence_number: failed to get sequence "
958 "number (%u) for domain %s\n",
959 (unsigned) *pseq
, domain_name
));
960 status
= NT_STATUS_OK
;
966 /* Get a list of trusted domains */
967 NTSTATUS
rpc_trusted_domains(TALLOC_CTX
*mem_ctx
,
968 struct rpc_pipe_client
*lsa_pipe
,
969 struct policy_handle
*lsa_policy
,
970 uint32_t *pnum_trusts
,
971 struct netr_DomainTrust
**ptrusts
)
973 struct netr_DomainTrust
*array
= NULL
;
974 uint32_t enum_ctx
= 0;
976 NTSTATUS status
, result
;
977 struct dcerpc_binding_handle
*b
= lsa_pipe
->binding_handle
;
980 struct lsa_DomainList dom_list
;
981 struct lsa_DomainListEx dom_list_ex
;
986 * We don't run into deadlocks here, cause winbind_off() is
987 * called in the main function.
989 status
= dcerpc_lsa_EnumTrustedDomainsEx(b
,
996 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_ERR(result
) &&
997 dom_list_ex
.count
> 0) {
998 count
+= dom_list_ex
.count
;
1001 status
= dcerpc_lsa_EnumTrustDom(b
,
1008 if (!NT_STATUS_IS_OK(status
)) {
1011 if (!NT_STATUS_IS_OK(result
)) {
1012 if (!NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1017 count
+= dom_list
.count
;
1020 array
= talloc_realloc(mem_ctx
,
1022 struct netr_DomainTrust
,
1024 if (array
== NULL
) {
1025 return NT_STATUS_NO_MEMORY
;
1028 for (i
= 0; i
< count
; i
++) {
1029 struct netr_DomainTrust
*trust
= &array
[i
];
1030 struct dom_sid
*sid
;
1032 ZERO_STRUCTP(trust
);
1034 sid
= talloc(array
, struct dom_sid
);
1036 return NT_STATUS_NO_MEMORY
;
1040 trust
->netbios_name
= talloc_move(array
,
1041 &dom_list_ex
.domains
[i
].netbios_name
.string
);
1042 trust
->dns_name
= talloc_move(array
,
1043 &dom_list_ex
.domains
[i
].domain_name
.string
);
1045 sid_copy(sid
, dom_list_ex
.domains
[i
].sid
);
1047 trust
->netbios_name
= talloc_move(array
,
1048 &dom_list
.domains
[i
].name
.string
);
1049 trust
->dns_name
= NULL
;
1051 sid_copy(sid
, dom_list
.domains
[i
].sid
);
1056 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
1058 *pnum_trusts
= count
;
1061 return NT_STATUS_OK
;
1064 static NTSTATUS
rpc_try_lookup_sids3(TALLOC_CTX
*mem_ctx
,
1065 struct winbindd_domain
*domain
,
1066 struct rpc_pipe_client
*cli
,
1067 struct lsa_SidArray
*sids
,
1068 struct lsa_RefDomainList
**pdomains
,
1069 struct lsa_TransNameArray
**pnames
)
1071 struct lsa_TransNameArray2 lsa_names2
;
1072 struct lsa_TransNameArray
*names
= *pnames
;
1074 NTSTATUS status
, result
;
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 if (sids
->num_sids
!= lsa_names2
.count
) {
1094 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
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
;
1109 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
1112 if ((*pdomains
) == NULL
) {
1113 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1115 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
1116 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1122 NTSTATUS
rpc_lookup_sids(TALLOC_CTX
*mem_ctx
,
1123 struct winbindd_domain
*domain
,
1124 struct lsa_SidArray
*sids
,
1125 struct lsa_RefDomainList
**pdomains
,
1126 struct lsa_TransNameArray
**pnames
)
1128 struct lsa_TransNameArray
*names
= *pnames
;
1129 struct rpc_pipe_client
*cli
= NULL
;
1130 struct policy_handle lsa_policy
;
1133 NTSTATUS status
, result
;
1135 status
= cm_connect_lsat(domain
, mem_ctx
, &cli
, &lsa_policy
);
1136 if (!NT_STATUS_IS_OK(status
)) {
1140 if (cli
->transport
->transport
== NCACN_IP_TCP
) {
1141 return rpc_try_lookup_sids3(mem_ctx
, domain
, cli
, sids
,
1145 status
= dcerpc_lsa_LookupSids(cli
->binding_handle
, mem_ctx
,
1146 &lsa_policy
, sids
, pdomains
,
1147 names
, LSA_LOOKUP_NAMES_ALL
,
1149 if (!NT_STATUS_IS_OK(status
)) {
1152 if (NT_STATUS_IS_ERR(result
)) {
1156 if (sids
->num_sids
!= names
->count
) {
1157 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1160 for (i
=0; i
< names
->count
; i
++) {
1161 if (names
->names
[i
].sid_index
== UINT32_MAX
) {
1164 if ((*pdomains
) == NULL
) {
1165 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
1167 if (names
->names
[i
].sid_index
>= (*pdomains
)->count
) {
1168 return NT_STATUS_INVALID_NETWORK_RESPONSE
;