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 2 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 DEBUG(3,("rpc: name_to_sid name=%s\n", domain_name));
274 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
276 DEBUG(3,("rpc: name_to_sid name=%s\\%s\n", domain_name, 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 ws_name_return( full_name, WB_REPLACE_CHAR );
286 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
288 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
289 if (!NT_STATUS_IS_OK(result))
292 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
293 (const char**) &full_name, NULL, &sids, &types);
295 if (!NT_STATUS_IS_OK(result))
298 /* Return rid and type if lookup successful */
300 sid_copy(sid, &sids[0]);
307 convert a domain SID to a user or group name
309 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
314 enum lsa_SidType *type)
318 enum lsa_SidType *types;
320 struct rpc_pipe_client *cli;
321 POLICY_HND lsa_policy;
323 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
326 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
327 if (!NT_STATUS_IS_OK(result)) {
328 DEBUG(2,("msrpc_sid_to_name: cm_connect_lsa() failed (%s)\n",
334 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
335 1, sid, &domains, &names, &types);
336 if (!NT_STATUS_IS_OK(result)) {
337 DEBUG(2,("msrpc_sid_to_name: rpccli_lsa_lookup_sids() failed (%s)\n",
342 *type = (enum lsa_SidType)types[0];
343 *domain_name = domains[0];
346 ws_name_replace( *name, WB_REPLACE_CHAR );
348 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
352 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
359 enum lsa_SidType **types)
363 struct rpc_pipe_client *cli;
364 POLICY_HND lsa_policy;
369 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
372 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
374 return NT_STATUS_NO_MEMORY;
380 for (i=0; i<num_rids; i++) {
381 if (!sid_compose(&sids[i], sid, rids[i])) {
382 return NT_STATUS_INTERNAL_ERROR;
386 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
387 if (!NT_STATUS_IS_OK(result)) {
391 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
392 num_rids, sids, &domains,
394 if (!NT_STATUS_IS_OK(result) &&
395 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
400 for (i=0; i<num_rids; i++) {
401 if ((*types)[i] != SID_NAME_UNKNOWN) {
402 ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
403 *domain_name = domains[i];
410 /* Lookup user information from a rid or username. */
411 static NTSTATUS query_user(struct winbindd_domain *domain,
413 const DOM_SID *user_sid,
414 WINBIND_USERINFO *user_info)
416 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
417 POLICY_HND dom_pol, user_pol;
418 SAM_USERINFO_CTR *ctr;
421 NET_USER_INFO_3 *user;
422 struct rpc_pipe_client *cli;
424 DEBUG(3,("rpc: query_user sid=%s\n",
425 sid_to_string(sid_string, user_sid)));
427 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
428 return NT_STATUS_UNSUCCESSFUL;
430 user_info->homedir = NULL;
431 user_info->shell = NULL;
432 user_info->primary_gid = (gid_t)-1;
434 /* try netsamlogon cache first */
436 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
439 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
440 sid_string_static(user_sid)));
442 sid_compose(&user_info->user_sid, &domain->sid, user->user_rid);
443 sid_compose(&user_info->group_sid, &domain->sid,
446 user_info->acct_name = unistr2_tdup(mem_ctx,
447 &user->uni_user_name);
448 user_info->full_name = unistr2_tdup(mem_ctx,
449 &user->uni_full_name);
456 if ( !winbindd_can_contact_domain( domain ) ) {
457 DEBUG(10,("query_user: No incoming trust for domain %s\n",
462 if ( !winbindd_can_contact_domain( domain ) ) {
463 DEBUG(10,("query_user: No incoming trust for domain %s\n",
468 /* no cache; hit the wire */
470 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
471 if (!NT_STATUS_IS_OK(result))
474 /* Get user handle */
475 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
476 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid,
479 if (!NT_STATUS_IS_OK(result))
483 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
486 rpccli_samr_close(cli, mem_ctx, &user_pol);
488 if (!NT_STATUS_IS_OK(result))
491 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
492 sid_compose(&user_info->group_sid, &domain->sid,
493 ctr->info.id21->group_rid);
494 user_info->acct_name = unistr2_tdup(mem_ctx,
495 &ctr->info.id21->uni_user_name);
496 user_info->full_name = unistr2_tdup(mem_ctx,
497 &ctr->info.id21->uni_full_name);
498 user_info->homedir = NULL;
499 user_info->shell = NULL;
500 user_info->primary_gid = (gid_t)-1;
505 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
506 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
508 const DOM_SID *user_sid,
509 uint32 *num_groups, DOM_SID **user_grpsids)
511 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
512 POLICY_HND dom_pol, user_pol;
513 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
514 DOM_GID *user_groups;
518 struct rpc_pipe_client *cli;
520 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
521 sid_to_string(sid_string, 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_open_user(cli, mem_ctx, &dom_pol,
554 des_access, user_rid, &user_pol);
556 if (!NT_STATUS_IS_OK(result))
559 /* Query user rids */
560 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
561 num_groups, &user_groups);
563 rpccli_samr_close(cli, mem_ctx, &user_pol);
565 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
568 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
569 if (!(*user_grpsids))
570 return NT_STATUS_NO_MEMORY;
572 for (i=0;i<(*num_groups);i++) {
573 sid_copy(&((*user_grpsids)[i]), &domain->sid);
574 sid_append_rid(&((*user_grpsids)[i]),
575 user_groups[i].g_rid);
581 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
583 uint32 num_sids, const DOM_SID *sids,
584 uint32 *num_aliases, uint32 **alias_rids)
586 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
588 DOM_SID2 *query_sids;
589 uint32 num_query_sids = 0;
591 struct rpc_pipe_client *cli;
592 uint32 *alias_rids_query, num_aliases_query;
593 int rangesize = MAX_SAM_ENTRIES_W2K;
594 uint32 total_sids = 0;
600 DEBUG(3,("rpc: lookup_useraliases\n"));
602 if ( !winbindd_can_contact_domain( domain ) ) {
603 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
608 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
609 if (!NT_STATUS_IS_OK(result))
615 num_query_sids = MIN(num_sids - total_sids, rangesize);
617 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
618 num_queries, num_query_sids));
620 if (num_query_sids) {
621 query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
622 if (query_sids == NULL) {
623 return NT_STATUS_NO_MEMORY;
629 for (i=0; i<num_query_sids; i++) {
630 sid_copy(&query_sids[i].sid, &sids[total_sids++]);
631 query_sids[i].num_auths = query_sids[i].sid.num_auths;
636 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
637 num_query_sids, query_sids,
641 if (!NT_STATUS_IS_OK(result)) {
644 TALLOC_FREE(query_sids);
650 for (i=0; i<num_aliases_query; i++) {
651 size_t na = *num_aliases;
652 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i],
654 return NT_STATUS_NO_MEMORY;
659 TALLOC_FREE(query_sids);
663 } while (total_sids < num_sids);
666 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
667 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
673 /* Lookup group membership given a rid. */
674 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
676 const DOM_SID *group_sid, uint32 *num_names,
677 DOM_SID **sid_mem, char ***names,
680 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
681 uint32 i, total_names = 0;
682 POLICY_HND dom_pol, group_pol;
683 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
684 uint32 *rid_mem = NULL;
688 struct rpc_pipe_client *cli;
689 unsigned int orig_timeout;
691 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
692 sid_to_string(sid_string, group_sid)));
694 if ( !winbindd_can_contact_domain( domain ) ) {
695 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
700 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
701 return NT_STATUS_UNSUCCESSFUL;
705 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
706 if (!NT_STATUS_IS_OK(result))
709 result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,
710 des_access, group_rid, &group_pol);
712 if (!NT_STATUS_IS_OK(result))
715 /* Step #1: Get a list of user rids that are the members of the
718 /* This call can take a long time - allow the server to time out.
719 35 seconds should do it. */
721 orig_timeout = cli_set_timeout(cli->cli, 35000);
723 result = rpccli_samr_query_groupmem(cli, mem_ctx,
724 &group_pol, num_names, &rid_mem,
727 /* And restore our original timeout. */
728 cli_set_timeout(cli->cli, orig_timeout);
730 rpccli_samr_close(cli, mem_ctx, &group_pol);
732 if (!NT_STATUS_IS_OK(result))
742 /* Step #2: Convert list of rids into list of usernames. Do this
743 in bunches of ~1000 to avoid crashing NT4. It looks like there
744 is a buffer overflow or something like that lurking around
747 #define MAX_LOOKUP_RIDS 900
749 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
750 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
751 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
753 for (j=0;j<(*num_names);j++)
754 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
756 if (*num_names>0 && (!*names || !*name_types))
757 return NT_STATUS_NO_MEMORY;
759 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
760 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
761 uint32 tmp_num_names = 0;
762 char **tmp_names = NULL;
763 uint32 *tmp_types = NULL;
765 /* Lookup a chunk of rids */
767 result = rpccli_samr_lookup_rids(cli, mem_ctx,
772 &tmp_names, &tmp_types);
774 /* see if we have a real error (and yes the
775 STATUS_SOME_UNMAPPED is the one returned from 2k) */
777 if (!NT_STATUS_IS_OK(result) &&
778 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
781 /* Copy result into array. The talloc system will take
782 care of freeing the temporary arrays later on. */
784 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
787 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
790 total_names += tmp_num_names;
793 *num_names = total_names;
802 static int get_ldap_seq(const char *server, int port, uint32 *seq)
806 const char *attrs[] = {"highestCommittedUSN", NULL};
807 LDAPMessage *res = NULL;
808 char **values = NULL;
811 *seq = DOM_SEQUENCE_NONE;
814 * Parameterised (5) second timeout on open. This is needed as the
815 * search timeout doesn't seem to apply to doing an open as well. JRA.
818 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
822 /* Timeout if no response within 20 seconds. */
826 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
827 CONST_DISCARD(char **, attrs), 0, &to, &res))
830 if (ldap_count_entries(ldp, res) != 1)
833 values = ldap_get_values(ldp, res, "highestCommittedUSN");
834 if (!values || !values[0])
837 *seq = atoi(values[0]);
843 ldap_value_free(values);
851 /**********************************************************************
852 Get the sequence number for a Windows AD native mode domain using
854 **********************************************************************/
856 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
861 fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr));
862 if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) {
863 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
864 "number for Domain (%s) from DC (%s)\n",
865 domain->name, ipstr));
870 #endif /* HAVE_LDAP */
872 /* find the sequence number for a domain */
873 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
879 BOOL got_seq_num = False;
880 struct rpc_pipe_client *cli;
882 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
884 if ( !winbindd_can_contact_domain( domain ) ) {
885 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
891 *seq = DOM_SEQUENCE_NONE;
893 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
894 return NT_STATUS_NO_MEMORY;
897 if ( domain->active_directory )
901 DEBUG(8,("using get_ldap_seq() to retrieve the "
902 "sequence number\n"));
904 res = get_ldap_sequence_number( domain, seq );
907 result = NT_STATUS_OK;
908 DEBUG(10,("domain_sequence_number: LDAP for "
910 domain->name, *seq));
914 DEBUG(10,("domain_sequence_number: failed to get LDAP "
915 "sequence number for domain %s\n",
918 #endif /* HAVE_LDAP */
920 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
921 if (!NT_STATUS_IS_OK(result)) {
925 /* Query domain info */
927 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
929 if (NT_STATUS_IS_OK(result)) {
930 *seq = ctr.info.inf8.seq_num;
935 /* retry with info-level 2 in case the dc does not support info-level 8
936 * (like all older samba2 and samba3 dc's - Guenther */
938 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
940 if (NT_STATUS_IS_OK(result)) {
941 *seq = ctr.info.inf2.seq_num;
947 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
948 domain->name, (unsigned)*seq));
950 DEBUG(10,("domain_sequence_number: failed to get sequence "
951 "number (%u) for domain %s\n",
952 (unsigned)*seq, domain->name ));
957 talloc_destroy(mem_ctx);
962 /* get a list of trusted domains */
963 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
970 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
972 struct rpc_pipe_client *cli;
973 POLICY_HND lsa_policy;
975 DEBUG(3,("rpc: trusted_domains\n"));
982 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
983 if (!NT_STATUS_IS_OK(result))
986 result = STATUS_MORE_ENTRIES;
988 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
989 uint32 start_idx, num;
994 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
995 &lsa_policy, &enum_ctx,
999 if (!NT_STATUS_IS_OK(result) &&
1000 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1003 start_idx = *num_domains;
1004 *num_domains += num;
1005 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
1006 char *, *num_domains);
1007 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
1008 DOM_SID, *num_domains);
1009 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
1010 char *, *num_domains);
1011 if ((*names == NULL) || (*dom_sids == NULL) ||
1012 (*alt_names == NULL))
1013 return NT_STATUS_NO_MEMORY;
1015 for (i=0; i<num; i++) {
1016 (*names)[start_idx+i] = tmp_names[i];
1017 (*dom_sids)[start_idx+i] = tmp_sids[i];
1018 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
1024 /* find the lockout policy for a domain */
1025 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1026 TALLOC_CTX *mem_ctx,
1027 SAM_UNK_INFO_12 *lockout_policy)
1030 struct rpc_pipe_client *cli;
1034 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1036 if ( !winbindd_can_contact_domain( domain ) ) {
1037 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1039 return NT_STATUS_NOT_SUPPORTED;
1042 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1043 if (!NT_STATUS_IS_OK(result)) {
1047 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
1048 if (!NT_STATUS_IS_OK(result)) {
1052 *lockout_policy = ctr.info.inf12;
1054 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
1055 ctr.info.inf12.bad_attempt_lockout));
1062 /* find the password policy for a domain */
1063 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1064 TALLOC_CTX *mem_ctx,
1065 SAM_UNK_INFO_1 *password_policy)
1068 struct rpc_pipe_client *cli;
1072 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1074 if ( !winbindd_can_contact_domain( domain ) ) {
1075 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1077 return NT_STATUS_NOT_SUPPORTED;
1080 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1081 if (!NT_STATUS_IS_OK(result)) {
1085 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
1086 if (!NT_STATUS_IS_OK(result)) {
1090 *password_policy = ctr.info.inf1;
1092 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1093 ctr.info.inf1.min_length_password));
1101 /* the rpc backend methods are exposed via this structure */
1102 struct winbindd_methods msrpc_methods = {
1109 msrpc_rids_to_names,
1112 msrpc_lookup_useraliases,
1115 msrpc_lockout_policy,
1116 msrpc_password_policy,