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;
71 ctr.sam.info1 = &info1;
73 /* this next bit is copied from net_user_list_internal() */
75 get_query_dispinfo_params(loop_count, &max_entries,
78 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol,
81 max_entries, max_size,
86 *num_entries += num_dom_users;
88 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
92 return NT_STATUS_NO_MEMORY;
95 for (j = 0; j < num_dom_users; i++, j++) {
96 fstring username, fullname;
97 uint32 rid = ctr.sam.info1->sam[j].rid_user;
99 unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username));
100 unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname));
102 (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
103 (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
104 (*info)[i].homedir = NULL;
105 (*info)[i].shell = NULL;
106 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
108 /* For the moment we set the primary group for
109 every user to be the Domain Users group.
110 There are serious problems with determining
111 the actual primary group for large domains.
112 This should really be made into a 'winbind
113 force group' smb.conf parameter or
114 something like that. */
116 sid_compose(&(*info)[i].group_sid, &domain->sid,
117 DOMAIN_GROUP_RID_USERS);
120 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
125 /* list all domain groups */
126 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
129 struct acct_info **info)
134 struct rpc_pipe_client *cli;
139 DEBUG(3,("rpc: enum_dom_groups\n"));
141 if ( !winbindd_can_contact_domain( domain ) ) {
142 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
147 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
148 if (!NT_STATUS_IS_OK(status))
152 struct acct_info *info2 = NULL;
154 TALLOC_CTX *mem_ctx2;
156 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
158 /* start is updated by this call. */
159 status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol,
161 0xFFFF, /* buffer size? */
164 if (!NT_STATUS_IS_OK(status) &&
165 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
166 talloc_destroy(mem_ctx2);
170 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
172 (*num_entries) + count);
174 talloc_destroy(mem_ctx2);
175 return NT_STATUS_NO_MEMORY;
178 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
179 (*num_entries) += count;
180 talloc_destroy(mem_ctx2);
181 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
186 /* List all domain groups */
188 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
191 struct acct_info **info)
195 struct rpc_pipe_client *cli;
200 DEBUG(3,("rpc: enum_local_groups\n"));
202 if ( !winbindd_can_contact_domain( domain ) ) {
203 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
208 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
209 if (!NT_STATUS_IS_OK(result))
213 struct acct_info *info2 = NULL;
214 uint32 count = 0, start = *num_entries;
215 TALLOC_CTX *mem_ctx2;
217 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
219 result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol,
220 &start, 0xFFFF, &info2,
223 if (!NT_STATUS_IS_OK(result) &&
224 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
226 talloc_destroy(mem_ctx2);
230 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
232 (*num_entries) + count);
234 talloc_destroy(mem_ctx2);
235 return NT_STATUS_NO_MEMORY;
238 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
239 (*num_entries) += count;
240 talloc_destroy(mem_ctx2);
242 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
247 /* convert a single name to a sid in a domain */
248 NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
250 enum winbindd_cmd original_cmd,
251 const char *domain_name,
254 enum lsa_SidType *type)
257 DOM_SID *sids = NULL;
258 enum lsa_SidType *types = NULL;
259 char *full_name = NULL;
260 struct rpc_pipe_client *cli;
261 POLICY_HND lsa_policy;
263 if (name == NULL || *name=='\0') {
264 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
265 } else if (domain_name == NULL || *domain_name == '\0') {
266 full_name = talloc_asprintf(mem_ctx, "%s", name);
268 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
271 DEBUG(0, ("talloc_asprintf failed!\n"));
272 return NT_STATUS_NO_MEMORY;
275 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
277 ws_name_return( full_name, WB_REPLACE_CHAR );
279 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
281 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
282 if (!NT_STATUS_IS_OK(result))
285 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
286 (const char**) &full_name, NULL, 1, &sids, &types);
288 if (!NT_STATUS_IS_OK(result))
291 /* Return rid and type if lookup successful */
293 sid_copy(sid, &sids[0]);
300 convert a domain SID to a user or group name
302 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
307 enum lsa_SidType *type)
311 enum lsa_SidType *types = NULL;
313 struct rpc_pipe_client *cli;
314 POLICY_HND lsa_policy;
316 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
319 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
320 if (!NT_STATUS_IS_OK(result)) {
321 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
327 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
328 1, sid, &domains, &names, &types);
329 if (!NT_STATUS_IS_OK(result)) {
330 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
335 *type = (enum lsa_SidType)types[0];
336 *domain_name = domains[0];
339 ws_name_replace( *name, WB_REPLACE_CHAR );
341 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
345 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
352 enum lsa_SidType **types)
356 struct rpc_pipe_client *cli;
357 POLICY_HND lsa_policy;
362 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
365 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
367 return NT_STATUS_NO_MEMORY;
373 for (i=0; i<num_rids; i++) {
374 if (!sid_compose(&sids[i], sid, rids[i])) {
375 return NT_STATUS_INTERNAL_ERROR;
379 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
380 if (!NT_STATUS_IS_OK(result)) {
384 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
385 num_rids, sids, &domains,
387 if (!NT_STATUS_IS_OK(result) &&
388 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
393 for (i=0; i<num_rids; i++) {
394 if ((*types)[i] != SID_NAME_UNKNOWN) {
395 ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
396 *domain_name = domains[i];
403 /* Lookup user information from a rid or username. */
404 static NTSTATUS query_user(struct winbindd_domain *domain,
406 const DOM_SID *user_sid,
407 WINBIND_USERINFO *user_info)
409 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
410 POLICY_HND dom_pol, user_pol;
411 SAM_USERINFO_CTR *ctr;
413 NET_USER_INFO_3 *user;
414 struct rpc_pipe_client *cli;
416 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
418 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
419 return NT_STATUS_UNSUCCESSFUL;
421 user_info->homedir = NULL;
422 user_info->shell = NULL;
423 user_info->primary_gid = (gid_t)-1;
425 /* try netsamlogon cache first */
427 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
430 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
431 sid_string_dbg(user_sid)));
433 sid_compose(&user_info->user_sid, &domain->sid, user->user_rid);
434 sid_compose(&user_info->group_sid, &domain->sid,
437 user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx,
438 &user->uni_user_name);
439 user_info->full_name = unistr2_to_ascii_talloc(mem_ctx,
440 &user->uni_full_name);
447 if ( !winbindd_can_contact_domain( domain ) ) {
448 DEBUG(10,("query_user: No incoming trust for domain %s\n",
453 if ( !winbindd_can_contact_domain( domain ) ) {
454 DEBUG(10,("query_user: No incoming trust for domain %s\n",
459 if ( !winbindd_can_contact_domain( domain ) ) {
460 DEBUG(10,("query_user: No incoming trust for domain %s\n",
465 /* no cache; hit the wire */
467 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
468 if (!NT_STATUS_IS_OK(result))
471 /* Get user handle */
472 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
473 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid,
476 if (!NT_STATUS_IS_OK(result))
480 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
483 rpccli_samr_Close(cli, mem_ctx, &user_pol);
485 if (!NT_STATUS_IS_OK(result))
488 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
489 sid_compose(&user_info->group_sid, &domain->sid,
490 ctr->info.id21->group_rid);
491 user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx,
492 &ctr->info.id21->uni_user_name);
493 user_info->full_name = unistr2_to_ascii_talloc(mem_ctx,
494 &ctr->info.id21->uni_full_name);
495 user_info->homedir = NULL;
496 user_info->shell = NULL;
497 user_info->primary_gid = (gid_t)-1;
502 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
503 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
505 const DOM_SID *user_sid,
506 uint32 *num_groups, DOM_SID **user_grpsids)
508 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
509 POLICY_HND dom_pol, user_pol;
510 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
511 DOM_GID *user_groups;
514 struct rpc_pipe_client *cli;
516 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
518 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
519 return NT_STATUS_UNSUCCESSFUL;
522 *user_grpsids = NULL;
524 /* so lets see if we have a cached user_info_3 */
525 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
526 num_groups, user_grpsids);
528 if (NT_STATUS_IS_OK(result)) {
532 if ( !winbindd_can_contact_domain( domain ) ) {
533 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
536 /* Tell the cache manager not to remember this one */
538 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
541 /* no cache; hit the wire */
543 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
544 if (!NT_STATUS_IS_OK(result))
547 /* Get user handle */
548 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
549 des_access, user_rid, &user_pol);
551 if (!NT_STATUS_IS_OK(result))
554 /* Query user rids */
555 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
556 num_groups, &user_groups);
558 rpccli_samr_Close(cli, mem_ctx, &user_pol);
560 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
563 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
564 if (!(*user_grpsids))
565 return NT_STATUS_NO_MEMORY;
567 for (i=0;i<(*num_groups);i++) {
568 sid_copy(&((*user_grpsids)[i]), &domain->sid);
569 sid_append_rid(&((*user_grpsids)[i]),
570 user_groups[i].g_rid);
576 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
578 uint32 num_sids, const DOM_SID *sids,
579 uint32 *num_aliases, uint32 **alias_rids)
581 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
583 DOM_SID2 *query_sids;
584 uint32 num_query_sids = 0;
586 struct rpc_pipe_client *cli;
587 uint32 *alias_rids_query, num_aliases_query;
588 int rangesize = MAX_SAM_ENTRIES_W2K;
589 uint32 total_sids = 0;
595 DEBUG(3,("rpc: lookup_useraliases\n"));
597 if ( !winbindd_can_contact_domain( domain ) ) {
598 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
603 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
604 if (!NT_STATUS_IS_OK(result))
610 num_query_sids = MIN(num_sids - total_sids, rangesize);
612 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
613 num_queries, num_query_sids));
615 if (num_query_sids) {
616 query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
617 if (query_sids == NULL) {
618 return NT_STATUS_NO_MEMORY;
624 for (i=0; i<num_query_sids; i++) {
625 sid_copy(&query_sids[i].sid, &sids[total_sids++]);
626 query_sids[i].num_auths = query_sids[i].sid.num_auths;
631 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
632 num_query_sids, query_sids,
636 if (!NT_STATUS_IS_OK(result)) {
639 TALLOC_FREE(query_sids);
645 for (i=0; i<num_aliases_query; i++) {
646 size_t na = *num_aliases;
647 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i],
649 return NT_STATUS_NO_MEMORY;
654 TALLOC_FREE(query_sids);
658 } while (total_sids < num_sids);
661 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
662 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
668 /* Lookup group membership given a rid. */
669 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
671 const DOM_SID *group_sid, uint32 *num_names,
672 DOM_SID **sid_mem, char ***names,
675 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
676 uint32 i, total_names = 0;
677 POLICY_HND dom_pol, group_pol;
678 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
679 uint32 *rid_mem = NULL;
682 struct rpc_pipe_client *cli;
683 unsigned int orig_timeout;
685 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
686 sid_string_dbg(group_sid)));
688 if ( !winbindd_can_contact_domain( domain ) ) {
689 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
694 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
695 return NT_STATUS_UNSUCCESSFUL;
699 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
700 if (!NT_STATUS_IS_OK(result))
703 result = rpccli_samr_OpenGroup(cli, mem_ctx,
709 if (!NT_STATUS_IS_OK(result))
712 /* Step #1: Get a list of user rids that are the members of the
715 /* This call can take a long time - allow the server to time out.
716 35 seconds should do it. */
718 orig_timeout = cli_set_timeout(cli->cli, 35000);
720 result = rpccli_samr_query_groupmem(cli, mem_ctx,
721 &group_pol, num_names, &rid_mem,
724 /* And restore our original timeout. */
725 cli_set_timeout(cli->cli, orig_timeout);
727 rpccli_samr_Close(cli, mem_ctx, &group_pol);
729 if (!NT_STATUS_IS_OK(result))
739 /* Step #2: Convert list of rids into list of usernames. Do this
740 in bunches of ~1000 to avoid crashing NT4. It looks like there
741 is a buffer overflow or something like that lurking around
744 #define MAX_LOOKUP_RIDS 900
746 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
747 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
748 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
750 for (j=0;j<(*num_names);j++)
751 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
753 if (*num_names>0 && (!*names || !*name_types))
754 return NT_STATUS_NO_MEMORY;
756 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
757 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
758 uint32 tmp_num_names = 0;
759 char **tmp_names = NULL;
760 uint32 *tmp_types = NULL;
762 /* Lookup a chunk of rids */
764 result = rpccli_samr_lookup_rids(cli, mem_ctx,
769 &tmp_names, &tmp_types);
771 /* see if we have a real error (and yes the
772 STATUS_SOME_UNMAPPED is the one returned from 2k) */
774 if (!NT_STATUS_IS_OK(result) &&
775 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
778 /* Copy result into array. The talloc system will take
779 care of freeing the temporary arrays later on. */
781 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
784 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
787 total_names += tmp_num_names;
790 *num_names = total_names;
799 static int get_ldap_seq(const char *server, int port, uint32 *seq)
803 const char *attrs[] = {"highestCommittedUSN", NULL};
804 LDAPMessage *res = NULL;
805 char **values = NULL;
808 *seq = DOM_SEQUENCE_NONE;
811 * Parameterised (5) second timeout on open. This is needed as the
812 * search timeout doesn't seem to apply to doing an open as well. JRA.
815 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
819 /* Timeout if no response within 20 seconds. */
823 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
824 CONST_DISCARD(char **, attrs), 0, &to, &res))
827 if (ldap_count_entries(ldp, res) != 1)
830 values = ldap_get_values(ldp, res, "highestCommittedUSN");
831 if (!values || !values[0])
834 *seq = atoi(values[0]);
840 ldap_value_free(values);
848 /**********************************************************************
849 Get the sequence number for a Windows AD native mode domain using
851 **********************************************************************/
853 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
856 char addr[INET6_ADDRSTRLEN];
858 print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
859 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
860 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
861 "number for Domain (%s) from DC (%s)\n",
862 domain->name, addr));
867 #endif /* HAVE_LDAP */
869 /* find the sequence number for a domain */
870 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
876 bool got_seq_num = False;
877 struct rpc_pipe_client *cli;
879 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
881 if ( !winbindd_can_contact_domain( domain ) ) {
882 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
888 *seq = DOM_SEQUENCE_NONE;
890 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
891 return NT_STATUS_NO_MEMORY;
894 if ( domain->active_directory )
898 DEBUG(8,("using get_ldap_seq() to retrieve the "
899 "sequence number\n"));
901 res = get_ldap_sequence_number( domain, seq );
904 result = NT_STATUS_OK;
905 DEBUG(10,("domain_sequence_number: LDAP for "
907 domain->name, *seq));
911 DEBUG(10,("domain_sequence_number: failed to get LDAP "
912 "sequence number for domain %s\n",
915 #endif /* HAVE_LDAP */
917 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
918 if (!NT_STATUS_IS_OK(result)) {
922 /* Query domain info */
924 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
926 if (NT_STATUS_IS_OK(result)) {
927 *seq = ctr.info.inf8.seq_num;
932 /* retry with info-level 2 in case the dc does not support info-level 8
933 * (like all older samba2 and samba3 dc's - Guenther */
935 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
937 if (NT_STATUS_IS_OK(result)) {
938 *seq = ctr.info.inf2.seq_num;
944 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
945 domain->name, (unsigned)*seq));
947 DEBUG(10,("domain_sequence_number: failed to get sequence "
948 "number (%u) for domain %s\n",
949 (unsigned)*seq, domain->name ));
954 talloc_destroy(mem_ctx);
959 /* get a list of trusted domains */
960 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
967 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
969 struct rpc_pipe_client *cli;
970 POLICY_HND lsa_policy;
972 DEBUG(3,("rpc: trusted_domains\n"));
979 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
980 if (!NT_STATUS_IS_OK(result))
983 result = STATUS_MORE_ENTRIES;
985 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
986 uint32 start_idx, num;
991 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
992 &lsa_policy, &enum_ctx,
996 if (!NT_STATUS_IS_OK(result) &&
997 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1000 start_idx = *num_domains;
1001 *num_domains += num;
1002 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1003 char *, *num_domains);
1004 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1005 DOM_SID, *num_domains);
1006 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1007 char *, *num_domains);
1008 if ((*names == NULL) || (*dom_sids == NULL) ||
1009 (*alt_names == NULL))
1010 return NT_STATUS_NO_MEMORY;
1012 for (i=0; i<num; i++) {
1013 (*names)[start_idx+i] = tmp_names[i];
1014 (*dom_sids)[start_idx+i] = tmp_sids[i];
1015 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1021 /* find the lockout policy for a domain */
1022 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1023 TALLOC_CTX *mem_ctx,
1024 SAM_UNK_INFO_12 *lockout_policy)
1027 struct rpc_pipe_client *cli;
1031 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1033 if ( !winbindd_can_contact_domain( domain ) ) {
1034 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1036 return NT_STATUS_NOT_SUPPORTED;
1039 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1040 if (!NT_STATUS_IS_OK(result)) {
1044 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
1045 if (!NT_STATUS_IS_OK(result)) {
1049 *lockout_policy = ctr.info.inf12;
1051 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
1052 ctr.info.inf12.bad_attempt_lockout));
1059 /* find the password policy for a domain */
1060 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1061 TALLOC_CTX *mem_ctx,
1062 SAM_UNK_INFO_1 *password_policy)
1065 struct rpc_pipe_client *cli;
1069 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1071 if ( !winbindd_can_contact_domain( domain ) ) {
1072 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1074 return NT_STATUS_NOT_SUPPORTED;
1077 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1078 if (!NT_STATUS_IS_OK(result)) {
1082 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
1083 if (!NT_STATUS_IS_OK(result)) {
1087 *password_policy = ctr.info.inf1;
1089 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1090 ctr.info.inf1.min_length_password));
1098 /* the rpc backend methods are exposed via this structure */
1099 struct winbindd_methods msrpc_methods = {
1106 msrpc_rids_to_names,
1109 msrpc_lookup_useraliases,
1112 msrpc_lockout_policy,
1113 msrpc_password_policy,