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)
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)
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)
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 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 struct rpc_pipe_client *cli;
281 POLICY_HND lsa_policy;
282 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
283 char *mapped_name = NULL;
285 if (name == NULL || *name=='\0') {
286 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
287 } else if (domain_name == NULL || *domain_name == '\0') {
288 full_name = talloc_asprintf(mem_ctx, "%s", name);
290 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
293 DEBUG(0, ("talloc_asprintf failed!\n"));
294 return NT_STATUS_NO_MEMORY;
297 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
299 name_map_status = normalize_name_unmap(mem_ctx, full_name,
302 /* Reset the full_name pointer if we mapped anytthing */
304 if (NT_STATUS_IS_OK(name_map_status) ||
305 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
307 full_name = mapped_name;
310 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
311 full_name?full_name:"", domain_name ));
313 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
314 if (!NT_STATUS_IS_OK(result))
317 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
318 (const char**) &full_name, NULL, 1, &sids, &types);
320 if (!NT_STATUS_IS_OK(result))
323 /* Return rid and type if lookup successful */
325 sid_copy(sid, &sids[0]);
332 convert a domain SID to a user or group name
334 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
339 enum lsa_SidType *type)
343 enum lsa_SidType *types = NULL;
345 struct rpc_pipe_client *cli;
346 POLICY_HND lsa_policy;
347 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
348 char *mapped_name = NULL;
350 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
353 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
354 if (!NT_STATUS_IS_OK(result)) {
355 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
361 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
362 1, sid, &domains, &names, &types);
363 if (!NT_STATUS_IS_OK(result)) {
364 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
369 *type = (enum lsa_SidType)types[0];
370 *domain_name = domains[0];
373 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
375 name_map_status = normalize_name_map(mem_ctx, domain, *name,
377 if (NT_STATUS_IS_OK(name_map_status) ||
378 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
381 DEBUG(5,("returning mapped name -- %s\n", *name));
387 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
394 enum lsa_SidType **types)
398 struct rpc_pipe_client *cli;
399 POLICY_HND lsa_policy;
404 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
407 sids = TALLOC_ARRAY(mem_ctx, 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 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
422 if (!NT_STATUS_IS_OK(result)) {
426 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
427 num_rids, sids, &domains,
429 if (!NT_STATUS_IS_OK(result) &&
430 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
435 for (i=0; i<num_rids; i++) {
436 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
437 char *mapped_name = NULL;
439 if ((*types)[i] != SID_NAME_UNKNOWN) {
440 name_map_status = normalize_name_map(mem_ctx,
444 if (NT_STATUS_IS_OK(name_map_status) ||
445 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
447 ret_names[i] = mapped_name;
450 *domain_name = domains[i];
457 /* Lookup user information from a rid or username. */
458 static NTSTATUS query_user(struct winbindd_domain *domain,
460 const DOM_SID *user_sid,
461 WINBIND_USERINFO *user_info)
463 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
464 POLICY_HND dom_pol, user_pol;
465 union samr_UserInfo *info = NULL;
467 struct netr_SamInfo3 *user;
468 struct rpc_pipe_client *cli;
470 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
472 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
473 return NT_STATUS_UNSUCCESSFUL;
475 user_info->homedir = NULL;
476 user_info->shell = NULL;
477 user_info->primary_gid = (gid_t)-1;
479 /* try netsamlogon cache first */
481 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
484 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
485 sid_string_dbg(user_sid)));
487 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
488 sid_compose(&user_info->group_sid, &domain->sid,
489 user->base.primary_gid);
491 user_info->acct_name = talloc_strdup(mem_ctx,
492 user->base.account_name.string);
493 user_info->full_name = talloc_strdup(mem_ctx,
494 user->base.full_name.string);
501 if ( !winbindd_can_contact_domain( domain ) ) {
502 DEBUG(10,("query_user: No incoming trust for domain %s\n",
507 if ( !winbindd_can_contact_domain( domain ) ) {
508 DEBUG(10,("query_user: No incoming trust for domain %s\n",
513 if ( !winbindd_can_contact_domain( domain ) ) {
514 DEBUG(10,("query_user: No incoming trust for domain %s\n",
519 /* no cache; hit the wire */
521 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
522 if (!NT_STATUS_IS_OK(result))
525 /* Get user handle */
526 result = rpccli_samr_OpenUser(cli, mem_ctx,
528 SEC_RIGHTS_MAXIMUM_ALLOWED,
532 if (!NT_STATUS_IS_OK(result))
536 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
541 rpccli_samr_Close(cli, mem_ctx, &user_pol);
543 if (!NT_STATUS_IS_OK(result))
546 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
547 sid_compose(&user_info->group_sid, &domain->sid,
548 info->info21.primary_gid);
549 user_info->acct_name = talloc_strdup(mem_ctx,
550 info->info21.account_name.string);
551 user_info->full_name = talloc_strdup(mem_ctx,
552 info->info21.full_name.string);
553 user_info->homedir = NULL;
554 user_info->shell = NULL;
555 user_info->primary_gid = (gid_t)-1;
560 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
561 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
563 const DOM_SID *user_sid,
564 uint32 *num_groups, DOM_SID **user_grpsids)
566 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
567 POLICY_HND dom_pol, user_pol;
568 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
569 struct samr_RidWithAttributeArray *rid_array = NULL;
572 struct rpc_pipe_client *cli;
574 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
576 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
577 return NT_STATUS_UNSUCCESSFUL;
580 *user_grpsids = NULL;
582 /* so lets see if we have a cached user_info_3 */
583 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
584 num_groups, user_grpsids);
586 if (NT_STATUS_IS_OK(result)) {
590 if ( !winbindd_can_contact_domain( domain ) ) {
591 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
594 /* Tell the cache manager not to remember this one */
596 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
599 /* no cache; hit the wire */
601 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
602 if (!NT_STATUS_IS_OK(result))
605 /* Get user handle */
606 result = rpccli_samr_OpenUser(cli, mem_ctx,
612 if (!NT_STATUS_IS_OK(result))
615 /* Query user rids */
616 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
619 *num_groups = rid_array->count;
621 rpccli_samr_Close(cli, mem_ctx, &user_pol);
623 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
626 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
627 if (!(*user_grpsids))
628 return NT_STATUS_NO_MEMORY;
630 for (i=0;i<(*num_groups);i++) {
631 sid_copy(&((*user_grpsids)[i]), &domain->sid);
632 sid_append_rid(&((*user_grpsids)[i]),
633 rid_array->rids[i].rid);
639 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
641 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
643 uint32 num_sids, const DOM_SID *sids,
644 uint32 *num_aliases, uint32 **alias_rids)
646 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
648 uint32 num_query_sids = 0;
650 struct rpc_pipe_client *cli;
651 struct samr_Ids alias_rids_query;
652 int rangesize = MAX_SAM_ENTRIES_W2K;
653 uint32 total_sids = 0;
659 DEBUG(3,("rpc: lookup_useraliases\n"));
661 if ( !winbindd_can_contact_domain( domain ) ) {
662 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
667 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
668 if (!NT_STATUS_IS_OK(result))
673 struct lsa_SidArray sid_array;
675 ZERO_STRUCT(sid_array);
677 num_query_sids = MIN(num_sids - total_sids, rangesize);
679 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
680 num_queries, num_query_sids));
682 if (num_query_sids) {
683 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
684 if (sid_array.sids == NULL) {
685 return NT_STATUS_NO_MEMORY;
688 sid_array.sids = NULL;
691 for (i=0; i<num_query_sids; i++) {
692 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
693 if (!sid_array.sids[i].sid) {
694 TALLOC_FREE(sid_array.sids);
695 return NT_STATUS_NO_MEMORY;
698 sid_array.num_sids = num_query_sids;
701 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
706 if (!NT_STATUS_IS_OK(result)) {
709 TALLOC_FREE(sid_array.sids);
715 for (i=0; i<alias_rids_query.count; i++) {
716 size_t na = *num_aliases;
717 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
719 return NT_STATUS_NO_MEMORY;
724 TALLOC_FREE(sid_array.sids);
728 } while (total_sids < num_sids);
731 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
732 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
738 /* Lookup group membership given a rid. */
739 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
741 const DOM_SID *group_sid, uint32 *num_names,
742 DOM_SID **sid_mem, char ***names,
745 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
746 uint32 i, total_names = 0;
747 POLICY_HND dom_pol, group_pol;
748 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
749 uint32 *rid_mem = NULL;
752 struct rpc_pipe_client *cli;
753 unsigned int orig_timeout;
754 struct samr_RidTypeArray *rids = NULL;
756 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
757 sid_string_dbg(group_sid)));
759 if ( !winbindd_can_contact_domain( domain ) ) {
760 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
765 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
766 return NT_STATUS_UNSUCCESSFUL;
770 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
771 if (!NT_STATUS_IS_OK(result))
774 result = rpccli_samr_OpenGroup(cli, mem_ctx,
780 if (!NT_STATUS_IS_OK(result))
783 /* Step #1: Get a list of user rids that are the members of the
786 /* This call can take a long time - allow the server to time out.
787 35 seconds should do it. */
789 orig_timeout = rpccli_set_timeout(cli, 35000);
791 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
795 /* And restore our original timeout. */
796 rpccli_set_timeout(cli, orig_timeout);
798 rpccli_samr_Close(cli, mem_ctx, &group_pol);
800 if (!NT_STATUS_IS_OK(result))
803 *num_names = rids->count;
804 rid_mem = rids->rids;
813 /* Step #2: Convert list of rids into list of usernames. Do this
814 in bunches of ~1000 to avoid crashing NT4. It looks like there
815 is a buffer overflow or something like that lurking around
818 #define MAX_LOOKUP_RIDS 900
820 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
821 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
822 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
824 for (j=0;j<(*num_names);j++)
825 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
827 if (*num_names>0 && (!*names || !*name_types))
828 return NT_STATUS_NO_MEMORY;
830 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
831 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
832 struct lsa_Strings tmp_names;
833 struct samr_Ids tmp_types;
835 /* Lookup a chunk of rids */
837 result = rpccli_samr_LookupRids(cli, mem_ctx,
844 /* see if we have a real error (and yes the
845 STATUS_SOME_UNMAPPED is the one returned from 2k) */
847 if (!NT_STATUS_IS_OK(result) &&
848 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
851 /* Copy result into array. The talloc system will take
852 care of freeing the temporary arrays later on. */
854 if (tmp_names.count != tmp_types.count) {
855 return NT_STATUS_UNSUCCESSFUL;
858 for (r=0; r<tmp_names.count; r++) {
859 (*names)[i+r] = fill_domain_username_talloc(mem_ctx,
861 tmp_names.names[r].string,
863 (*name_types)[i+r] = tmp_types.ids[r];
866 total_names += tmp_names.count;
869 *num_names = total_names;
878 static int get_ldap_seq(const char *server, int port, uint32 *seq)
882 const char *attrs[] = {"highestCommittedUSN", NULL};
883 LDAPMessage *res = NULL;
884 char **values = NULL;
887 *seq = DOM_SEQUENCE_NONE;
890 * Parameterised (5) second timeout on open. This is needed as the
891 * search timeout doesn't seem to apply to doing an open as well. JRA.
894 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
898 /* Timeout if no response within 20 seconds. */
902 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
903 CONST_DISCARD(char **, attrs), 0, &to, &res))
906 if (ldap_count_entries(ldp, res) != 1)
909 values = ldap_get_values(ldp, res, "highestCommittedUSN");
910 if (!values || !values[0])
913 *seq = atoi(values[0]);
919 ldap_value_free(values);
927 /**********************************************************************
928 Get the sequence number for a Windows AD native mode domain using
930 **********************************************************************/
932 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
935 char addr[INET6_ADDRSTRLEN];
937 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
938 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
939 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
940 "number for Domain (%s) from DC (%s)\n",
941 domain->name, addr));
946 #endif /* HAVE_LDAP */
948 /* find the sequence number for a domain */
949 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
952 union samr_DomainInfo *info = NULL;
955 bool got_seq_num = False;
956 struct rpc_pipe_client *cli;
958 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
960 if ( !winbindd_can_contact_domain( domain ) ) {
961 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
967 *seq = DOM_SEQUENCE_NONE;
969 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
970 return NT_STATUS_NO_MEMORY;
973 if ( domain->active_directory )
977 DEBUG(8,("using get_ldap_seq() to retrieve the "
978 "sequence number\n"));
980 res = get_ldap_sequence_number( domain, seq );
983 result = NT_STATUS_OK;
984 DEBUG(10,("domain_sequence_number: LDAP for "
986 domain->name, *seq));
990 DEBUG(10,("domain_sequence_number: failed to get LDAP "
991 "sequence number for domain %s\n",
994 #endif /* HAVE_LDAP */
996 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
997 if (!NT_STATUS_IS_OK(result)) {
1001 /* Query domain info */
1003 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1008 if (NT_STATUS_IS_OK(result)) {
1009 *seq = info->info8.sequence_num;
1014 /* retry with info-level 2 in case the dc does not support info-level 8
1015 * (like all older samba2 and samba3 dc's) - Guenther */
1017 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1022 if (NT_STATUS_IS_OK(result)) {
1023 *seq = info->general.sequence_num;
1029 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1030 domain->name, (unsigned)*seq));
1032 DEBUG(10,("domain_sequence_number: failed to get sequence "
1033 "number (%u) for domain %s\n",
1034 (unsigned)*seq, domain->name ));
1039 talloc_destroy(mem_ctx);
1044 /* get a list of trusted domains */
1045 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1046 TALLOC_CTX *mem_ctx,
1047 uint32 *num_domains,
1052 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1053 uint32 enum_ctx = 0;
1054 struct rpc_pipe_client *cli;
1055 POLICY_HND lsa_policy;
1057 DEBUG(3,("rpc: trusted_domains\n"));
1064 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1065 if (!NT_STATUS_IS_OK(result))
1068 result = STATUS_MORE_ENTRIES;
1070 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1073 struct lsa_DomainList dom_list;
1075 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1081 if (!NT_STATUS_IS_OK(result) &&
1082 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1085 start_idx = *num_domains;
1086 *num_domains += dom_list.count;
1087 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1088 char *, *num_domains);
1089 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1090 DOM_SID, *num_domains);
1091 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1092 char *, *num_domains);
1093 if ((*names == NULL) || (*dom_sids == NULL) ||
1094 (*alt_names == NULL))
1095 return NT_STATUS_NO_MEMORY;
1097 for (i=0; i<dom_list.count; i++) {
1098 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1099 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1100 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1106 /* find the lockout policy for a domain */
1107 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1108 TALLOC_CTX *mem_ctx,
1109 struct samr_DomInfo12 *lockout_policy)
1112 struct rpc_pipe_client *cli;
1114 union samr_DomainInfo *info = NULL;
1116 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1118 if ( !winbindd_can_contact_domain( domain ) ) {
1119 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1121 return NT_STATUS_NOT_SUPPORTED;
1124 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1125 if (!NT_STATUS_IS_OK(result)) {
1129 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1133 if (!NT_STATUS_IS_OK(result)) {
1137 *lockout_policy = info->info12;
1139 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1140 info->info12.lockout_threshold));
1147 /* find the password policy for a domain */
1148 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1149 TALLOC_CTX *mem_ctx,
1150 struct samr_DomInfo1 *password_policy)
1153 struct rpc_pipe_client *cli;
1155 union samr_DomainInfo *info = NULL;
1157 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1159 if ( !winbindd_can_contact_domain( domain ) ) {
1160 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1162 return NT_STATUS_NOT_SUPPORTED;
1165 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1166 if (!NT_STATUS_IS_OK(result)) {
1170 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1174 if (!NT_STATUS_IS_OK(result)) {
1178 *password_policy = info->info1;
1180 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1181 info->info1.min_password_length));
1189 /* the rpc backend methods are exposed via this structure */
1190 struct winbindd_methods msrpc_methods = {
1197 msrpc_rids_to_names,
1200 msrpc_lookup_useraliases,
1203 msrpc_lockout_policy,
1204 msrpc_password_policy,