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;
102 struct samr_DispEntryGeneral *src;
103 struct wbint_userinfo *dst;
105 src = &(disp_info.info1.entries[j]);
108 dst->acct_name = talloc_strdup(
109 mem_ctx, src->account_name.string);
110 dst->full_name = talloc_strdup(
111 mem_ctx, src->full_name.string);
114 sid_compose(&dst->user_sid, &domain->sid, rid);
116 /* For the moment we set the primary group for
117 every user to be the Domain Users group.
118 There are serious problems with determining
119 the actual primary group for large domains.
120 This should really be made into a 'winbind
121 force group' smb.conf parameter or
122 something like that. */
124 sid_compose(&dst->group_sid, &domain->sid,
125 DOMAIN_GROUP_RID_USERS);
128 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
133 /* list all domain groups */
134 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
137 struct acct_info **info)
139 struct policy_handle dom_pol;
142 struct rpc_pipe_client *cli;
147 DEBUG(3,("rpc: enum_dom_groups\n"));
149 if ( !winbindd_can_contact_domain( domain ) ) {
150 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
155 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
156 if (!NT_STATUS_IS_OK(status))
160 struct samr_SamArray *sam_array = NULL;
162 TALLOC_CTX *mem_ctx2;
165 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
167 /* start is updated by this call. */
168 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
172 0xFFFF, /* buffer size? */
175 if (!NT_STATUS_IS_OK(status) &&
176 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
177 talloc_destroy(mem_ctx2);
181 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
183 (*num_entries) + count);
185 talloc_destroy(mem_ctx2);
186 return NT_STATUS_NO_MEMORY;
189 for (g=0; g < count; g++) {
191 fstrcpy((*info)[*num_entries + g].acct_name,
192 sam_array->entries[g].name.string);
193 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
196 (*num_entries) += count;
197 talloc_destroy(mem_ctx2);
198 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
203 /* List all domain groups */
205 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
208 struct acct_info **info)
210 struct policy_handle dom_pol;
212 struct rpc_pipe_client *cli;
217 DEBUG(3,("rpc: enum_local_groups\n"));
219 if ( !winbindd_can_contact_domain( domain ) ) {
220 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
225 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
226 if (!NT_STATUS_IS_OK(result))
230 struct samr_SamArray *sam_array = NULL;
231 uint32 count = 0, start = *num_entries;
232 TALLOC_CTX *mem_ctx2;
235 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
237 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
241 0xFFFF, /* buffer size? */
243 if (!NT_STATUS_IS_OK(result) &&
244 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
246 talloc_destroy(mem_ctx2);
250 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
252 (*num_entries) + count);
254 talloc_destroy(mem_ctx2);
255 return NT_STATUS_NO_MEMORY;
258 for (g=0; g < count; g++) {
260 fstrcpy((*info)[*num_entries + g].acct_name,
261 sam_array->entries[g].name.string);
262 (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
265 (*num_entries) += count;
266 talloc_destroy(mem_ctx2);
268 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
273 /* convert a single name to a sid in a domain */
274 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
276 const char *domain_name,
280 enum lsa_SidType *type)
283 DOM_SID *sids = NULL;
284 enum lsa_SidType *types = NULL;
285 char *full_name = NULL;
286 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
287 char *mapped_name = NULL;
289 if (name == NULL || *name=='\0') {
290 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
291 } else if (domain_name == NULL || *domain_name == '\0') {
292 full_name = talloc_asprintf(mem_ctx, "%s", name);
294 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
297 DEBUG(0, ("talloc_asprintf failed!\n"));
298 return NT_STATUS_NO_MEMORY;
301 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
303 name_map_status = normalize_name_unmap(mem_ctx, full_name,
306 /* Reset the full_name pointer if we mapped anytthing */
308 if (NT_STATUS_IS_OK(name_map_status) ||
309 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
311 full_name = mapped_name;
314 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
315 full_name?full_name:"", domain_name ));
317 result = winbindd_lookup_names(mem_ctx, domain, 1,
318 (const char **)&full_name, NULL,
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 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
339 enum lsa_SidType *type)
343 enum lsa_SidType *types = NULL;
345 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
346 char *mapped_name = NULL;
348 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
351 result = winbindd_lookup_sids(mem_ctx,
358 if (!NT_STATUS_IS_OK(result)) {
359 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
365 *type = (enum lsa_SidType)types[0];
366 *domain_name = domains[0];
369 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
371 name_map_status = normalize_name_map(mem_ctx, domain, *name,
373 if (NT_STATUS_IS_OK(name_map_status) ||
374 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
377 DEBUG(5,("returning mapped name -- %s\n", *name));
383 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
390 enum lsa_SidType **types)
398 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
401 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
403 return NT_STATUS_NO_MEMORY;
409 for (i=0; i<num_rids; i++) {
410 if (!sid_compose(&sids[i], sid, rids[i])) {
411 return NT_STATUS_INTERNAL_ERROR;
415 result = winbindd_lookup_sids(mem_ctx,
423 if (!NT_STATUS_IS_OK(result) &&
424 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
429 for (i=0; i<num_rids; i++) {
430 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
431 char *mapped_name = NULL;
433 if ((*types)[i] != SID_NAME_UNKNOWN) {
434 name_map_status = normalize_name_map(mem_ctx,
438 if (NT_STATUS_IS_OK(name_map_status) ||
439 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
441 ret_names[i] = mapped_name;
444 *domain_name = domains[i];
451 /* Lookup user information from a rid or username. */
452 static NTSTATUS query_user(struct winbindd_domain *domain,
454 const DOM_SID *user_sid,
455 struct wbint_userinfo *user_info)
457 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
458 struct policy_handle dom_pol, user_pol;
459 union samr_UserInfo *info = NULL;
461 struct netr_SamInfo3 *user;
462 struct rpc_pipe_client *cli;
464 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
466 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
467 return NT_STATUS_UNSUCCESSFUL;
469 user_info->homedir = NULL;
470 user_info->shell = NULL;
471 user_info->primary_gid = (gid_t)-1;
473 /* try netsamlogon cache first */
475 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
478 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
479 sid_string_dbg(user_sid)));
481 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
482 sid_compose(&user_info->group_sid, &domain->sid,
483 user->base.primary_gid);
485 user_info->acct_name = talloc_strdup(mem_ctx,
486 user->base.account_name.string);
487 user_info->full_name = talloc_strdup(mem_ctx,
488 user->base.full_name.string);
495 if ( !winbindd_can_contact_domain( domain ) ) {
496 DEBUG(10,("query_user: No incoming trust for domain %s\n",
501 /* no cache; hit the wire */
503 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
504 if (!NT_STATUS_IS_OK(result))
507 /* Get user handle */
508 result = rpccli_samr_OpenUser(cli, mem_ctx,
510 SEC_FLAG_MAXIMUM_ALLOWED,
514 if (!NT_STATUS_IS_OK(result))
518 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
523 rpccli_samr_Close(cli, mem_ctx, &user_pol);
525 if (!NT_STATUS_IS_OK(result))
528 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
529 sid_compose(&user_info->group_sid, &domain->sid,
530 info->info21.primary_gid);
531 user_info->acct_name = talloc_strdup(mem_ctx,
532 info->info21.account_name.string);
533 user_info->full_name = talloc_strdup(mem_ctx,
534 info->info21.full_name.string);
535 user_info->homedir = NULL;
536 user_info->shell = NULL;
537 user_info->primary_gid = (gid_t)-1;
542 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
543 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
545 const DOM_SID *user_sid,
546 uint32 *num_groups, DOM_SID **user_grpsids)
548 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
549 struct policy_handle dom_pol, user_pol;
550 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
551 struct samr_RidWithAttributeArray *rid_array = NULL;
554 struct rpc_pipe_client *cli;
556 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
558 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
559 return NT_STATUS_UNSUCCESSFUL;
562 *user_grpsids = NULL;
564 /* so lets see if we have a cached user_info_3 */
565 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
566 num_groups, user_grpsids);
568 if (NT_STATUS_IS_OK(result)) {
572 if ( !winbindd_can_contact_domain( domain ) ) {
573 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
576 /* Tell the cache manager not to remember this one */
578 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
581 /* no cache; hit the wire */
583 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
584 if (!NT_STATUS_IS_OK(result))
587 /* Get user handle */
588 result = rpccli_samr_OpenUser(cli, mem_ctx,
594 if (!NT_STATUS_IS_OK(result))
597 /* Query user rids */
598 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
601 *num_groups = rid_array->count;
603 rpccli_samr_Close(cli, mem_ctx, &user_pol);
605 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
608 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
609 if (!(*user_grpsids))
610 return NT_STATUS_NO_MEMORY;
612 for (i=0;i<(*num_groups);i++) {
613 sid_copy(&((*user_grpsids)[i]), &domain->sid);
614 sid_append_rid(&((*user_grpsids)[i]),
615 rid_array->rids[i].rid);
621 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
623 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
625 uint32 num_sids, const DOM_SID *sids,
629 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
630 struct policy_handle dom_pol;
631 uint32 num_query_sids = 0;
633 struct rpc_pipe_client *cli;
634 struct samr_Ids alias_rids_query;
635 int rangesize = MAX_SAM_ENTRIES_W2K;
636 uint32 total_sids = 0;
642 DEBUG(3,("rpc: lookup_useraliases\n"));
644 if ( !winbindd_can_contact_domain( domain ) ) {
645 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
650 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
651 if (!NT_STATUS_IS_OK(result))
656 struct lsa_SidArray sid_array;
658 ZERO_STRUCT(sid_array);
660 num_query_sids = MIN(num_sids - total_sids, rangesize);
662 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
663 num_queries, num_query_sids));
665 if (num_query_sids) {
666 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
667 if (sid_array.sids == NULL) {
668 return NT_STATUS_NO_MEMORY;
671 sid_array.sids = NULL;
674 for (i=0; i<num_query_sids; i++) {
675 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
676 if (!sid_array.sids[i].sid) {
677 TALLOC_FREE(sid_array.sids);
678 return NT_STATUS_NO_MEMORY;
681 sid_array.num_sids = num_query_sids;
684 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
689 if (!NT_STATUS_IS_OK(result)) {
692 TALLOC_FREE(sid_array.sids);
698 for (i=0; i<alias_rids_query.count; i++) {
699 size_t na = *num_aliases;
700 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
702 return NT_STATUS_NO_MEMORY;
707 TALLOC_FREE(sid_array.sids);
711 } while (total_sids < num_sids);
714 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
715 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
721 /* Lookup group membership given a rid. */
722 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
724 const DOM_SID *group_sid,
725 enum lsa_SidType type,
727 DOM_SID **sid_mem, char ***names,
730 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
731 uint32 i, total_names = 0;
732 struct policy_handle dom_pol, group_pol;
733 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
734 uint32 *rid_mem = NULL;
737 struct rpc_pipe_client *cli;
738 unsigned int orig_timeout;
739 struct samr_RidTypeArray *rids = NULL;
741 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
742 sid_string_dbg(group_sid)));
744 if ( !winbindd_can_contact_domain( domain ) ) {
745 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
750 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
751 return NT_STATUS_UNSUCCESSFUL;
755 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
756 if (!NT_STATUS_IS_OK(result))
759 result = rpccli_samr_OpenGroup(cli, mem_ctx,
765 if (!NT_STATUS_IS_OK(result))
768 /* Step #1: Get a list of user rids that are the members of the
771 /* This call can take a long time - allow the server to time out.
772 35 seconds should do it. */
774 orig_timeout = rpccli_set_timeout(cli, 35000);
776 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
780 /* And restore our original timeout. */
781 rpccli_set_timeout(cli, orig_timeout);
783 rpccli_samr_Close(cli, mem_ctx, &group_pol);
785 if (!NT_STATUS_IS_OK(result))
788 *num_names = rids->count;
789 rid_mem = rids->rids;
798 /* Step #2: Convert list of rids into list of usernames. Do this
799 in bunches of ~1000 to avoid crashing NT4. It looks like there
800 is a buffer overflow or something like that lurking around
803 #define MAX_LOOKUP_RIDS 900
805 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
806 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
807 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
809 for (j=0;j<(*num_names);j++)
810 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
812 if (*num_names>0 && (!*names || !*name_types))
813 return NT_STATUS_NO_MEMORY;
815 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
816 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
817 struct lsa_Strings tmp_names;
818 struct samr_Ids tmp_types;
820 /* Lookup a chunk of rids */
822 result = rpccli_samr_LookupRids(cli, mem_ctx,
829 /* see if we have a real error (and yes the
830 STATUS_SOME_UNMAPPED is the one returned from 2k) */
832 if (!NT_STATUS_IS_OK(result) &&
833 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
836 /* Copy result into array. The talloc system will take
837 care of freeing the temporary arrays later on. */
839 if (tmp_names.count != tmp_types.count) {
840 return NT_STATUS_UNSUCCESSFUL;
843 for (r=0; r<tmp_names.count; r++) {
844 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
847 (*names)[total_names] = fill_domain_username_talloc(
848 mem_ctx, domain->name,
849 tmp_names.names[r].string, true);
850 (*name_types)[total_names] = tmp_types.ids[r];
855 *num_names = total_names;
864 static int get_ldap_seq(const char *server, int port, uint32 *seq)
868 const char *attrs[] = {"highestCommittedUSN", NULL};
869 LDAPMessage *res = NULL;
870 char **values = NULL;
873 *seq = DOM_SEQUENCE_NONE;
876 * Parameterised (5) second timeout on open. This is needed as the
877 * search timeout doesn't seem to apply to doing an open as well. JRA.
880 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
884 /* Timeout if no response within 20 seconds. */
888 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
889 CONST_DISCARD(char **, attrs), 0, &to, &res))
892 if (ldap_count_entries(ldp, res) != 1)
895 values = ldap_get_values(ldp, res, "highestCommittedUSN");
896 if (!values || !values[0])
899 *seq = atoi(values[0]);
905 ldap_value_free(values);
913 /**********************************************************************
914 Get the sequence number for a Windows AD native mode domain using
916 **********************************************************************/
918 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
921 char addr[INET6_ADDRSTRLEN];
923 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
924 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
925 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
926 "number for Domain (%s) from DC (%s)\n",
927 domain->name, addr));
932 #endif /* HAVE_LDAP */
934 /* find the sequence number for a domain */
935 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
938 union samr_DomainInfo *info = NULL;
940 struct policy_handle dom_pol;
941 bool got_seq_num = False;
942 struct rpc_pipe_client *cli;
944 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
946 if ( !winbindd_can_contact_domain( domain ) ) {
947 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
953 *seq = DOM_SEQUENCE_NONE;
955 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
956 return NT_STATUS_NO_MEMORY;
959 if ( domain->active_directory )
963 DEBUG(8,("using get_ldap_seq() to retrieve the "
964 "sequence number\n"));
966 res = get_ldap_sequence_number( domain, seq );
969 result = NT_STATUS_OK;
970 DEBUG(10,("domain_sequence_number: LDAP for "
972 domain->name, *seq));
976 DEBUG(10,("domain_sequence_number: failed to get LDAP "
977 "sequence number for domain %s\n",
980 #endif /* HAVE_LDAP */
982 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
983 if (!NT_STATUS_IS_OK(result)) {
987 /* Query domain info */
989 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
994 if (NT_STATUS_IS_OK(result)) {
995 *seq = info->info8.sequence_num;
1000 /* retry with info-level 2 in case the dc does not support info-level 8
1001 * (like all older samba2 and samba3 dc's) - Guenther */
1003 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1008 if (NT_STATUS_IS_OK(result)) {
1009 *seq = info->general.sequence_num;
1015 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
1016 domain->name, (unsigned)*seq));
1018 DEBUG(10,("domain_sequence_number: failed to get sequence "
1019 "number (%u) for domain %s\n",
1020 (unsigned)*seq, domain->name ));
1025 talloc_destroy(mem_ctx);
1030 /* get a list of trusted domains */
1031 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
1032 TALLOC_CTX *mem_ctx,
1033 uint32 *num_domains,
1038 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1039 uint32 enum_ctx = 0;
1040 struct rpc_pipe_client *cli;
1041 struct policy_handle lsa_policy;
1043 DEBUG(3,("rpc: trusted_domains\n"));
1050 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1051 if (!NT_STATUS_IS_OK(result))
1054 result = STATUS_MORE_ENTRIES;
1056 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1059 struct lsa_DomainList dom_list;
1061 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1067 if (!NT_STATUS_IS_OK(result) &&
1068 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1071 start_idx = *num_domains;
1072 *num_domains += dom_list.count;
1073 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1074 char *, *num_domains);
1075 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1076 DOM_SID, *num_domains);
1077 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1078 char *, *num_domains);
1079 if ((*names == NULL) || (*dom_sids == NULL) ||
1080 (*alt_names == NULL))
1081 return NT_STATUS_NO_MEMORY;
1083 for (i=0; i<dom_list.count; i++) {
1084 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1085 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1086 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1092 /* find the lockout policy for a domain */
1093 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1094 TALLOC_CTX *mem_ctx,
1095 struct samr_DomInfo12 *lockout_policy)
1098 struct rpc_pipe_client *cli;
1099 struct policy_handle dom_pol;
1100 union samr_DomainInfo *info = NULL;
1102 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1104 if ( !winbindd_can_contact_domain( domain ) ) {
1105 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1107 return NT_STATUS_NOT_SUPPORTED;
1110 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1111 if (!NT_STATUS_IS_OK(result)) {
1115 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1119 if (!NT_STATUS_IS_OK(result)) {
1123 *lockout_policy = info->info12;
1125 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1126 info->info12.lockout_threshold));
1133 /* find the password policy for a domain */
1134 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1135 TALLOC_CTX *mem_ctx,
1136 struct samr_DomInfo1 *password_policy)
1139 struct rpc_pipe_client *cli;
1140 struct policy_handle dom_pol;
1141 union samr_DomainInfo *info = NULL;
1143 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1145 if ( !winbindd_can_contact_domain( domain ) ) {
1146 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1148 return NT_STATUS_NOT_SUPPORTED;
1151 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1152 if (!NT_STATUS_IS_OK(result)) {
1156 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1160 if (!NT_STATUS_IS_OK(result)) {
1164 *password_policy = info->info1;
1166 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1167 info->info1.min_password_length));
1174 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1175 TALLOC_CTX *mem_ctx,
1176 struct policy_handle *pol,
1178 const DOM_SID *sids,
1181 enum lsa_SidType **ptypes);
1183 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1184 struct winbindd_domain *domain,
1186 const struct dom_sid *sids,
1189 enum lsa_SidType **types)
1192 struct rpc_pipe_client *cli = NULL;
1193 struct policy_handle lsa_policy;
1194 unsigned int orig_timeout;
1195 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1197 if (domain->can_do_ncacn_ip_tcp) {
1198 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1199 if (NT_STATUS_IS_OK(status)) {
1200 lookup_sids_fn = rpccli_lsa_lookup_sids3;
1203 domain->can_do_ncacn_ip_tcp = false;
1205 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1207 if (!NT_STATUS_IS_OK(status)) {
1213 * This call can take a long time
1214 * allow the server to time out.
1215 * 35 seconds should do it.
1217 orig_timeout = rpccli_set_timeout(cli, 35000);
1219 status = lookup_sids_fn(cli,
1228 /* And restore our original timeout. */
1229 rpccli_set_timeout(cli, orig_timeout);
1231 if (!NT_STATUS_IS_OK(status)) {
1238 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1239 TALLOC_CTX *mem_ctx,
1240 struct policy_handle *pol,
1243 const char ***dom_names,
1245 struct dom_sid **sids,
1246 enum lsa_SidType **types);
1248 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1249 struct winbindd_domain *domain,
1252 const char ***domains,
1253 struct dom_sid **sids,
1254 enum lsa_SidType **types)
1257 struct rpc_pipe_client *cli = NULL;
1258 struct policy_handle lsa_policy;
1259 unsigned int orig_timeout;
1260 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1262 if (domain->can_do_ncacn_ip_tcp) {
1263 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1264 if (NT_STATUS_IS_OK(status)) {
1265 lookup_names_fn = rpccli_lsa_lookup_names4;
1268 domain->can_do_ncacn_ip_tcp = false;
1270 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1272 if (!NT_STATUS_IS_OK(status)) {
1279 * This call can take a long time
1280 * allow the server to time out.
1281 * 35 seconds should do it.
1283 orig_timeout = rpccli_set_timeout(cli, 35000);
1285 status = lookup_names_fn(cli,
1289 (const char **) names,
1295 /* And restore our original timeout. */
1296 rpccli_set_timeout(cli, orig_timeout);
1298 if (!NT_STATUS_IS_OK(status)) {
1305 /* the rpc backend methods are exposed via this structure */
1306 struct winbindd_methods msrpc_methods = {
1313 msrpc_rids_to_names,
1316 msrpc_lookup_useraliases,
1319 msrpc_lockout_policy,
1320 msrpc_password_policy,