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)-1);
100 unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
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 status = 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;
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_static(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 SAM_USERINFO_CTR *ctr;
415 NET_USER_INFO_3 *user;
416 struct rpc_pipe_client *cli;
418 DEBUG(3,("rpc: query_user sid=%s\n",
419 sid_to_string(sid_string, user_sid)));
421 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
422 return NT_STATUS_UNSUCCESSFUL;
424 user_info->homedir = NULL;
425 user_info->shell = NULL;
426 user_info->primary_gid = (gid_t)-1;
428 /* try netsamlogon cache first */
430 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
433 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
434 sid_string_static(user_sid)));
436 sid_compose(&user_info->user_sid, &domain->sid, user->user_rid);
437 sid_compose(&user_info->group_sid, &domain->sid,
440 user_info->acct_name = unistr2_tdup(mem_ctx,
441 &user->uni_user_name);
442 user_info->full_name = unistr2_tdup(mem_ctx,
443 &user->uni_full_name);
450 if ( !winbindd_can_contact_domain( domain ) ) {
451 DEBUG(10,("query_user: No incoming trust for domain %s\n",
456 if ( !winbindd_can_contact_domain( domain ) ) {
457 DEBUG(10,("query_user: No incoming trust for domain %s\n",
462 /* no cache; hit the wire */
464 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
465 if (!NT_STATUS_IS_OK(result))
468 /* Get user handle */
469 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
470 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid,
473 if (!NT_STATUS_IS_OK(result))
477 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
480 rpccli_samr_close(cli, mem_ctx, &user_pol);
482 if (!NT_STATUS_IS_OK(result))
485 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
486 sid_compose(&user_info->group_sid, &domain->sid,
487 ctr->info.id21->group_rid);
488 user_info->acct_name = unistr2_tdup(mem_ctx,
489 &ctr->info.id21->uni_user_name);
490 user_info->full_name = unistr2_tdup(mem_ctx,
491 &ctr->info.id21->uni_full_name);
492 user_info->homedir = NULL;
493 user_info->shell = NULL;
494 user_info->primary_gid = (gid_t)-1;
499 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
500 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
502 const DOM_SID *user_sid,
503 uint32 *num_groups, DOM_SID **user_grpsids)
505 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
506 POLICY_HND dom_pol, user_pol;
507 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
508 DOM_GID *user_groups;
512 struct rpc_pipe_client *cli;
514 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
515 sid_to_string(sid_string, user_sid)));
517 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
518 return NT_STATUS_UNSUCCESSFUL;
521 *user_grpsids = NULL;
523 /* so lets see if we have a cached user_info_3 */
524 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
525 num_groups, user_grpsids);
527 if (NT_STATUS_IS_OK(result)) {
531 if ( !winbindd_can_contact_domain( domain ) ) {
532 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
535 /* Tell the cache manager not to remember this one */
537 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
540 /* no cache; hit the wire */
542 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
543 if (!NT_STATUS_IS_OK(result))
546 /* Get user handle */
547 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
548 des_access, user_rid, &user_pol);
550 if (!NT_STATUS_IS_OK(result))
553 /* Query user rids */
554 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
555 num_groups, &user_groups);
557 rpccli_samr_close(cli, mem_ctx, &user_pol);
559 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
562 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
563 if (!(*user_grpsids))
564 return NT_STATUS_NO_MEMORY;
566 for (i=0;i<(*num_groups);i++) {
567 sid_copy(&((*user_grpsids)[i]), &domain->sid);
568 sid_append_rid(&((*user_grpsids)[i]),
569 user_groups[i].g_rid);
575 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
577 uint32 num_sids, const DOM_SID *sids,
578 uint32 *num_aliases, uint32 **alias_rids)
580 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
582 DOM_SID2 *query_sids;
583 uint32 num_query_sids = 0;
585 struct rpc_pipe_client *cli;
586 uint32 *alias_rids_query, num_aliases_query;
587 int rangesize = MAX_SAM_ENTRIES_W2K;
588 uint32 total_sids = 0;
594 DEBUG(3,("rpc: lookup_useraliases\n"));
596 if ( !winbindd_can_contact_domain( domain ) ) {
597 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
602 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
603 if (!NT_STATUS_IS_OK(result))
609 num_query_sids = MIN(num_sids - total_sids, rangesize);
611 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
612 num_queries, num_query_sids));
614 if (num_query_sids) {
615 query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
616 if (query_sids == NULL) {
617 return NT_STATUS_NO_MEMORY;
623 for (i=0; i<num_query_sids; i++) {
624 sid_copy(&query_sids[i].sid, &sids[total_sids++]);
625 query_sids[i].num_auths = query_sids[i].sid.num_auths;
630 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
631 num_query_sids, query_sids,
635 if (!NT_STATUS_IS_OK(result)) {
638 TALLOC_FREE(query_sids);
644 for (i=0; i<num_aliases_query; i++) {
645 size_t na = *num_aliases;
646 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i],
648 return NT_STATUS_NO_MEMORY;
653 TALLOC_FREE(query_sids);
657 } while (total_sids < num_sids);
660 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
661 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
667 /* Lookup group membership given a rid. */
668 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
670 const DOM_SID *group_sid, uint32 *num_names,
671 DOM_SID **sid_mem, char ***names,
674 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
675 uint32 i, total_names = 0;
676 POLICY_HND dom_pol, group_pol;
677 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
678 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_to_string(sid_string, 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_open_group(cli, mem_ctx, &dom_pol,
704 des_access, group_rid, &group_pol);
706 if (!NT_STATUS_IS_OK(result))
709 /* Step #1: Get a list of user rids that are the members of the
712 /* This call can take a long time - allow the server to time out.
713 35 seconds should do it. */
715 orig_timeout = cli_set_timeout(cli->cli, 35000);
717 result = rpccli_samr_query_groupmem(cli, mem_ctx,
718 &group_pol, num_names, &rid_mem,
721 /* And restore our original timeout. */
722 cli_set_timeout(cli->cli, orig_timeout);
724 rpccli_samr_close(cli, mem_ctx, &group_pol);
726 if (!NT_STATUS_IS_OK(result))
736 /* Step #2: Convert list of rids into list of usernames. Do this
737 in bunches of ~1000 to avoid crashing NT4. It looks like there
738 is a buffer overflow or something like that lurking around
741 #define MAX_LOOKUP_RIDS 900
743 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
744 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
745 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
747 for (j=0;j<(*num_names);j++)
748 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
750 if (*num_names>0 && (!*names || !*name_types))
751 return NT_STATUS_NO_MEMORY;
753 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
754 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
755 uint32 tmp_num_names = 0;
756 char **tmp_names = NULL;
757 uint32 *tmp_types = NULL;
759 /* Lookup a chunk of rids */
761 result = rpccli_samr_lookup_rids(cli, mem_ctx,
766 &tmp_names, &tmp_types);
768 /* see if we have a real error (and yes the
769 STATUS_SOME_UNMAPPED is the one returned from 2k) */
771 if (!NT_STATUS_IS_OK(result) &&
772 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
775 /* Copy result into array. The talloc system will take
776 care of freeing the temporary arrays later on. */
778 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
781 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
784 total_names += tmp_num_names;
787 *num_names = total_names;
796 static int get_ldap_seq(const char *server, int port, uint32 *seq)
800 const char *attrs[] = {"highestCommittedUSN", NULL};
801 LDAPMessage *res = NULL;
802 char **values = NULL;
805 *seq = DOM_SEQUENCE_NONE;
808 * Parameterised (5) second timeout on open. This is needed as the
809 * search timeout doesn't seem to apply to doing an open as well. JRA.
812 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
816 /* Timeout if no response within 20 seconds. */
820 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
821 CONST_DISCARD(char **, attrs), 0, &to, &res))
824 if (ldap_count_entries(ldp, res) != 1)
827 values = ldap_get_values(ldp, res, "highestCommittedUSN");
828 if (!values || !values[0])
831 *seq = atoi(values[0]);
837 ldap_value_free(values);
845 /**********************************************************************
846 Get the sequence number for a Windows AD native mode domain using
848 **********************************************************************/
850 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
855 fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr));
856 if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) {
857 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
858 "number for Domain (%s) from DC (%s)\n",
859 domain->name, ipstr));
864 #endif /* HAVE_LDAP */
866 /* find the sequence number for a domain */
867 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
873 BOOL got_seq_num = False;
874 struct rpc_pipe_client *cli;
876 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
878 if ( !winbindd_can_contact_domain( domain ) ) {
879 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
885 *seq = DOM_SEQUENCE_NONE;
887 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
888 return NT_STATUS_NO_MEMORY;
891 if ( domain->active_directory )
895 DEBUG(8,("using get_ldap_seq() to retrieve the "
896 "sequence number\n"));
898 res = get_ldap_sequence_number( domain, seq );
901 result = NT_STATUS_OK;
902 DEBUG(10,("domain_sequence_number: LDAP for "
904 domain->name, *seq));
908 DEBUG(10,("domain_sequence_number: failed to get LDAP "
909 "sequence number for domain %s\n",
912 #endif /* HAVE_LDAP */
914 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
915 if (!NT_STATUS_IS_OK(result)) {
919 /* Query domain info */
921 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
923 if (NT_STATUS_IS_OK(result)) {
924 *seq = ctr.info.inf8.seq_num;
929 /* retry with info-level 2 in case the dc does not support info-level 8
930 * (like all older samba2 and samba3 dc's - Guenther */
932 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
934 if (NT_STATUS_IS_OK(result)) {
935 *seq = ctr.info.inf2.seq_num;
941 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
942 domain->name, (unsigned)*seq));
944 DEBUG(10,("domain_sequence_number: failed to get sequence "
945 "number (%u) for domain %s\n",
946 (unsigned)*seq, domain->name ));
951 talloc_destroy(mem_ctx);
956 /* get a list of trusted domains */
957 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
964 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
966 struct rpc_pipe_client *cli;
967 POLICY_HND lsa_policy;
969 DEBUG(3,("rpc: trusted_domains\n"));
976 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
977 if (!NT_STATUS_IS_OK(result))
980 result = STATUS_MORE_ENTRIES;
982 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
983 uint32 start_idx, num;
988 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
989 &lsa_policy, &enum_ctx,
993 if (!NT_STATUS_IS_OK(result) &&
994 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
997 start_idx = *num_domains;
999 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1000 char *, *num_domains);
1001 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1002 DOM_SID, *num_domains);
1003 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1004 char *, *num_domains);
1005 if ((*names == NULL) || (*dom_sids == NULL) ||
1006 (*alt_names == NULL))
1007 return NT_STATUS_NO_MEMORY;
1009 for (i=0; i<num; i++) {
1010 (*names)[start_idx+i] = tmp_names[i];
1011 (*dom_sids)[start_idx+i] = tmp_sids[i];
1012 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1018 /* find the lockout policy for a domain */
1019 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1020 TALLOC_CTX *mem_ctx,
1021 SAM_UNK_INFO_12 *lockout_policy)
1024 struct rpc_pipe_client *cli;
1028 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1030 if ( !winbindd_can_contact_domain( domain ) ) {
1031 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1033 return NT_STATUS_NOT_SUPPORTED;
1036 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1037 if (!NT_STATUS_IS_OK(result)) {
1041 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
1042 if (!NT_STATUS_IS_OK(result)) {
1046 *lockout_policy = ctr.info.inf12;
1048 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
1049 ctr.info.inf12.bad_attempt_lockout));
1056 /* find the password policy for a domain */
1057 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1058 TALLOC_CTX *mem_ctx,
1059 SAM_UNK_INFO_1 *password_policy)
1062 struct rpc_pipe_client *cli;
1066 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1068 if ( !winbindd_can_contact_domain( domain ) ) {
1069 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1071 return NT_STATUS_NOT_SUPPORTED;
1074 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1075 if (!NT_STATUS_IS_OK(result)) {
1079 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
1080 if (!NT_STATUS_IS_OK(result)) {
1084 *password_policy = ctr.info.inf1;
1086 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1087 ctr.info.inf1.min_length_password));
1095 /* the rpc backend methods are exposed via this structure */
1096 struct winbindd_methods msrpc_methods = {
1103 msrpc_rids_to_names,
1106 msrpc_lookup_useraliases,
1109 msrpc_lockout_policy,
1110 msrpc_password_policy,