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, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 WINBIND_USERINFO **info)
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))
66 uint32 num_dom_users, j;
67 uint32 max_entries, max_size;
73 ctr.sam.info1 = &info1;
75 if (!(ctx2 = talloc_init("winbindd enum_users")))
76 return NT_STATUS_NO_MEMORY;
78 /* this next bit is copied from net_user_list_internal() */
80 get_query_dispinfo_params(loop_count, &max_entries,
83 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol,
86 max_entries, max_size,
91 *num_entries += num_dom_users;
93 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
98 return NT_STATUS_NO_MEMORY;
101 for (j = 0; j < num_dom_users; i++, j++) {
102 fstring username, fullname;
103 uint32 rid = ctr.sam.info1->sam[j].rid_user;
105 unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1);
106 unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
108 (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
109 (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
110 (*info)[i].homedir = NULL;
111 (*info)[i].shell = NULL;
112 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
114 /* For the moment we set the primary group for
115 every user to be the Domain Users group.
116 There are serious problems with determining
117 the actual primary group for large domains.
118 This should really be made into a 'winbind
119 force group' smb.conf parameter or
120 something like that. */
122 sid_compose(&(*info)[i].group_sid, &domain->sid,
123 DOMAIN_GROUP_RID_USERS);
126 talloc_destroy(ctx2);
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)
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 acct_info *info2 = NULL;
162 TALLOC_CTX *mem_ctx2;
164 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
166 /* start is updated by this call. */
167 status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol,
169 0xFFFF, /* buffer size? */
172 if (!NT_STATUS_IS_OK(status) &&
173 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
174 talloc_destroy(mem_ctx2);
178 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
180 (*num_entries) + count);
182 talloc_destroy(mem_ctx2);
183 status = NT_STATUS_NO_MEMORY;
187 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
188 (*num_entries) += count;
189 talloc_destroy(mem_ctx2);
190 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
195 /* List all domain groups */
197 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
200 struct acct_info **info)
204 struct rpc_pipe_client *cli;
209 DEBUG(3,("rpc: enum_local_groups\n"));
211 if ( !winbindd_can_contact_domain( domain ) ) {
212 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
217 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
218 if (!NT_STATUS_IS_OK(result))
222 struct acct_info *info2 = NULL;
223 uint32 count = 0, start = *num_entries;
224 TALLOC_CTX *mem_ctx2;
226 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
228 result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol,
229 &start, 0xFFFF, &info2,
232 if (!NT_STATUS_IS_OK(result) &&
233 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
235 talloc_destroy(mem_ctx2);
239 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
241 (*num_entries) + count);
243 talloc_destroy(mem_ctx2);
244 return NT_STATUS_NO_MEMORY;
247 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
248 (*num_entries) += count;
249 talloc_destroy(mem_ctx2);
251 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
256 /* convert a single name to a sid in a domain */
257 NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
259 enum winbindd_cmd original_cmd,
260 const char *domain_name,
263 enum lsa_SidType *type)
266 DOM_SID *sids = NULL;
267 enum lsa_SidType *types = NULL;
268 char *full_name = NULL;
269 struct rpc_pipe_client *cli;
270 POLICY_HND lsa_policy;
272 if (name == NULL || *name=='\0') {
273 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
274 } else if (domain_name == NULL || *domain_name == '\0') {
275 full_name = talloc_asprintf(mem_ctx, "%s", name);
277 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
280 DEBUG(0, ("talloc_asprintf failed!\n"));
281 return NT_STATUS_NO_MEMORY;
284 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
286 ws_name_return( full_name, WB_REPLACE_CHAR );
288 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
290 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
291 if (!NT_STATUS_IS_OK(result))
294 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
295 (const char**) &full_name, NULL, 1, &sids, &types);
297 if (!NT_STATUS_IS_OK(result))
300 /* Return rid and type if lookup successful */
302 sid_copy(sid, &sids[0]);
309 convert a domain SID to a user or group name
311 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
316 enum lsa_SidType *type)
320 enum lsa_SidType *types;
322 struct rpc_pipe_client *cli;
323 POLICY_HND lsa_policy;
325 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
328 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
329 if (!NT_STATUS_IS_OK(result)) {
330 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
336 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
337 1, sid, &domains, &names, &types);
338 if (!NT_STATUS_IS_OK(result)) {
339 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
344 *type = (enum lsa_SidType)types[0];
345 *domain_name = domains[0];
348 ws_name_replace( *name, WB_REPLACE_CHAR );
350 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
354 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
361 enum lsa_SidType **types)
365 struct rpc_pipe_client *cli;
366 POLICY_HND lsa_policy;
371 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
374 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
376 return NT_STATUS_NO_MEMORY;
382 for (i=0; i<num_rids; i++) {
383 if (!sid_compose(&sids[i], sid, rids[i])) {
384 return NT_STATUS_INTERNAL_ERROR;
388 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
389 if (!NT_STATUS_IS_OK(result)) {
393 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
394 num_rids, sids, &domains,
396 if (!NT_STATUS_IS_OK(result) &&
397 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
402 for (i=0; i<num_rids; i++) {
403 if ((*types)[i] != SID_NAME_UNKNOWN) {
404 ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
405 *domain_name = domains[i];
412 /* Lookup user information from a rid or username. */
413 static NTSTATUS query_user(struct winbindd_domain *domain,
415 const DOM_SID *user_sid,
416 WINBIND_USERINFO *user_info)
418 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
419 POLICY_HND dom_pol, user_pol;
420 SAM_USERINFO_CTR *ctr;
423 NET_USER_INFO_3 *user;
424 struct rpc_pipe_client *cli;
426 DEBUG(3,("rpc: query_user sid=%s\n",
427 sid_to_string(sid_string, user_sid)));
429 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
430 return NT_STATUS_UNSUCCESSFUL;
432 user_info->homedir = NULL;
433 user_info->shell = NULL;
434 user_info->primary_gid = (gid_t)-1;
436 /* try netsamlogon cache first */
438 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
441 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
442 sid_string_static(user_sid)));
444 sid_compose(&user_info->user_sid, &domain->sid, user->user_rid);
445 sid_compose(&user_info->group_sid, &domain->sid,
448 user_info->acct_name = unistr2_tdup(mem_ctx,
449 &user->uni_user_name);
450 user_info->full_name = unistr2_tdup(mem_ctx,
451 &user->uni_full_name);
458 if ( !winbindd_can_contact_domain( domain ) ) {
459 DEBUG(10,("query_user: No incoming trust for domain %s\n",
464 if ( !winbindd_can_contact_domain( domain ) ) {
465 DEBUG(10,("query_user: No incoming trust for domain %s\n",
470 /* no cache; hit the wire */
472 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
473 if (!NT_STATUS_IS_OK(result))
476 /* Get user handle */
477 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
478 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid,
481 if (!NT_STATUS_IS_OK(result))
485 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
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 ctr->info.id21->group_rid);
496 user_info->acct_name = unistr2_tdup(mem_ctx,
497 &ctr->info.id21->uni_user_name);
498 user_info->full_name = unistr2_tdup(mem_ctx,
499 &ctr->info.id21->uni_full_name);
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 DOM_GID *user_groups;
520 struct rpc_pipe_client *cli;
522 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
523 sid_to_string(sid_string, user_sid)));
525 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
526 return NT_STATUS_UNSUCCESSFUL;
529 *user_grpsids = NULL;
531 /* so lets see if we have a cached user_info_3 */
532 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
533 num_groups, user_grpsids);
535 if (NT_STATUS_IS_OK(result)) {
539 if ( !winbindd_can_contact_domain( domain ) ) {
540 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
543 /* Tell the cache manager not to remember this one */
545 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
548 /* no cache; hit the wire */
550 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
551 if (!NT_STATUS_IS_OK(result))
554 /* Get user handle */
555 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
556 des_access, user_rid, &user_pol);
558 if (!NT_STATUS_IS_OK(result))
561 /* Query user rids */
562 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
563 num_groups, &user_groups);
565 rpccli_samr_close(cli, mem_ctx, &user_pol);
567 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
570 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
571 if (!(*user_grpsids))
572 return NT_STATUS_NO_MEMORY;
574 for (i=0;i<(*num_groups);i++) {
575 sid_copy(&((*user_grpsids)[i]), &domain->sid);
576 sid_append_rid(&((*user_grpsids)[i]),
577 user_groups[i].g_rid);
583 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
585 uint32 num_sids, const DOM_SID *sids,
586 uint32 *num_aliases, uint32 **alias_rids)
588 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
590 DOM_SID2 *query_sids;
591 uint32 num_query_sids = 0;
593 struct rpc_pipe_client *cli;
594 uint32 *alias_rids_query, num_aliases_query;
595 int rangesize = MAX_SAM_ENTRIES_W2K;
596 uint32 total_sids = 0;
602 DEBUG(3,("rpc: lookup_useraliases\n"));
604 if ( !winbindd_can_contact_domain( domain ) ) {
605 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
610 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
611 if (!NT_STATUS_IS_OK(result))
617 num_query_sids = MIN(num_sids - total_sids, rangesize);
619 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
620 num_queries, num_query_sids));
622 if (num_query_sids) {
623 query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
624 if (query_sids == NULL) {
625 return NT_STATUS_NO_MEMORY;
631 for (i=0; i<num_query_sids; i++) {
632 sid_copy(&query_sids[i].sid, &sids[total_sids++]);
633 query_sids[i].num_auths = query_sids[i].sid.num_auths;
638 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
639 num_query_sids, query_sids,
643 if (!NT_STATUS_IS_OK(result)) {
646 TALLOC_FREE(query_sids);
652 for (i=0; i<num_aliases_query; i++) {
653 size_t na = *num_aliases;
654 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i],
656 return NT_STATUS_NO_MEMORY;
661 TALLOC_FREE(query_sids);
665 } while (total_sids < num_sids);
668 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
669 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
675 /* Lookup group membership given a rid. */
676 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
678 const DOM_SID *group_sid, uint32 *num_names,
679 DOM_SID **sid_mem, char ***names,
682 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
683 uint32 i, total_names = 0;
684 POLICY_HND dom_pol, group_pol;
685 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
686 uint32 *rid_mem = NULL;
690 struct rpc_pipe_client *cli;
691 unsigned int orig_timeout;
693 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
694 sid_to_string(sid_string, group_sid)));
696 if ( !winbindd_can_contact_domain( domain ) ) {
697 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
702 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
703 return NT_STATUS_UNSUCCESSFUL;
707 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
708 if (!NT_STATUS_IS_OK(result))
711 result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,
712 des_access, group_rid, &group_pol);
714 if (!NT_STATUS_IS_OK(result))
717 /* Step #1: Get a list of user rids that are the members of the
720 /* This call can take a long time - allow the server to time out.
721 35 seconds should do it. */
723 orig_timeout = cli_set_timeout(cli->cli, 35000);
725 result = rpccli_samr_query_groupmem(cli, mem_ctx,
726 &group_pol, num_names, &rid_mem,
729 /* And restore our original timeout. */
730 cli_set_timeout(cli->cli, orig_timeout);
732 rpccli_samr_close(cli, mem_ctx, &group_pol);
734 if (!NT_STATUS_IS_OK(result))
744 /* Step #2: Convert list of rids into list of usernames. Do this
745 in bunches of ~1000 to avoid crashing NT4. It looks like there
746 is a buffer overflow or something like that lurking around
749 #define MAX_LOOKUP_RIDS 900
751 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
752 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
753 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
755 for (j=0;j<(*num_names);j++)
756 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
758 if (*num_names>0 && (!*names || !*name_types))
759 return NT_STATUS_NO_MEMORY;
761 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
762 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
763 uint32 tmp_num_names = 0;
764 char **tmp_names = NULL;
765 uint32 *tmp_types = NULL;
767 /* Lookup a chunk of rids */
769 result = rpccli_samr_lookup_rids(cli, mem_ctx,
774 &tmp_names, &tmp_types);
776 /* see if we have a real error (and yes the
777 STATUS_SOME_UNMAPPED is the one returned from 2k) */
779 if (!NT_STATUS_IS_OK(result) &&
780 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
783 /* Copy result into array. The talloc system will take
784 care of freeing the temporary arrays later on. */
786 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
789 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
792 total_names += tmp_num_names;
795 *num_names = total_names;
804 static int get_ldap_seq(const char *server, int port, uint32 *seq)
808 const char *attrs[] = {"highestCommittedUSN", NULL};
809 LDAPMessage *res = NULL;
810 char **values = NULL;
813 *seq = DOM_SEQUENCE_NONE;
816 * Parameterised (5) second timeout on open. This is needed as the
817 * search timeout doesn't seem to apply to doing an open as well. JRA.
820 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
824 /* Timeout if no response within 20 seconds. */
828 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
829 CONST_DISCARD(char **, attrs), 0, &to, &res))
832 if (ldap_count_entries(ldp, res) != 1)
835 values = ldap_get_values(ldp, res, "highestCommittedUSN");
836 if (!values || !values[0])
839 *seq = atoi(values[0]);
845 ldap_value_free(values);
853 /**********************************************************************
854 Get the sequence number for a Windows AD native mode domain using
856 **********************************************************************/
858 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
863 fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr));
864 if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) {
865 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
866 "number for Domain (%s) from DC (%s)\n",
867 domain->name, ipstr));
872 #endif /* HAVE_LDAP */
874 /* find the sequence number for a domain */
875 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
881 BOOL got_seq_num = False;
882 struct rpc_pipe_client *cli;
884 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
886 if ( !winbindd_can_contact_domain( domain ) ) {
887 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
893 *seq = DOM_SEQUENCE_NONE;
895 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
896 return NT_STATUS_NO_MEMORY;
899 if ( domain->active_directory )
903 DEBUG(8,("using get_ldap_seq() to retrieve the "
904 "sequence number\n"));
906 res = get_ldap_sequence_number( domain, seq );
909 result = NT_STATUS_OK;
910 DEBUG(10,("domain_sequence_number: LDAP for "
912 domain->name, *seq));
916 DEBUG(10,("domain_sequence_number: failed to get LDAP "
917 "sequence number for domain %s\n",
920 #endif /* HAVE_LDAP */
922 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
923 if (!NT_STATUS_IS_OK(result)) {
927 /* Query domain info */
929 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
931 if (NT_STATUS_IS_OK(result)) {
932 *seq = ctr.info.inf8.seq_num;
937 /* retry with info-level 2 in case the dc does not support info-level 8
938 * (like all older samba2 and samba3 dc's - Guenther */
940 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
942 if (NT_STATUS_IS_OK(result)) {
943 *seq = ctr.info.inf2.seq_num;
949 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
950 domain->name, (unsigned)*seq));
952 DEBUG(10,("domain_sequence_number: failed to get sequence "
953 "number (%u) for domain %s\n",
954 (unsigned)*seq, domain->name ));
959 talloc_destroy(mem_ctx);
964 /* get a list of trusted domains */
965 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
972 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
974 struct rpc_pipe_client *cli;
975 POLICY_HND lsa_policy;
977 DEBUG(3,("rpc: trusted_domains\n"));
984 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
985 if (!NT_STATUS_IS_OK(result))
988 result = STATUS_MORE_ENTRIES;
990 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
991 uint32 start_idx, num;
996 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
997 &lsa_policy, &enum_ctx,
1001 if (!NT_STATUS_IS_OK(result) &&
1002 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1005 start_idx = *num_domains;
1006 *num_domains += num;
1007 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1008 char *, *num_domains);
1009 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1010 DOM_SID, *num_domains);
1011 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1012 char *, *num_domains);
1013 if ((*names == NULL) || (*dom_sids == NULL) ||
1014 (*alt_names == NULL))
1015 return NT_STATUS_NO_MEMORY;
1017 for (i=0; i<num; i++) {
1018 (*names)[start_idx+i] = tmp_names[i];
1019 (*dom_sids)[start_idx+i] = tmp_sids[i];
1020 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1026 /* find the lockout policy for a domain */
1027 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1028 TALLOC_CTX *mem_ctx,
1029 SAM_UNK_INFO_12 *lockout_policy)
1032 struct rpc_pipe_client *cli;
1036 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1038 if ( !winbindd_can_contact_domain( domain ) ) {
1039 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1041 return NT_STATUS_NOT_SUPPORTED;
1044 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1045 if (!NT_STATUS_IS_OK(result)) {
1049 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
1050 if (!NT_STATUS_IS_OK(result)) {
1054 *lockout_policy = ctr.info.inf12;
1056 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
1057 ctr.info.inf12.bad_attempt_lockout));
1064 /* find the password policy for a domain */
1065 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1066 TALLOC_CTX *mem_ctx,
1067 SAM_UNK_INFO_1 *password_policy)
1070 struct rpc_pipe_client *cli;
1074 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1076 if ( !winbindd_can_contact_domain( domain ) ) {
1077 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1079 return NT_STATUS_NOT_SUPPORTED;
1082 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1083 if (!NT_STATUS_IS_OK(result)) {
1087 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
1088 if (!NT_STATUS_IS_OK(result)) {
1092 *password_policy = ctr.info.inf1;
1094 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1095 ctr.info.inf1.min_length_password));
1103 /* the rpc backend methods are exposed via this structure */
1104 struct winbindd_methods msrpc_methods = {
1111 msrpc_rids_to_names,
1114 msrpc_lookup_useraliases,
1117 msrpc_lockout_policy,
1118 msrpc_password_policy,