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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #define DBGC_CLASS DBGC_WINBIND
31 /* Query display info for a domain. This returns enough information plus a
32 bit extra to give an overview of domain users for the User Manager
34 static NTSTATUS query_user_list(struct winbindd_domain *domain,
37 WINBIND_USERINFO **info)
41 unsigned int i, start_idx;
43 struct rpc_pipe_client *cli;
45 DEBUG(3,("rpc: query_user_list\n"));
50 if ( !winbindd_can_contact_domain( domain ) ) {
51 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
56 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
57 if (!NT_STATUS_IS_OK(result))
64 uint32 num_dom_users, j;
65 uint32 max_entries, max_size;
66 uint32_t total_size, returned_size;
68 union samr_DispInfo disp_info;
70 /* this next bit is copied from net_user_list_internal() */
72 get_query_dispinfo_params(loop_count, &max_entries,
75 result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
84 num_dom_users = disp_info.info1.count;
85 start_idx += disp_info.info1.count;
88 *num_entries += num_dom_users;
90 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
94 return NT_STATUS_NO_MEMORY;
97 for (j = 0; j < num_dom_users; i++, j++) {
99 uint32_t rid = disp_info.info1.entries[j].rid;
101 (*info)[i].acct_name = talloc_strdup(mem_ctx,
102 disp_info.info1.entries[j].account_name.string);
103 (*info)[i].full_name = talloc_strdup(mem_ctx,
104 disp_info.info1.entries[j].full_name.string);
105 (*info)[i].homedir = NULL;
106 (*info)[i].shell = NULL;
107 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
109 /* For the moment we set the primary group for
110 every user to be the Domain Users group.
111 There are serious problems with determining
112 the actual primary group for large domains.
113 This should really be made into a 'winbind
114 force group' smb.conf parameter or
115 something like that. */
117 sid_compose(&(*info)[i].group_sid, &domain->sid,
118 DOMAIN_GROUP_RID_USERS);
121 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
126 /* list all domain groups */
127 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
130 struct acct_info **info)
135 struct rpc_pipe_client *cli;
140 DEBUG(3,("rpc: enum_dom_groups\n"));
142 if ( !winbindd_can_contact_domain( domain ) ) {
143 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
148 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
149 if (!NT_STATUS_IS_OK(status))
153 struct acct_info *info2 = NULL;
155 TALLOC_CTX *mem_ctx2;
157 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
159 /* start is updated by this call. */
160 status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol,
162 0xFFFF, /* buffer size? */
165 if (!NT_STATUS_IS_OK(status) &&
166 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
167 talloc_destroy(mem_ctx2);
171 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
173 (*num_entries) + count);
175 talloc_destroy(mem_ctx2);
176 return NT_STATUS_NO_MEMORY;
179 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
180 (*num_entries) += count;
181 talloc_destroy(mem_ctx2);
182 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
187 /* List all domain groups */
189 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
192 struct acct_info **info)
196 struct rpc_pipe_client *cli;
201 DEBUG(3,("rpc: enum_local_groups\n"));
203 if ( !winbindd_can_contact_domain( domain ) ) {
204 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
209 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
210 if (!NT_STATUS_IS_OK(result))
214 struct acct_info *info2 = NULL;
215 uint32 count = 0, start = *num_entries;
216 TALLOC_CTX *mem_ctx2;
218 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
220 result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol,
221 &start, 0xFFFF, &info2,
224 if (!NT_STATUS_IS_OK(result) &&
225 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
227 talloc_destroy(mem_ctx2);
231 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
233 (*num_entries) + count);
235 talloc_destroy(mem_ctx2);
236 return NT_STATUS_NO_MEMORY;
239 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
240 (*num_entries) += count;
241 talloc_destroy(mem_ctx2);
243 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
248 /* convert a single name to a sid in a domain */
249 NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
251 enum winbindd_cmd original_cmd,
252 const char *domain_name,
255 enum lsa_SidType *type)
258 DOM_SID *sids = NULL;
259 enum lsa_SidType *types = NULL;
260 char *full_name = NULL;
261 struct rpc_pipe_client *cli;
262 POLICY_HND lsa_policy;
264 if (name == NULL || *name=='\0') {
265 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
266 } else if (domain_name == NULL || *domain_name == '\0') {
267 full_name = talloc_asprintf(mem_ctx, "%s", name);
269 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
272 DEBUG(0, ("talloc_asprintf failed!\n"));
273 return NT_STATUS_NO_MEMORY;
276 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
278 ws_name_return( full_name, WB_REPLACE_CHAR );
280 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
282 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
283 if (!NT_STATUS_IS_OK(result))
286 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
287 (const char**) &full_name, NULL, 1, &sids, &types);
289 if (!NT_STATUS_IS_OK(result))
292 /* Return rid and type if lookup successful */
294 sid_copy(sid, &sids[0]);
301 convert a domain SID to a user or group name
303 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
308 enum lsa_SidType *type)
312 enum lsa_SidType *types = NULL;
314 struct rpc_pipe_client *cli;
315 POLICY_HND lsa_policy;
317 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
320 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
321 if (!NT_STATUS_IS_OK(result)) {
322 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
328 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
329 1, sid, &domains, &names, &types);
330 if (!NT_STATUS_IS_OK(result)) {
331 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
336 *type = (enum lsa_SidType)types[0];
337 *domain_name = domains[0];
340 ws_name_replace( *name, WB_REPLACE_CHAR );
342 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
346 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
353 enum lsa_SidType **types)
357 struct rpc_pipe_client *cli;
358 POLICY_HND lsa_policy;
363 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
366 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
368 return NT_STATUS_NO_MEMORY;
374 for (i=0; i<num_rids; i++) {
375 if (!sid_compose(&sids[i], sid, rids[i])) {
376 return NT_STATUS_INTERNAL_ERROR;
380 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
381 if (!NT_STATUS_IS_OK(result)) {
385 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
386 num_rids, sids, &domains,
388 if (!NT_STATUS_IS_OK(result) &&
389 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
394 for (i=0; i<num_rids; i++) {
395 if ((*types)[i] != SID_NAME_UNKNOWN) {
396 ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
397 *domain_name = domains[i];
404 /* Lookup user information from a rid or username. */
405 static NTSTATUS query_user(struct winbindd_domain *domain,
407 const DOM_SID *user_sid,
408 WINBIND_USERINFO *user_info)
410 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
411 POLICY_HND dom_pol, user_pol;
412 union samr_UserInfo *info = NULL;
414 NET_USER_INFO_3 *user;
415 struct rpc_pipe_client *cli;
417 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
419 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
420 return NT_STATUS_UNSUCCESSFUL;
422 user_info->homedir = NULL;
423 user_info->shell = NULL;
424 user_info->primary_gid = (gid_t)-1;
426 /* try netsamlogon cache first */
428 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
431 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
432 sid_string_dbg(user_sid)));
434 sid_compose(&user_info->user_sid, &domain->sid, user->user_rid);
435 sid_compose(&user_info->group_sid, &domain->sid,
438 user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx,
439 &user->uni_user_name);
440 user_info->full_name = unistr2_to_ascii_talloc(mem_ctx,
441 &user->uni_full_name);
448 if ( !winbindd_can_contact_domain( domain ) ) {
449 DEBUG(10,("query_user: No incoming trust for domain %s\n",
454 if ( !winbindd_can_contact_domain( domain ) ) {
455 DEBUG(10,("query_user: No incoming trust for domain %s\n",
460 if ( !winbindd_can_contact_domain( domain ) ) {
461 DEBUG(10,("query_user: No incoming trust for domain %s\n",
466 /* no cache; hit the wire */
468 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
469 if (!NT_STATUS_IS_OK(result))
472 /* Get user handle */
473 result = rpccli_samr_OpenUser(cli, mem_ctx,
475 SEC_RIGHTS_MAXIMUM_ALLOWED,
479 if (!NT_STATUS_IS_OK(result))
483 result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
488 rpccli_samr_Close(cli, mem_ctx, &user_pol);
490 if (!NT_STATUS_IS_OK(result))
493 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
494 sid_compose(&user_info->group_sid, &domain->sid,
495 info->info21.primary_gid);
496 user_info->acct_name = talloc_strdup(mem_ctx,
497 info->info21.account_name.string);
498 user_info->full_name = talloc_strdup(mem_ctx,
499 info->info21.full_name.string);
500 user_info->homedir = NULL;
501 user_info->shell = NULL;
502 user_info->primary_gid = (gid_t)-1;
507 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
508 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
510 const DOM_SID *user_sid,
511 uint32 *num_groups, DOM_SID **user_grpsids)
513 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
514 POLICY_HND dom_pol, user_pol;
515 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
516 struct samr_RidWithAttributeArray *rid_array = NULL;
519 struct rpc_pipe_client *cli;
521 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
523 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
524 return NT_STATUS_UNSUCCESSFUL;
527 *user_grpsids = NULL;
529 /* so lets see if we have a cached user_info_3 */
530 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
531 num_groups, user_grpsids);
533 if (NT_STATUS_IS_OK(result)) {
537 if ( !winbindd_can_contact_domain( domain ) ) {
538 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
541 /* Tell the cache manager not to remember this one */
543 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
546 /* no cache; hit the wire */
548 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
549 if (!NT_STATUS_IS_OK(result))
552 /* Get user handle */
553 result = rpccli_samr_OpenUser(cli, mem_ctx,
559 if (!NT_STATUS_IS_OK(result))
562 /* Query user rids */
563 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
566 *num_groups = rid_array->count;
568 rpccli_samr_Close(cli, mem_ctx, &user_pol);
570 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
573 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
574 if (!(*user_grpsids))
575 return NT_STATUS_NO_MEMORY;
577 for (i=0;i<(*num_groups);i++) {
578 sid_copy(&((*user_grpsids)[i]), &domain->sid);
579 sid_append_rid(&((*user_grpsids)[i]),
580 rid_array->rids[i].rid);
586 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
588 uint32 num_sids, const DOM_SID *sids,
589 uint32 *num_aliases, uint32 **alias_rids)
591 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
593 uint32 num_query_sids = 0;
595 struct rpc_pipe_client *cli;
596 struct samr_Ids alias_rids_query;
597 int rangesize = MAX_SAM_ENTRIES_W2K;
598 uint32 total_sids = 0;
604 DEBUG(3,("rpc: lookup_useraliases\n"));
606 if ( !winbindd_can_contact_domain( domain ) ) {
607 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
612 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
613 if (!NT_STATUS_IS_OK(result))
618 struct lsa_SidArray sid_array;
620 ZERO_STRUCT(sid_array);
622 num_query_sids = MIN(num_sids - total_sids, rangesize);
624 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
625 num_queries, num_query_sids));
627 if (num_query_sids) {
628 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
629 if (sid_array.sids == NULL) {
630 return NT_STATUS_NO_MEMORY;
633 sid_array.sids = NULL;
636 for (i=0; i<num_query_sids; i++) {
637 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
638 if (!sid_array.sids[i].sid) {
639 TALLOC_FREE(sid_array.sids);
640 return NT_STATUS_NO_MEMORY;
643 sid_array.num_sids = num_query_sids;
646 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
651 if (!NT_STATUS_IS_OK(result)) {
654 TALLOC_FREE(sid_array.sids);
660 for (i=0; i<alias_rids_query.count; i++) {
661 size_t na = *num_aliases;
662 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
664 return NT_STATUS_NO_MEMORY;
669 TALLOC_FREE(sid_array.sids);
673 } while (total_sids < num_sids);
676 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
677 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
683 /* Lookup group membership given a rid. */
684 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
686 const DOM_SID *group_sid, uint32 *num_names,
687 DOM_SID **sid_mem, char ***names,
690 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
691 uint32 i, total_names = 0;
692 POLICY_HND dom_pol, group_pol;
693 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
694 uint32 *rid_mem = NULL;
697 struct rpc_pipe_client *cli;
698 unsigned int orig_timeout;
699 struct samr_RidTypeArray *rids = NULL;
701 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
702 sid_string_dbg(group_sid)));
704 if ( !winbindd_can_contact_domain( domain ) ) {
705 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
710 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
711 return NT_STATUS_UNSUCCESSFUL;
715 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
716 if (!NT_STATUS_IS_OK(result))
719 result = rpccli_samr_OpenGroup(cli, mem_ctx,
725 if (!NT_STATUS_IS_OK(result))
728 /* Step #1: Get a list of user rids that are the members of the
731 /* This call can take a long time - allow the server to time out.
732 35 seconds should do it. */
734 orig_timeout = cli_set_timeout(cli->cli, 35000);
736 result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
740 /* And restore our original timeout. */
741 cli_set_timeout(cli->cli, orig_timeout);
743 rpccli_samr_Close(cli, mem_ctx, &group_pol);
745 if (!NT_STATUS_IS_OK(result))
748 *num_names = rids->count;
749 rid_mem = rids->rids;
758 /* Step #2: Convert list of rids into list of usernames. Do this
759 in bunches of ~1000 to avoid crashing NT4. It looks like there
760 is a buffer overflow or something like that lurking around
763 #define MAX_LOOKUP_RIDS 900
765 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
766 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
767 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
769 for (j=0;j<(*num_names);j++)
770 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
772 if (*num_names>0 && (!*names || !*name_types))
773 return NT_STATUS_NO_MEMORY;
775 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
776 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
777 uint32 tmp_num_names = 0;
778 char **tmp_names = NULL;
779 uint32 *tmp_types = NULL;
781 /* Lookup a chunk of rids */
783 result = rpccli_samr_lookup_rids(cli, mem_ctx,
788 &tmp_names, &tmp_types);
790 /* see if we have a real error (and yes the
791 STATUS_SOME_UNMAPPED is the one returned from 2k) */
793 if (!NT_STATUS_IS_OK(result) &&
794 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
797 /* Copy result into array. The talloc system will take
798 care of freeing the temporary arrays later on. */
800 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
803 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
806 total_names += tmp_num_names;
809 *num_names = total_names;
818 static int get_ldap_seq(const char *server, int port, uint32 *seq)
822 const char *attrs[] = {"highestCommittedUSN", NULL};
823 LDAPMessage *res = NULL;
824 char **values = NULL;
827 *seq = DOM_SEQUENCE_NONE;
830 * Parameterised (5) second timeout on open. This is needed as the
831 * search timeout doesn't seem to apply to doing an open as well. JRA.
834 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
838 /* Timeout if no response within 20 seconds. */
842 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
843 CONST_DISCARD(char **, attrs), 0, &to, &res))
846 if (ldap_count_entries(ldp, res) != 1)
849 values = ldap_get_values(ldp, res, "highestCommittedUSN");
850 if (!values || !values[0])
853 *seq = atoi(values[0]);
859 ldap_value_free(values);
867 /**********************************************************************
868 Get the sequence number for a Windows AD native mode domain using
870 **********************************************************************/
872 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
875 char addr[INET6_ADDRSTRLEN];
877 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
878 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
879 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
880 "number for Domain (%s) from DC (%s)\n",
881 domain->name, addr));
886 #endif /* HAVE_LDAP */
888 /* find the sequence number for a domain */
889 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
892 union samr_DomainInfo *info = NULL;
895 bool got_seq_num = False;
896 struct rpc_pipe_client *cli;
898 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
900 if ( !winbindd_can_contact_domain( domain ) ) {
901 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
907 *seq = DOM_SEQUENCE_NONE;
909 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
910 return NT_STATUS_NO_MEMORY;
913 if ( domain->active_directory )
917 DEBUG(8,("using get_ldap_seq() to retrieve the "
918 "sequence number\n"));
920 res = get_ldap_sequence_number( domain, seq );
923 result = NT_STATUS_OK;
924 DEBUG(10,("domain_sequence_number: LDAP for "
926 domain->name, *seq));
930 DEBUG(10,("domain_sequence_number: failed to get LDAP "
931 "sequence number for domain %s\n",
934 #endif /* HAVE_LDAP */
936 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
937 if (!NT_STATUS_IS_OK(result)) {
941 /* Query domain info */
943 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
948 if (NT_STATUS_IS_OK(result)) {
949 *seq = info->info8.sequence_num;
954 /* retry with info-level 2 in case the dc does not support info-level 8
955 * (like all older samba2 and samba3 dc's) - Guenther */
957 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
962 if (NT_STATUS_IS_OK(result)) {
963 *seq = info->info2.sequence_num;
969 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
970 domain->name, (unsigned)*seq));
972 DEBUG(10,("domain_sequence_number: failed to get sequence "
973 "number (%u) for domain %s\n",
974 (unsigned)*seq, domain->name ));
979 talloc_destroy(mem_ctx);
984 /* get a list of trusted domains */
985 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
992 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
994 struct rpc_pipe_client *cli;
995 POLICY_HND lsa_policy;
997 DEBUG(3,("rpc: trusted_domains\n"));
1004 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1005 if (!NT_STATUS_IS_OK(result))
1008 result = STATUS_MORE_ENTRIES;
1010 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1013 struct lsa_DomainList dom_list;
1015 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1021 if (!NT_STATUS_IS_OK(result) &&
1022 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1025 start_idx = *num_domains;
1026 *num_domains += dom_list.count;
1027 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1028 char *, *num_domains);
1029 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1030 DOM_SID, *num_domains);
1031 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1032 char *, *num_domains);
1033 if ((*names == NULL) || (*dom_sids == NULL) ||
1034 (*alt_names == NULL))
1035 return NT_STATUS_NO_MEMORY;
1037 for (i=0; i<dom_list.count; i++) {
1038 (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
1039 (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
1040 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1046 /* find the lockout policy for a domain */
1047 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1048 TALLOC_CTX *mem_ctx,
1049 struct samr_DomInfo12 *lockout_policy)
1052 struct rpc_pipe_client *cli;
1054 union samr_DomainInfo *info = NULL;
1056 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1058 if ( !winbindd_can_contact_domain( domain ) ) {
1059 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1061 return NT_STATUS_NOT_SUPPORTED;
1064 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1065 if (!NT_STATUS_IS_OK(result)) {
1069 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1073 if (!NT_STATUS_IS_OK(result)) {
1077 *lockout_policy = info->info12;
1079 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1080 info->info12.lockout_threshold));
1087 /* find the password policy for a domain */
1088 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1089 TALLOC_CTX *mem_ctx,
1090 struct samr_DomInfo1 *password_policy)
1093 struct rpc_pipe_client *cli;
1095 union samr_DomainInfo *info = NULL;
1097 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1099 if ( !winbindd_can_contact_domain( domain ) ) {
1100 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1102 return NT_STATUS_NOT_SUPPORTED;
1105 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1106 if (!NT_STATUS_IS_OK(result)) {
1110 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1114 if (!NT_STATUS_IS_OK(result)) {
1118 *password_policy = info->info1;
1120 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1121 info->info1.min_password_length));
1129 /* the rpc backend methods are exposed via this structure */
1130 struct winbindd_methods msrpc_methods = {
1137 msrpc_rids_to_names,
1140 msrpc_lookup_useraliases,
1143 msrpc_lockout_policy,
1144 msrpc_password_policy,