2 Unix SMB/CIFS implementation.
4 Winbind rpc backend functions
6 Copyright (C) Tim Potter 2000-2001,2003
7 Copyright (C) Andrew Tridgell 2001
8 Copyright (C) Volker Lendecke 2005
9 Copyright (C) Guenther Deschner 2008 (pidl conversion)
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #define DBGC_CLASS DBGC_WINBIND
32 /* Query display info for a domain. This returns enough information plus a
33 bit extra to give an overview of domain users for the User Manager
35 static NTSTATUS
query_user_list(struct winbindd_domain
*domain
,
38 WINBIND_USERINFO
**info
)
41 struct policy_handle dom_pol
;
42 unsigned int i
, start_idx
;
44 struct rpc_pipe_client
*cli
;
46 DEBUG(3,("rpc: query_user_list\n"));
51 if ( !winbindd_can_contact_domain( domain
) ) {
52 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
57 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
58 if (!NT_STATUS_IS_OK(result
))
65 uint32 num_dom_users
, j
;
66 uint32 max_entries
, max_size
;
67 uint32_t total_size
, returned_size
;
69 union samr_DispInfo disp_info
;
71 /* this next bit is copied from net_user_list_internal() */
73 get_query_dispinfo_params(loop_count
, &max_entries
,
76 result
= rpccli_samr_QueryDisplayInfo(cli
, mem_ctx
,
85 num_dom_users
= disp_info
.info1
.count
;
86 start_idx
+= disp_info
.info1
.count
;
89 *num_entries
+= num_dom_users
;
91 *info
= TALLOC_REALLOC_ARRAY(mem_ctx
, *info
, WINBIND_USERINFO
,
95 return NT_STATUS_NO_MEMORY
;
98 for (j
= 0; j
< num_dom_users
; i
++, j
++) {
100 uint32_t rid
= disp_info
.info1
.entries
[j
].rid
;
102 (*info
)[i
].acct_name
= talloc_strdup(mem_ctx
,
103 disp_info
.info1
.entries
[j
].account_name
.string
);
104 (*info
)[i
].full_name
= talloc_strdup(mem_ctx
,
105 disp_info
.info1
.entries
[j
].full_name
.string
);
106 (*info
)[i
].homedir
= NULL
;
107 (*info
)[i
].shell
= NULL
;
108 sid_compose(&(*info
)[i
].user_sid
, &domain
->sid
, rid
);
110 /* For the moment we set the primary group for
111 every user to be the Domain Users group.
112 There are serious problems with determining
113 the actual primary group for large domains.
114 This should really be made into a 'winbind
115 force group' smb.conf parameter or
116 something like that. */
118 sid_compose(&(*info
)[i
].group_sid
, &domain
->sid
,
119 DOMAIN_GROUP_RID_USERS
);
122 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
127 /* list all domain groups */
128 static NTSTATUS
enum_dom_groups(struct winbindd_domain
*domain
,
131 struct acct_info
**info
)
133 struct policy_handle dom_pol
;
136 struct rpc_pipe_client
*cli
;
141 DEBUG(3,("rpc: enum_dom_groups\n"));
143 if ( !winbindd_can_contact_domain( domain
) ) {
144 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
149 status
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
150 if (!NT_STATUS_IS_OK(status
))
154 struct samr_SamArray
*sam_array
= NULL
;
156 TALLOC_CTX
*mem_ctx2
;
159 mem_ctx2
= talloc_init("enum_dom_groups[rpc]");
161 /* start is updated by this call. */
162 status
= rpccli_samr_EnumDomainGroups(cli
, mem_ctx2
,
166 0xFFFF, /* buffer size? */
169 if (!NT_STATUS_IS_OK(status
) &&
170 !NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
171 talloc_destroy(mem_ctx2
);
175 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
177 (*num_entries
) + count
);
179 talloc_destroy(mem_ctx2
);
180 return NT_STATUS_NO_MEMORY
;
183 for (g
=0; g
< count
; g
++) {
185 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
186 sam_array
->entries
[g
].name
.string
);
187 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
190 (*num_entries
) += count
;
191 talloc_destroy(mem_ctx2
);
192 } while (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
));
197 /* List all domain groups */
199 static NTSTATUS
enum_local_groups(struct winbindd_domain
*domain
,
202 struct acct_info
**info
)
204 struct policy_handle dom_pol
;
206 struct rpc_pipe_client
*cli
;
211 DEBUG(3,("rpc: enum_local_groups\n"));
213 if ( !winbindd_can_contact_domain( domain
) ) {
214 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
219 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
220 if (!NT_STATUS_IS_OK(result
))
224 struct samr_SamArray
*sam_array
= NULL
;
225 uint32 count
= 0, start
= *num_entries
;
226 TALLOC_CTX
*mem_ctx2
;
229 mem_ctx2
= talloc_init("enum_dom_local_groups[rpc]");
231 result
= rpccli_samr_EnumDomainAliases(cli
, mem_ctx2
,
235 0xFFFF, /* buffer size? */
237 if (!NT_STATUS_IS_OK(result
) &&
238 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
) )
240 talloc_destroy(mem_ctx2
);
244 (*info
) = TALLOC_REALLOC_ARRAY(mem_ctx
, *info
,
246 (*num_entries
) + count
);
248 talloc_destroy(mem_ctx2
);
249 return NT_STATUS_NO_MEMORY
;
252 for (g
=0; g
< count
; g
++) {
254 fstrcpy((*info
)[*num_entries
+ g
].acct_name
,
255 sam_array
->entries
[g
].name
.string
);
256 (*info
)[*num_entries
+ g
].rid
= sam_array
->entries
[g
].idx
;
259 (*num_entries
) += count
;
260 talloc_destroy(mem_ctx2
);
262 } while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
));
267 /* convert a single name to a sid in a domain */
268 static NTSTATUS
msrpc_name_to_sid(struct winbindd_domain
*domain
,
270 enum winbindd_cmd original_cmd
,
271 const char *domain_name
,
274 enum lsa_SidType
*type
)
277 DOM_SID
*sids
= NULL
;
278 enum lsa_SidType
*types
= NULL
;
279 char *full_name
= NULL
;
280 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
281 char *mapped_name
= NULL
;
283 if (name
== NULL
|| *name
=='\0') {
284 full_name
= talloc_asprintf(mem_ctx
, "%s", domain_name
);
285 } else if (domain_name
== NULL
|| *domain_name
== '\0') {
286 full_name
= talloc_asprintf(mem_ctx
, "%s", name
);
288 full_name
= talloc_asprintf(mem_ctx
, "%s\\%s", domain_name
, name
);
291 DEBUG(0, ("talloc_asprintf failed!\n"));
292 return NT_STATUS_NO_MEMORY
;
295 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name
));
297 name_map_status
= normalize_name_unmap(mem_ctx
, full_name
,
300 /* Reset the full_name pointer if we mapped anytthing */
302 if (NT_STATUS_IS_OK(name_map_status
) ||
303 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
305 full_name
= mapped_name
;
308 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
309 full_name
?full_name
:"", domain_name
));
311 result
= winbindd_lookup_names(mem_ctx
, domain
, 1,
312 (const char **)&full_name
, NULL
,
314 if (!NT_STATUS_IS_OK(result
))
317 /* Return rid and type if lookup successful */
319 sid_copy(sid
, &sids
[0]);
326 convert a domain SID to a user or group name
328 static NTSTATUS
msrpc_sid_to_name(struct winbindd_domain
*domain
,
333 enum lsa_SidType
*type
)
337 enum lsa_SidType
*types
= NULL
;
339 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
340 char *mapped_name
= NULL
;
342 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid
),
345 result
= winbindd_lookup_sids(mem_ctx
,
352 if (!NT_STATUS_IS_OK(result
)) {
353 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
359 *type
= (enum lsa_SidType
)types
[0];
360 *domain_name
= domains
[0];
363 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains
[0], *name
));
365 name_map_status
= normalize_name_map(mem_ctx
, domain
, *name
,
367 if (NT_STATUS_IS_OK(name_map_status
) ||
368 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
371 DEBUG(5,("returning mapped name -- %s\n", *name
));
377 static NTSTATUS
msrpc_rids_to_names(struct winbindd_domain
*domain
,
384 enum lsa_SidType
**types
)
392 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain
->name
));
395 sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_rids
);
397 return NT_STATUS_NO_MEMORY
;
403 for (i
=0; i
<num_rids
; i
++) {
404 if (!sid_compose(&sids
[i
], sid
, rids
[i
])) {
405 return NT_STATUS_INTERNAL_ERROR
;
409 result
= winbindd_lookup_sids(mem_ctx
,
417 if (!NT_STATUS_IS_OK(result
) &&
418 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
423 for (i
=0; i
<num_rids
; i
++) {
424 NTSTATUS name_map_status
= NT_STATUS_UNSUCCESSFUL
;
425 char *mapped_name
= NULL
;
427 if ((*types
)[i
] != SID_NAME_UNKNOWN
) {
428 name_map_status
= normalize_name_map(mem_ctx
,
432 if (NT_STATUS_IS_OK(name_map_status
) ||
433 NT_STATUS_EQUAL(name_map_status
, NT_STATUS_FILE_RENAMED
))
435 ret_names
[i
] = mapped_name
;
438 *domain_name
= domains
[i
];
445 /* Lookup user information from a rid or username. */
446 static NTSTATUS
query_user(struct winbindd_domain
*domain
,
448 const DOM_SID
*user_sid
,
449 WINBIND_USERINFO
*user_info
)
451 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
452 struct policy_handle dom_pol
, user_pol
;
453 union samr_UserInfo
*info
= NULL
;
455 struct netr_SamInfo3
*user
;
456 struct rpc_pipe_client
*cli
;
458 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid
)));
460 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
461 return NT_STATUS_UNSUCCESSFUL
;
463 user_info
->homedir
= NULL
;
464 user_info
->shell
= NULL
;
465 user_info
->primary_gid
= (gid_t
)-1;
467 /* try netsamlogon cache first */
469 if ( (user
= netsamlogon_cache_get( mem_ctx
, user_sid
)) != NULL
)
472 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
473 sid_string_dbg(user_sid
)));
475 sid_compose(&user_info
->user_sid
, &domain
->sid
, user
->base
.rid
);
476 sid_compose(&user_info
->group_sid
, &domain
->sid
,
477 user
->base
.primary_gid
);
479 user_info
->acct_name
= talloc_strdup(mem_ctx
,
480 user
->base
.account_name
.string
);
481 user_info
->full_name
= talloc_strdup(mem_ctx
,
482 user
->base
.full_name
.string
);
489 if ( !winbindd_can_contact_domain( domain
) ) {
490 DEBUG(10,("query_user: No incoming trust for domain %s\n",
495 if ( !winbindd_can_contact_domain( domain
) ) {
496 DEBUG(10,("query_user: No incoming trust for domain %s\n",
501 if ( !winbindd_can_contact_domain( domain
) ) {
502 DEBUG(10,("query_user: No incoming trust for domain %s\n",
507 /* no cache; hit the wire */
509 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
510 if (!NT_STATUS_IS_OK(result
))
513 /* Get user handle */
514 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
516 SEC_FLAG_MAXIMUM_ALLOWED
,
520 if (!NT_STATUS_IS_OK(result
))
524 result
= rpccli_samr_QueryUserInfo(cli
, mem_ctx
,
529 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
531 if (!NT_STATUS_IS_OK(result
))
534 sid_compose(&user_info
->user_sid
, &domain
->sid
, user_rid
);
535 sid_compose(&user_info
->group_sid
, &domain
->sid
,
536 info
->info21
.primary_gid
);
537 user_info
->acct_name
= talloc_strdup(mem_ctx
,
538 info
->info21
.account_name
.string
);
539 user_info
->full_name
= talloc_strdup(mem_ctx
,
540 info
->info21
.full_name
.string
);
541 user_info
->homedir
= NULL
;
542 user_info
->shell
= NULL
;
543 user_info
->primary_gid
= (gid_t
)-1;
548 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
549 static NTSTATUS
lookup_usergroups(struct winbindd_domain
*domain
,
551 const DOM_SID
*user_sid
,
552 uint32
*num_groups
, DOM_SID
**user_grpsids
)
554 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
555 struct policy_handle dom_pol
, user_pol
;
556 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
557 struct samr_RidWithAttributeArray
*rid_array
= NULL
;
560 struct rpc_pipe_client
*cli
;
562 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid
)));
564 if (!sid_peek_check_rid(&domain
->sid
, user_sid
, &user_rid
))
565 return NT_STATUS_UNSUCCESSFUL
;
568 *user_grpsids
= NULL
;
570 /* so lets see if we have a cached user_info_3 */
571 result
= lookup_usergroups_cached(domain
, mem_ctx
, user_sid
,
572 num_groups
, user_grpsids
);
574 if (NT_STATUS_IS_OK(result
)) {
578 if ( !winbindd_can_contact_domain( domain
) ) {
579 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
582 /* Tell the cache manager not to remember this one */
584 return NT_STATUS_SYNCHRONIZATION_REQUIRED
;
587 /* no cache; hit the wire */
589 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
590 if (!NT_STATUS_IS_OK(result
))
593 /* Get user handle */
594 result
= rpccli_samr_OpenUser(cli
, mem_ctx
,
600 if (!NT_STATUS_IS_OK(result
))
603 /* Query user rids */
604 result
= rpccli_samr_GetGroupsForUser(cli
, mem_ctx
,
607 *num_groups
= rid_array
->count
;
609 rpccli_samr_Close(cli
, mem_ctx
, &user_pol
);
611 if (!NT_STATUS_IS_OK(result
) || (*num_groups
) == 0)
614 (*user_grpsids
) = TALLOC_ARRAY(mem_ctx
, DOM_SID
, *num_groups
);
615 if (!(*user_grpsids
))
616 return NT_STATUS_NO_MEMORY
;
618 for (i
=0;i
<(*num_groups
);i
++) {
619 sid_copy(&((*user_grpsids
)[i
]), &domain
->sid
);
620 sid_append_rid(&((*user_grpsids
)[i
]),
621 rid_array
->rids
[i
].rid
);
627 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
629 static NTSTATUS
msrpc_lookup_useraliases(struct winbindd_domain
*domain
,
631 uint32 num_sids
, const DOM_SID
*sids
,
635 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
636 struct policy_handle dom_pol
;
637 uint32 num_query_sids
= 0;
639 struct rpc_pipe_client
*cli
;
640 struct samr_Ids alias_rids_query
;
641 int rangesize
= MAX_SAM_ENTRIES_W2K
;
642 uint32 total_sids
= 0;
648 DEBUG(3,("rpc: lookup_useraliases\n"));
650 if ( !winbindd_can_contact_domain( domain
) ) {
651 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
656 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
657 if (!NT_STATUS_IS_OK(result
))
662 struct lsa_SidArray sid_array
;
664 ZERO_STRUCT(sid_array
);
666 num_query_sids
= MIN(num_sids
- total_sids
, rangesize
);
668 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
669 num_queries
, num_query_sids
));
671 if (num_query_sids
) {
672 sid_array
.sids
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_SidPtr
, num_query_sids
);
673 if (sid_array
.sids
== NULL
) {
674 return NT_STATUS_NO_MEMORY
;
677 sid_array
.sids
= NULL
;
680 for (i
=0; i
<num_query_sids
; i
++) {
681 sid_array
.sids
[i
].sid
= sid_dup_talloc(mem_ctx
, &sids
[total_sids
++]);
682 if (!sid_array
.sids
[i
].sid
) {
683 TALLOC_FREE(sid_array
.sids
);
684 return NT_STATUS_NO_MEMORY
;
687 sid_array
.num_sids
= num_query_sids
;
690 result
= rpccli_samr_GetAliasMembership(cli
, mem_ctx
,
695 if (!NT_STATUS_IS_OK(result
)) {
698 TALLOC_FREE(sid_array
.sids
);
704 for (i
=0; i
<alias_rids_query
.count
; i
++) {
705 size_t na
= *num_aliases
;
706 if (!add_rid_to_array_unique(mem_ctx
, alias_rids_query
.ids
[i
],
708 return NT_STATUS_NO_MEMORY
;
713 TALLOC_FREE(sid_array
.sids
);
717 } while (total_sids
< num_sids
);
720 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
721 "(rangesize: %d)\n", *num_aliases
, num_queries
, rangesize
));
727 /* Lookup group membership given a rid. */
728 static NTSTATUS
lookup_groupmem(struct winbindd_domain
*domain
,
730 const DOM_SID
*group_sid
, uint32
*num_names
,
731 DOM_SID
**sid_mem
, char ***names
,
734 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
735 uint32 i
, total_names
= 0;
736 struct policy_handle dom_pol
, group_pol
;
737 uint32 des_access
= SEC_FLAG_MAXIMUM_ALLOWED
;
738 uint32
*rid_mem
= NULL
;
741 struct rpc_pipe_client
*cli
;
742 unsigned int orig_timeout
;
743 struct samr_RidTypeArray
*rids
= NULL
;
745 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain
->name
,
746 sid_string_dbg(group_sid
)));
748 if ( !winbindd_can_contact_domain( domain
) ) {
749 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
754 if (!sid_peek_check_rid(&domain
->sid
, group_sid
, &group_rid
))
755 return NT_STATUS_UNSUCCESSFUL
;
759 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
760 if (!NT_STATUS_IS_OK(result
))
763 result
= rpccli_samr_OpenGroup(cli
, mem_ctx
,
769 if (!NT_STATUS_IS_OK(result
))
772 /* Step #1: Get a list of user rids that are the members of the
775 /* This call can take a long time - allow the server to time out.
776 35 seconds should do it. */
778 orig_timeout
= rpccli_set_timeout(cli
, 35000);
780 result
= rpccli_samr_QueryGroupMember(cli
, mem_ctx
,
784 /* And restore our original timeout. */
785 rpccli_set_timeout(cli
, orig_timeout
);
787 rpccli_samr_Close(cli
, mem_ctx
, &group_pol
);
789 if (!NT_STATUS_IS_OK(result
))
792 *num_names
= rids
->count
;
793 rid_mem
= rids
->rids
;
802 /* Step #2: Convert list of rids into list of usernames. Do this
803 in bunches of ~1000 to avoid crashing NT4. It looks like there
804 is a buffer overflow or something like that lurking around
807 #define MAX_LOOKUP_RIDS 900
809 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, *num_names
);
810 *name_types
= TALLOC_ZERO_ARRAY(mem_ctx
, uint32
, *num_names
);
811 *sid_mem
= TALLOC_ZERO_ARRAY(mem_ctx
, DOM_SID
, *num_names
);
813 for (j
=0;j
<(*num_names
);j
++)
814 sid_compose(&(*sid_mem
)[j
], &domain
->sid
, rid_mem
[j
]);
816 if (*num_names
>0 && (!*names
|| !*name_types
))
817 return NT_STATUS_NO_MEMORY
;
819 for (i
= 0; i
< *num_names
; i
+= MAX_LOOKUP_RIDS
) {
820 int num_lookup_rids
= MIN(*num_names
- i
, MAX_LOOKUP_RIDS
);
821 struct lsa_Strings tmp_names
;
822 struct samr_Ids tmp_types
;
824 /* Lookup a chunk of rids */
826 result
= rpccli_samr_LookupRids(cli
, mem_ctx
,
833 /* see if we have a real error (and yes the
834 STATUS_SOME_UNMAPPED is the one returned from 2k) */
836 if (!NT_STATUS_IS_OK(result
) &&
837 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
))
840 /* Copy result into array. The talloc system will take
841 care of freeing the temporary arrays later on. */
843 if (tmp_names
.count
!= tmp_types
.count
) {
844 return NT_STATUS_UNSUCCESSFUL
;
847 for (r
=0; r
<tmp_names
.count
; r
++) {
848 if (tmp_types
.ids
[r
] == SID_NAME_UNKNOWN
) {
851 (*names
)[total_names
] = fill_domain_username_talloc(
852 mem_ctx
, domain
->name
,
853 tmp_names
.names
[r
].string
, true);
854 (*name_types
)[total_names
] = tmp_types
.ids
[r
];
859 *num_names
= total_names
;
868 static int get_ldap_seq(const char *server
, int port
, uint32
*seq
)
872 const char *attrs
[] = {"highestCommittedUSN", NULL
};
873 LDAPMessage
*res
= NULL
;
874 char **values
= NULL
;
877 *seq
= DOM_SEQUENCE_NONE
;
880 * Parameterised (5) second timeout on open. This is needed as the
881 * search timeout doesn't seem to apply to doing an open as well. JRA.
884 ldp
= ldap_open_with_timeout(server
, port
, lp_ldap_timeout());
888 /* Timeout if no response within 20 seconds. */
892 if (ldap_search_st(ldp
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
893 CONST_DISCARD(char **, attrs
), 0, &to
, &res
))
896 if (ldap_count_entries(ldp
, res
) != 1)
899 values
= ldap_get_values(ldp
, res
, "highestCommittedUSN");
900 if (!values
|| !values
[0])
903 *seq
= atoi(values
[0]);
909 ldap_value_free(values
);
917 /**********************************************************************
918 Get the sequence number for a Windows AD native mode domain using
920 **********************************************************************/
922 static int get_ldap_sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
925 char addr
[INET6_ADDRSTRLEN
];
927 print_sockaddr(addr
, sizeof(addr
), &domain
->dcaddr
);
928 if ((ret
= get_ldap_seq(addr
, LDAP_PORT
, seq
)) == 0) {
929 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
930 "number for Domain (%s) from DC (%s)\n",
931 domain
->name
, addr
));
936 #endif /* HAVE_LDAP */
938 /* find the sequence number for a domain */
939 static NTSTATUS
sequence_number(struct winbindd_domain
*domain
, uint32
*seq
)
942 union samr_DomainInfo
*info
= NULL
;
944 struct policy_handle dom_pol
;
945 bool got_seq_num
= False
;
946 struct rpc_pipe_client
*cli
;
948 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain
->name
));
950 if ( !winbindd_can_contact_domain( domain
) ) {
951 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
957 *seq
= DOM_SEQUENCE_NONE
;
959 if (!(mem_ctx
= talloc_init("sequence_number[rpc]")))
960 return NT_STATUS_NO_MEMORY
;
963 if ( domain
->active_directory
)
967 DEBUG(8,("using get_ldap_seq() to retrieve the "
968 "sequence number\n"));
970 res
= get_ldap_sequence_number( domain
, seq
);
973 result
= NT_STATUS_OK
;
974 DEBUG(10,("domain_sequence_number: LDAP for "
976 domain
->name
, *seq
));
980 DEBUG(10,("domain_sequence_number: failed to get LDAP "
981 "sequence number for domain %s\n",
984 #endif /* HAVE_LDAP */
986 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
987 if (!NT_STATUS_IS_OK(result
)) {
991 /* Query domain info */
993 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
998 if (NT_STATUS_IS_OK(result
)) {
999 *seq
= info
->info8
.sequence_num
;
1004 /* retry with info-level 2 in case the dc does not support info-level 8
1005 * (like all older samba2 and samba3 dc's) - Guenther */
1007 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1012 if (NT_STATUS_IS_OK(result
)) {
1013 *seq
= info
->general
.sequence_num
;
1019 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1020 domain
->name
, (unsigned)*seq
));
1022 DEBUG(10,("domain_sequence_number: failed to get sequence "
1023 "number (%u) for domain %s\n",
1024 (unsigned)*seq
, domain
->name
));
1029 talloc_destroy(mem_ctx
);
1034 /* get a list of trusted domains */
1035 static NTSTATUS
trusted_domains(struct winbindd_domain
*domain
,
1036 TALLOC_CTX
*mem_ctx
,
1037 uint32
*num_domains
,
1042 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1043 uint32 enum_ctx
= 0;
1044 struct rpc_pipe_client
*cli
;
1045 struct policy_handle lsa_policy
;
1047 DEBUG(3,("rpc: trusted_domains\n"));
1054 result
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1055 if (!NT_STATUS_IS_OK(result
))
1058 result
= STATUS_MORE_ENTRIES
;
1060 while (NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
)) {
1063 struct lsa_DomainList dom_list
;
1065 result
= rpccli_lsa_EnumTrustDom(cli
, mem_ctx
,
1071 if (!NT_STATUS_IS_OK(result
) &&
1072 !NT_STATUS_EQUAL(result
, STATUS_MORE_ENTRIES
))
1075 start_idx
= *num_domains
;
1076 *num_domains
+= dom_list
.count
;
1077 *names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *names
,
1078 char *, *num_domains
);
1079 *dom_sids
= TALLOC_REALLOC_ARRAY(mem_ctx
, *dom_sids
,
1080 DOM_SID
, *num_domains
);
1081 *alt_names
= TALLOC_REALLOC_ARRAY(mem_ctx
, *alt_names
,
1082 char *, *num_domains
);
1083 if ((*names
== NULL
) || (*dom_sids
== NULL
) ||
1084 (*alt_names
== NULL
))
1085 return NT_STATUS_NO_MEMORY
;
1087 for (i
=0; i
<dom_list
.count
; i
++) {
1088 (*names
)[start_idx
+i
] = CONST_DISCARD(char *, dom_list
.domains
[i
].name
.string
);
1089 (*dom_sids
)[start_idx
+i
] = *dom_list
.domains
[i
].sid
;
1090 (*alt_names
)[start_idx
+i
] = talloc_strdup(mem_ctx
, "");
1096 /* find the lockout policy for a domain */
1097 static NTSTATUS
msrpc_lockout_policy(struct winbindd_domain
*domain
,
1098 TALLOC_CTX
*mem_ctx
,
1099 struct samr_DomInfo12
*lockout_policy
)
1102 struct rpc_pipe_client
*cli
;
1103 struct policy_handle dom_pol
;
1104 union samr_DomainInfo
*info
= NULL
;
1106 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain
->name
));
1108 if ( !winbindd_can_contact_domain( domain
) ) {
1109 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1111 return NT_STATUS_NOT_SUPPORTED
;
1114 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1115 if (!NT_STATUS_IS_OK(result
)) {
1119 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1123 if (!NT_STATUS_IS_OK(result
)) {
1127 *lockout_policy
= info
->info12
;
1129 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1130 info
->info12
.lockout_threshold
));
1137 /* find the password policy for a domain */
1138 static NTSTATUS
msrpc_password_policy(struct winbindd_domain
*domain
,
1139 TALLOC_CTX
*mem_ctx
,
1140 struct samr_DomInfo1
*password_policy
)
1143 struct rpc_pipe_client
*cli
;
1144 struct policy_handle dom_pol
;
1145 union samr_DomainInfo
*info
= NULL
;
1147 DEBUG(10,("rpc: fetch password policy for %s\n", domain
->name
));
1149 if ( !winbindd_can_contact_domain( domain
) ) {
1150 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1152 return NT_STATUS_NOT_SUPPORTED
;
1155 result
= cm_connect_sam(domain
, mem_ctx
, &cli
, &dom_pol
);
1156 if (!NT_STATUS_IS_OK(result
)) {
1160 result
= rpccli_samr_QueryDomainInfo(cli
, mem_ctx
,
1164 if (!NT_STATUS_IS_OK(result
)) {
1168 *password_policy
= info
->info1
;
1170 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1171 info
->info1
.min_password_length
));
1178 typedef NTSTATUS (*lookup_sids_fn_t
)(struct rpc_pipe_client
*cli
,
1179 TALLOC_CTX
*mem_ctx
,
1180 struct policy_handle
*pol
,
1182 const DOM_SID
*sids
,
1185 enum lsa_SidType
**ptypes
);
1187 NTSTATUS
winbindd_lookup_sids(TALLOC_CTX
*mem_ctx
,
1188 struct winbindd_domain
*domain
,
1190 const struct dom_sid
*sids
,
1193 enum lsa_SidType
**types
)
1196 struct rpc_pipe_client
*cli
= NULL
;
1197 struct policy_handle lsa_policy
;
1198 unsigned int orig_timeout
;
1199 lookup_sids_fn_t lookup_sids_fn
= rpccli_lsa_lookup_sids
;
1201 if (domain
->can_do_ncacn_ip_tcp
) {
1202 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1203 if (NT_STATUS_IS_OK(status
)) {
1204 lookup_sids_fn
= rpccli_lsa_lookup_sids3
;
1207 domain
->can_do_ncacn_ip_tcp
= false;
1209 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1211 if (!NT_STATUS_IS_OK(status
)) {
1217 * This call can take a long time
1218 * allow the server to time out.
1219 * 35 seconds should do it.
1221 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1223 status
= lookup_sids_fn(cli
,
1232 /* And restore our original timeout. */
1233 rpccli_set_timeout(cli
, orig_timeout
);
1235 if (!NT_STATUS_IS_OK(status
)) {
1242 typedef NTSTATUS (*lookup_names_fn_t
)(struct rpc_pipe_client
*cli
,
1243 TALLOC_CTX
*mem_ctx
,
1244 struct policy_handle
*pol
,
1247 const char ***dom_names
,
1249 struct dom_sid
**sids
,
1250 enum lsa_SidType
**types
);
1252 NTSTATUS
winbindd_lookup_names(TALLOC_CTX
*mem_ctx
,
1253 struct winbindd_domain
*domain
,
1256 const char ***domains
,
1257 struct dom_sid
**sids
,
1258 enum lsa_SidType
**types
)
1261 struct rpc_pipe_client
*cli
= NULL
;
1262 struct policy_handle lsa_policy
;
1263 unsigned int orig_timeout
;
1264 lookup_names_fn_t lookup_names_fn
= rpccli_lsa_lookup_names
;
1266 if (domain
->can_do_ncacn_ip_tcp
) {
1267 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, &cli
);
1268 if (NT_STATUS_IS_OK(status
)) {
1269 lookup_names_fn
= rpccli_lsa_lookup_names4
;
1272 domain
->can_do_ncacn_ip_tcp
= false;
1274 status
= cm_connect_lsa(domain
, mem_ctx
, &cli
, &lsa_policy
);
1276 if (!NT_STATUS_IS_OK(status
)) {
1283 * This call can take a long time
1284 * allow the server to time out.
1285 * 35 seconds should do it.
1287 orig_timeout
= rpccli_set_timeout(cli
, 35000);
1289 status
= lookup_names_fn(cli
,
1293 (const char **) names
,
1299 /* And restore our original timeout. */
1300 rpccli_set_timeout(cli
, orig_timeout
);
1302 if (!NT_STATUS_IS_OK(status
)) {
1309 /* the rpc backend methods are exposed via this structure */
1310 struct winbindd_methods msrpc_methods
= {
1317 msrpc_rids_to_names
,
1320 msrpc_lookup_useraliases
,
1323 msrpc_lockout_policy
,
1324 msrpc_password_policy
,