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 struct wbint_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,
92 struct wbint_userinfo,
96 return NT_STATUS_NO_MEMORY;
99 for (j = 0; j < num_dom_users; i++, j++) {
101 uint32_t rid = disp_info.info1.entries[j].rid;
103 (*info)[i].acct_name = talloc_strdup(mem_ctx,
104 disp_info.info1.entries[j].account_name.string);
105 (*info)[i].full_name = talloc_strdup(mem_ctx,
106 disp_info.info1.entries[j].full_name.string);
107 (*info)[i].homedir = NULL;
108 (*info)[i].shell = NULL;
109 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
111 /* For the moment we set the primary group for
112 every user to be the Domain Users group.
113 There are serious problems with determining
114 the actual primary group for large domains.
115 This should really be made into a 'winbind
116 force group' smb.conf parameter or
117 something like that. */
119 sid_compose(&(*info)[i].group_sid, &domain->sid,
120 DOMAIN_GROUP_RID_USERS);
123 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
128 /* list all domain groups */
129 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
132 struct acct_info **info)
134 struct policy_handle dom_pol;
137 struct rpc_pipe_client *cli;
142 DEBUG(3,("rpc: enum_dom_groups\n"));
144 if ( !winbindd_can_contact_domain( domain ) ) {
145 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
150 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
151 if (!NT_STATUS_IS_OK(status))
155 struct samr_SamArray *sam_array = NULL;
157 TALLOC_CTX *mem_ctx2;
160 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
162 /* start is updated by this call. */
163 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
167 0xFFFF, /* buffer size? */
170 if (!NT_STATUS_IS_OK(status) &&
171 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
172 talloc_destroy(mem_ctx2);
176 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
178 (*num_entries) + count);
180 talloc_destroy(mem_ctx2);
181 return NT_STATUS_NO_MEMORY;
184 for (g=0; g < count; g++) {
186 fstrcpy((*info)[*num_entries + g].acct_name,
187 sam_array->entries[g].name.string);
188 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
191 (*num_entries) += count;
192 talloc_destroy(mem_ctx2);
193 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
198 /* List all domain groups */
200 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
203 struct acct_info **info)
205 struct policy_handle dom_pol;
207 struct rpc_pipe_client *cli;
212 DEBUG(3,("rpc: enum_local_groups\n"));
214 if ( !winbindd_can_contact_domain( domain ) ) {
215 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
220 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
221 if (!NT_STATUS_IS_OK(result))
225 struct samr_SamArray *sam_array = NULL;
226 uint32 count = 0, start = *num_entries;
227 TALLOC_CTX *mem_ctx2;
230 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
232 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
236 0xFFFF, /* buffer size? */
238 if (!NT_STATUS_IS_OK(result) &&
239 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
241 talloc_destroy(mem_ctx2);
245 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
247 (*num_entries) + count);
249 talloc_destroy(mem_ctx2);
250 return NT_STATUS_NO_MEMORY;
253 for (g=0; g < count; g++) {
255 fstrcpy((*info)[*num_entries + g].acct_name,
256 sam_array->entries[g].name.string);
257 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
260 (*num_entries) += count;
261 talloc_destroy(mem_ctx2);
263 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
268 /* convert a single name to a sid in a domain */
269 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
271 const char *domain_name,
275 enum lsa_SidType *type)
278 DOM_SID *sids = NULL;
279 enum lsa_SidType *types = NULL;
280 char *full_name = NULL;
281 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
282 char *mapped_name = NULL;
284 if (name == NULL || *name=='\0') {
285 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
286 } else if (domain_name == NULL || *domain_name == '\0') {
287 full_name = talloc_asprintf(mem_ctx, "%s", name);
289 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
292 DEBUG(0, ("talloc_asprintf failed!\n"));
293 return NT_STATUS_NO_MEMORY;
296 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
298 name_map_status = normalize_name_unmap(mem_ctx, full_name,
301 /* Reset the full_name pointer if we mapped anytthing */
303 if (NT_STATUS_IS_OK(name_map_status) ||
304 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
306 full_name = mapped_name;
309 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
310 full_name?full_name:"", domain_name ));
312 result = winbindd_lookup_names(mem_ctx, domain, 1,
313 (const char **)&full_name, NULL,
315 if (!NT_STATUS_IS_OK(result))
318 /* Return rid and type if lookup successful */
320 sid_copy(sid, &sids[0]);
327 convert a domain SID to a user or group name
329 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
334 enum lsa_SidType *type)
338 enum lsa_SidType *types = NULL;
340 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
341 char *mapped_name = NULL;
343 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
346 result = winbindd_lookup_sids(mem_ctx,
353 if (!NT_STATUS_IS_OK(result)) {
354 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
360 *type = (enum lsa_SidType)types[0];
361 *domain_name = domains[0];
364 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
366 name_map_status = normalize_name_map(mem_ctx, domain, *name,
368 if (NT_STATUS_IS_OK(name_map_status) ||
369 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
372 DEBUG(5,("returning mapped name -- %s\n", *name));
378 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
385 enum lsa_SidType **types)
393 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
396 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
398 return NT_STATUS_NO_MEMORY;
404 for (i=0; i<num_rids; i++) {
405 if (!sid_compose(&sids[i], sid, rids[i])) {
406 return NT_STATUS_INTERNAL_ERROR;
410 result = winbindd_lookup_sids(mem_ctx,
418 if (!NT_STATUS_IS_OK(result) &&
419 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
424 for (i=0; i<num_rids; i++) {
425 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
426 char *mapped_name = NULL;
428 if ((*types)[i] != SID_NAME_UNKNOWN) {
429 name_map_status = normalize_name_map(mem_ctx,
433 if (NT_STATUS_IS_OK(name_map_status) ||
434 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
436 ret_names[i] = mapped_name;
439 *domain_name = domains[i];
446 /* Lookup user information from a rid or username. */
447 static NTSTATUS query_user(struct winbindd_domain *domain,
449 const DOM_SID *user_sid,
450 struct wbint_userinfo *user_info)
452 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
453 struct policy_handle dom_pol, user_pol;
454 union samr_UserInfo *info = NULL;
456 struct netr_SamInfo3 *user;
457 struct rpc_pipe_client *cli;
459 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
461 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
462 return NT_STATUS_UNSUCCESSFUL;
464 user_info->homedir = NULL;
465 user_info->shell = NULL;
466 user_info->primary_gid = (gid_t)-1;
468 /* try netsamlogon cache first */
470 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
473 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
474 sid_string_dbg(user_sid)));
476 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
477 sid_compose(&user_info->group_sid, &domain->sid,
478 user->base.primary_gid);
480 user_info->acct_name = talloc_strdup(mem_ctx,
481 user->base.account_name.string);
482 user_info->full_name = talloc_strdup(mem_ctx,
483 user->base.full_name.string);
490 if ( !winbindd_can_contact_domain( domain ) ) {
491 DEBUG(10,("query_user: No incoming trust for domain %s\n",
496 if ( !winbindd_can_contact_domain( domain ) ) {
497 DEBUG(10,("query_user: No incoming trust for domain %s\n",
502 if ( !winbindd_can_contact_domain( domain ) ) {
503 DEBUG(10,("query_user: No incoming trust for domain %s\n",
508 /* no cache; hit the wire */
510 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
511 if (!NT_STATUS_IS_OK(result))
514 /* Get user handle */
515 result = rpccli_samr_OpenUser(cli, mem_ctx,
517 SEC_FLAG_MAXIMUM_ALLOWED,
521 if (!NT_STATUS_IS_OK(result))
525 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
530 rpccli_samr_Close(cli, mem_ctx, &user_pol);
532 if (!NT_STATUS_IS_OK(result))
535 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
536 sid_compose(&user_info->group_sid, &domain->sid,
537 info->info21.primary_gid);
538 user_info->acct_name = talloc_strdup(mem_ctx,
539 info->info21.account_name.string);
540 user_info->full_name = talloc_strdup(mem_ctx,
541 info->info21.full_name.string);
542 user_info->homedir = NULL;
543 user_info->shell = NULL;
544 user_info->primary_gid = (gid_t)-1;
549 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
550 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
552 const DOM_SID *user_sid,
553 uint32 *num_groups, DOM_SID **user_grpsids)
555 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
556 struct policy_handle dom_pol, user_pol;
557 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
558 struct samr_RidWithAttributeArray *rid_array = NULL;
561 struct rpc_pipe_client *cli;
563 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
565 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
566 return NT_STATUS_UNSUCCESSFUL;
569 *user_grpsids = NULL;
571 /* so lets see if we have a cached user_info_3 */
572 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
573 num_groups, user_grpsids);
575 if (NT_STATUS_IS_OK(result)) {
579 if ( !winbindd_can_contact_domain( domain ) ) {
580 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
583 /* Tell the cache manager not to remember this one */
585 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
588 /* no cache; hit the wire */
590 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
591 if (!NT_STATUS_IS_OK(result))
594 /* Get user handle */
595 result = rpccli_samr_OpenUser(cli, mem_ctx,
601 if (!NT_STATUS_IS_OK(result))
604 /* Query user rids */
605 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
608 *num_groups = rid_array->count;
610 rpccli_samr_Close(cli, mem_ctx, &user_pol);
612 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
615 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
616 if (!(*user_grpsids))
617 return NT_STATUS_NO_MEMORY;
619 for (i=0;i<(*num_groups);i++) {
620 sid_copy(&((*user_grpsids)[i]), &domain->sid);
621 sid_append_rid(&((*user_grpsids)[i]),
622 rid_array->rids[i].rid);
628 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
630 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
632 uint32 num_sids, const DOM_SID *sids,
636 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
637 struct policy_handle dom_pol;
638 uint32 num_query_sids = 0;
640 struct rpc_pipe_client *cli;
641 struct samr_Ids alias_rids_query;
642 int rangesize = MAX_SAM_ENTRIES_W2K;
643 uint32 total_sids = 0;
649 DEBUG(3,("rpc: lookup_useraliases\n"));
651 if ( !winbindd_can_contact_domain( domain ) ) {
652 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
657 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
658 if (!NT_STATUS_IS_OK(result))
663 struct lsa_SidArray sid_array;
665 ZERO_STRUCT(sid_array);
667 num_query_sids = MIN(num_sids - total_sids, rangesize);
669 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
670 num_queries, num_query_sids));
672 if (num_query_sids) {
673 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
674 if (sid_array.sids == NULL) {
675 return NT_STATUS_NO_MEMORY;
678 sid_array.sids = NULL;
681 for (i=0; i<num_query_sids; i++) {
682 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
683 if (!sid_array.sids[i].sid) {
684 TALLOC_FREE(sid_array.sids);
685 return NT_STATUS_NO_MEMORY;
688 sid_array.num_sids = num_query_sids;
691 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
696 if (!NT_STATUS_IS_OK(result)) {
699 TALLOC_FREE(sid_array.sids);
705 for (i=0; i<alias_rids_query.count; i++) {
706 size_t na = *num_aliases;
707 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
709 return NT_STATUS_NO_MEMORY;
714 TALLOC_FREE(sid_array.sids);
718 } while (total_sids < num_sids);
721 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
722 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
728 /* Lookup group membership given a rid. */
729 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
731 const DOM_SID *group_sid,
732 enum lsa_SidType type,
734 DOM_SID **sid_mem, char ***names,
737 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
738 uint32 i, total_names = 0;
739 struct policy_handle dom_pol, group_pol;
740 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
741 uint32 *rid_mem = NULL;
744 struct rpc_pipe_client *cli;
745 unsigned int orig_timeout;
746 struct samr_RidTypeArray *rids = NULL;
748 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
749 sid_string_dbg(group_sid)));
751 if ( !winbindd_can_contact_domain( domain ) ) {
752 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
757 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
758 return NT_STATUS_UNSUCCESSFUL;
762 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
763 if (!NT_STATUS_IS_OK(result))
766 result = rpccli_samr_OpenGroup(cli, mem_ctx,
772 if (!NT_STATUS_IS_OK(result))
775 /* Step #1: Get a list of user rids that are the members of the
778 /* This call can take a long time - allow the server to time out.
779 35 seconds should do it. */
781 orig_timeout = rpccli_set_timeout(cli, 35000);
783 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
787 /* And restore our original timeout. */
788 rpccli_set_timeout(cli, orig_timeout);
790 rpccli_samr_Close(cli, mem_ctx, &group_pol);
792 if (!NT_STATUS_IS_OK(result))
795 *num_names = rids->count;
796 rid_mem = rids->rids;
805 /* Step #2: Convert list of rids into list of usernames. Do this
806 in bunches of ~1000 to avoid crashing NT4. It looks like there
807 is a buffer overflow or something like that lurking around
810 #define MAX_LOOKUP_RIDS 900
812 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
813 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
814 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
816 for (j=0;j<(*num_names);j++)
817 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
819 if (*num_names>0 && (!*names || !*name_types))
820 return NT_STATUS_NO_MEMORY;
822 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
823 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
824 struct lsa_Strings tmp_names;
825 struct samr_Ids tmp_types;
827 /* Lookup a chunk of rids */
829 result = rpccli_samr_LookupRids(cli, mem_ctx,
836 /* see if we have a real error (and yes the
837 STATUS_SOME_UNMAPPED is the one returned from 2k) */
839 if (!NT_STATUS_IS_OK(result) &&
840 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
843 /* Copy result into array. The talloc system will take
844 care of freeing the temporary arrays later on. */
846 if (tmp_names.count != tmp_types.count) {
847 return NT_STATUS_UNSUCCESSFUL;
850 for (r=0; r<tmp_names.count; r++) {
851 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
854 (*names)[total_names] = fill_domain_username_talloc(
855 mem_ctx, domain->name,
856 tmp_names.names[r].string, true);
857 (*name_types)[total_names] = tmp_types.ids[r];
862 *num_names = total_names;
871 static int get_ldap_seq(const char *server, int port, uint32 *seq)
875 const char *attrs[] = {"highestCommittedUSN", NULL};
876 LDAPMessage *res = NULL;
877 char **values = NULL;
880 *seq = DOM_SEQUENCE_NONE;
883 * Parameterised (5) second timeout on open. This is needed as the
884 * search timeout doesn't seem to apply to doing an open as well. JRA.
887 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
891 /* Timeout if no response within 20 seconds. */
895 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
896 CONST_DISCARD(char **, attrs), 0, &to, &res))
899 if (ldap_count_entries(ldp, res) != 1)
902 values = ldap_get_values(ldp, res, "highestCommittedUSN");
903 if (!values || !values[0])
906 *seq = atoi(values[0]);
912 ldap_value_free(values);
920 /**********************************************************************
921 Get the sequence number for a Windows AD native mode domain using
923 **********************************************************************/
925 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
928 char addr[INET6_ADDRSTRLEN];
930 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
931 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
932 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
933 "number for Domain (%s) from DC (%s)\n",
934 domain->name, addr));
939 #endif /* HAVE_LDAP */
941 /* find the sequence number for a domain */
942 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
945 union samr_DomainInfo *info = NULL;
947 struct policy_handle dom_pol;
948 bool got_seq_num = False;
949 struct rpc_pipe_client *cli;
951 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
953 if ( !winbindd_can_contact_domain( domain ) ) {
954 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
960 *seq = DOM_SEQUENCE_NONE;
962 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
963 return NT_STATUS_NO_MEMORY;
966 if ( domain->active_directory )
970 DEBUG(8,("using get_ldap_seq() to retrieve the "
971 "sequence number\n"));
973 res = get_ldap_sequence_number( domain, seq );
976 result = NT_STATUS_OK;
977 DEBUG(10,("domain_sequence_number: LDAP for "
979 domain->name, *seq));
983 DEBUG(10,("domain_sequence_number: failed to get LDAP "
984 "sequence number for domain %s\n",
987 #endif /* HAVE_LDAP */
989 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
990 if (!NT_STATUS_IS_OK(result)) {
994 /* Query domain info */
996 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1001 if (NT_STATUS_IS_OK(result)) {
1002 *seq = info->info8.sequence_num;
1007 /* retry with info-level 2 in case the dc does not support info-level 8
1008 * (like all older samba2 and samba3 dc's) - Guenther */
1010 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1015 if (NT_STATUS_IS_OK(result)) {
1016 *seq = info->general.sequence_num;
1022 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1023 domain->name, (unsigned)*seq));
1025 DEBUG(10,("domain_sequence_number: failed to get sequence "
1026 "number (%u) for domain %s\n",
1027 (unsigned)*seq, domain->name ));
1032 talloc_destroy(mem_ctx);
1037 /* get a list of trusted domains */
1038 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1039 TALLOC_CTX *mem_ctx,
1040 uint32 *num_domains,
1045 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1046 uint32 enum_ctx = 0;
1047 struct rpc_pipe_client *cli;
1048 struct policy_handle lsa_policy;
1050 DEBUG(3,("rpc: trusted_domains\n"));
1057 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1058 if (!NT_STATUS_IS_OK(result))
1061 result = STATUS_MORE_ENTRIES;
1063 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1066 struct lsa_DomainList dom_list;
1068 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1074 if (!NT_STATUS_IS_OK(result) &&
1075 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1078 start_idx = *num_domains;
1079 *num_domains += dom_list.count;
1080 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1081 char *, *num_domains);
1082 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1083 DOM_SID, *num_domains);
1084 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1085 char *, *num_domains);
1086 if ((*names == NULL) || (*dom_sids == NULL) ||
1087 (*alt_names == NULL))
1088 return NT_STATUS_NO_MEMORY;
1090 for (i=0; i<dom_list.count; i++) {
1091 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1092 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1093 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1099 /* find the lockout policy for a domain */
1100 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1101 TALLOC_CTX *mem_ctx,
1102 struct samr_DomInfo12 *lockout_policy)
1105 struct rpc_pipe_client *cli;
1106 struct policy_handle dom_pol;
1107 union samr_DomainInfo *info = NULL;
1109 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1111 if ( !winbindd_can_contact_domain( domain ) ) {
1112 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1114 return NT_STATUS_NOT_SUPPORTED;
1117 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1118 if (!NT_STATUS_IS_OK(result)) {
1122 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1126 if (!NT_STATUS_IS_OK(result)) {
1130 *lockout_policy = info->info12;
1132 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1133 info->info12.lockout_threshold));
1140 /* find the password policy for a domain */
1141 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1142 TALLOC_CTX *mem_ctx,
1143 struct samr_DomInfo1 *password_policy)
1146 struct rpc_pipe_client *cli;
1147 struct policy_handle dom_pol;
1148 union samr_DomainInfo *info = NULL;
1150 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1152 if ( !winbindd_can_contact_domain( domain ) ) {
1153 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1155 return NT_STATUS_NOT_SUPPORTED;
1158 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1159 if (!NT_STATUS_IS_OK(result)) {
1163 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1167 if (!NT_STATUS_IS_OK(result)) {
1171 *password_policy = info->info1;
1173 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1174 info->info1.min_password_length));
1181 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1182 TALLOC_CTX *mem_ctx,
1183 struct policy_handle *pol,
1185 const DOM_SID *sids,
1188 enum lsa_SidType **ptypes);
1190 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1191 struct winbindd_domain *domain,
1193 const struct dom_sid *sids,
1196 enum lsa_SidType **types)
1199 struct rpc_pipe_client *cli = NULL;
1200 struct policy_handle lsa_policy;
1201 unsigned int orig_timeout;
1202 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1204 if (domain->can_do_ncacn_ip_tcp) {
1205 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1206 if (NT_STATUS_IS_OK(status)) {
1207 lookup_sids_fn = rpccli_lsa_lookup_sids3;
1210 domain->can_do_ncacn_ip_tcp = false;
1212 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1214 if (!NT_STATUS_IS_OK(status)) {
1220 * This call can take a long time
1221 * allow the server to time out.
1222 * 35 seconds should do it.
1224 orig_timeout = rpccli_set_timeout(cli, 35000);
1226 status = lookup_sids_fn(cli,
1235 /* And restore our original timeout. */
1236 rpccli_set_timeout(cli, orig_timeout);
1238 if (!NT_STATUS_IS_OK(status)) {
1245 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1246 TALLOC_CTX *mem_ctx,
1247 struct policy_handle *pol,
1250 const char ***dom_names,
1252 struct dom_sid **sids,
1253 enum lsa_SidType **types);
1255 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1256 struct winbindd_domain *domain,
1259 const char ***domains,
1260 struct dom_sid **sids,
1261 enum lsa_SidType **types)
1264 struct rpc_pipe_client *cli = NULL;
1265 struct policy_handle lsa_policy;
1266 unsigned int orig_timeout;
1267 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1269 if (domain->can_do_ncacn_ip_tcp) {
1270 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1271 if (NT_STATUS_IS_OK(status)) {
1272 lookup_names_fn = rpccli_lsa_lookup_names4;
1275 domain->can_do_ncacn_ip_tcp = false;
1277 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1279 if (!NT_STATUS_IS_OK(status)) {
1286 * This call can take a long time
1287 * allow the server to time out.
1288 * 35 seconds should do it.
1290 orig_timeout = rpccli_set_timeout(cli, 35000);
1292 status = lookup_names_fn(cli,
1296 (const char **) names,
1302 /* And restore our original timeout. */
1303 rpccli_set_timeout(cli, orig_timeout);
1305 if (!NT_STATUS_IS_OK(status)) {
1312 /* the rpc backend methods are exposed via this structure */
1313 struct winbindd_methods msrpc_methods = {
1320 msrpc_rids_to_names,
1323 msrpc_lookup_useraliases,
1326 msrpc_lockout_policy,
1327 msrpc_password_policy,