2 Unix SMB/CIFS implementation.
4 Winbind rpc backend functions
6 Copyright (C) Tim Potter 2000-2001,2003
7 Copyright (C) Andrew Tridgell 2001
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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)
40 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
42 BOOL got_dom_pol = False;
43 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
44 unsigned int i, start_idx, retry;
46 DEBUG(3,("rpc: query_user_list\n"));
55 if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
58 /* Get domain handle */
60 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
61 des_access, &domain->sid, &dom_pol);
63 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
65 if (!NT_STATUS_IS_OK(result))
74 uint32 num_dom_users, *dom_rids, j, size = 0xffff;
75 uint16 acb_mask = ACB_NORMAL;
77 if (!(ctx2 = talloc_init("winbindd enum_users"))) {
78 result = NT_STATUS_NO_MEMORY;
82 result = cli_samr_enum_dom_users(
83 hnd->cli, ctx2, &dom_pol, &start_idx, acb_mask,
84 size, &dom_users, &dom_rids, &num_dom_users);
86 *num_entries += num_dom_users;
88 *info = talloc_realloc(
90 (*num_entries) * sizeof(WINBIND_USERINFO));
93 result = NT_STATUS_NO_MEMORY;
98 for (j = 0; j < num_dom_users; i++, j++) {
99 (*info)[i].acct_name =
100 talloc_strdup(mem_ctx, dom_users[j]);
101 (*info)[i].full_name = talloc_strdup(mem_ctx, "");
102 (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, dom_rids[j]);
103 /* For the moment we set the primary group for
104 every user to be the Domain Users group.
105 There are serious problems with determining
106 the actual primary group for large domains.
107 This should really be made into a 'winbind
108 force group' smb.conf parameter or
109 something like that. */
111 = rid_to_talloced_sid(domain,
113 DOMAIN_GROUP_RID_USERS);
116 talloc_destroy(ctx2);
118 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
123 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
128 /* list all domain groups */
129 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
132 struct acct_info **info)
134 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
145 DEBUG(3,("rpc: enum_dom_groups\n"));
149 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
152 status = cli_samr_open_domain(hnd->cli, mem_ctx,
153 &hnd->pol, des_access, &domain->sid, &dom_pol);
154 } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
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 = cli_samr_enum_dom_groups(hnd->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(mem_ctx, *info,
179 sizeof(**info) * ((*num_entries) + count));
181 talloc_destroy(mem_ctx2);
182 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
183 return NT_STATUS_NO_MEMORY;
186 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
187 (*num_entries) += count;
188 talloc_destroy(mem_ctx2);
189 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
191 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
196 /* List all domain groups */
198 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
201 struct acct_info **info)
203 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
214 if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
217 result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
218 des_access, &domain->sid, &dom_pol);
219 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
221 if ( !NT_STATUS_IS_OK(result))
225 struct acct_info *info2 = NULL;
226 uint32 count = 0, start = *num_entries;
227 TALLOC_CTX *mem_ctx2;
229 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
231 result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
232 &start, 0xFFFF, &info2, &count);
234 if ( !NT_STATUS_IS_OK(result)
235 && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
237 talloc_destroy(mem_ctx2);
241 (*info) = talloc_realloc(mem_ctx, *info,
242 sizeof(**info) * ((*num_entries) + count));
244 talloc_destroy(mem_ctx2);
245 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
246 return NT_STATUS_NO_MEMORY;
249 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
250 (*num_entries) += count;
251 talloc_destroy(mem_ctx2);
252 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
254 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
259 /* convert a single name to a sid in a domain */
260 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
264 enum SID_NAME_USE *type)
268 DOM_SID *sids = NULL;
269 uint32 *types = NULL;
270 const char *full_name;
273 DEBUG(3,("rpc: name_to_sid name=%s\n", name));
275 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
278 DEBUG(0, ("talloc_asprintf failed!\n"));
279 return NT_STATUS_NO_MEMORY;
282 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name, domain->name ));
286 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) {
290 result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
291 &full_name, &sids, &types);
292 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
293 hnd && hnd->cli && hnd->cli->fd == -1);
295 /* Return rid and type if lookup successful */
297 if (NT_STATUS_IS_OK(result)) {
298 sid_copy(sid, &sids[0]);
299 *type = (enum SID_NAME_USE)types[0];
306 convert a domain SID to a user or group name
308 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
312 enum SID_NAME_USE *type)
321 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
326 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
329 result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
330 1, sid, &domains, &names, &types);
331 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
332 hnd && hnd->cli && hnd->cli->fd == -1);
334 if (NT_STATUS_IS_OK(result)) {
335 *type = (enum SID_NAME_USE)types[0];
337 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
340 if (!strequal(domain->name, domains[0])) {
341 DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
342 return NT_STATUS_UNSUCCESSFUL;
349 /* Lookup user information from a rid or username. */
350 static NTSTATUS query_user(struct winbindd_domain *domain,
353 WINBIND_USERINFO *user_info)
355 CLI_POLICY_HND *hnd = NULL;
356 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
357 POLICY_HND dom_pol, user_pol;
358 BOOL got_dom_pol = False, got_user_pol = False;
359 SAM_USERINFO_CTR *ctr;
363 NET_USER_INFO_3 *user;
365 DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string, user_sid)));
366 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
370 /* try netsamlogon cache first */
372 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
375 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
376 sid_string_static(user_sid)));
378 user_info->user_sid = rid_to_talloced_sid( domain, mem_ctx, user_rid );
379 user_info->group_sid = rid_to_talloced_sid( domain, mem_ctx, user->group_rid );
381 user_info->acct_name = unistr2_tdup(mem_ctx, &user->uni_user_name);
382 user_info->full_name = unistr2_tdup(mem_ctx, &user->uni_full_name);
389 /* no cache; hit the wire */
393 /* Get sam handle; if we fail here there is no hope */
395 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
398 /* Get domain handle */
400 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
401 SEC_RIGHTS_MAXIMUM_ALLOWED,
402 &domain->sid, &dom_pol);
403 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
404 hnd && hnd->cli && hnd->cli->fd == -1);
406 if (!NT_STATUS_IS_OK(result))
411 /* Get user handle */
412 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
413 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
415 if (!NT_STATUS_IS_OK(result))
421 result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol,
424 if (!NT_STATUS_IS_OK(result))
427 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
428 got_user_pol = False;
430 user_info->user_sid = rid_to_talloced_sid(domain, mem_ctx, user_rid);
431 user_info->group_sid = rid_to_talloced_sid(domain, mem_ctx, ctr->info.id21->group_rid);
432 user_info->acct_name = unistr2_tdup(mem_ctx,
433 &ctr->info.id21->uni_user_name);
434 user_info->full_name = unistr2_tdup(mem_ctx,
435 &ctr->info.id21->uni_full_name);
438 /* Clean up policy handles */
440 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
443 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
448 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
449 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
452 uint32 *num_groups, DOM_SID ***user_grpsids)
455 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
456 POLICY_HND dom_pol, user_pol;
457 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
458 BOOL got_dom_pol = False, got_user_pol = False;
459 DOM_GID *user_groups;
464 NET_USER_INFO_3 *user;
466 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string, user_sid)));
469 *user_grpsids = NULL;
471 /* so lets see if we have a cached user_info_3 */
473 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
475 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
476 sid_string_static(user_sid)));
478 *num_groups = user->num_groups;
480 (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
481 for (i=0;i<(*num_groups);i++) {
482 (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user->gids[i].g_rid);
490 /* no cache; hit the wire */
494 /* Get sam handle; if we fail here there is no hope */
496 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
499 /* Get domain handle */
501 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
502 des_access, &domain->sid, &dom_pol);
503 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
504 hnd && hnd->cli && hnd->cli->fd == -1);
506 if (!NT_STATUS_IS_OK(result))
512 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
516 /* Get user handle */
517 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
518 des_access, user_rid, &user_pol);
520 if (!NT_STATUS_IS_OK(result))
525 /* Query user rids */
526 result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol,
527 num_groups, &user_groups);
529 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
532 (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
533 if (!(*user_grpsids)) {
534 result = NT_STATUS_NO_MEMORY;
538 for (i=0;i<(*num_groups);i++) {
539 (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
543 /* Clean up policy handles */
545 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
548 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
554 /* Lookup group membership given a rid. */
555 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
557 DOM_SID *group_sid, uint32 *num_names,
558 DOM_SID ***sid_mem, char ***names,
561 CLI_POLICY_HND *hnd = NULL;
562 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
563 uint32 i, total_names = 0;
564 POLICY_HND dom_pol, group_pol;
565 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
566 BOOL got_dom_pol = False, got_group_pol = False;
567 uint32 *rid_mem = NULL;
573 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, sid_to_string(sid_string, group_sid)));
575 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
584 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
587 /* Get domain handle */
589 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
590 des_access, &domain->sid, &dom_pol);
591 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
593 if (!NT_STATUS_IS_OK(result))
598 /* Get group handle */
600 result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
601 des_access, group_rid, &group_pol);
603 if (!NT_STATUS_IS_OK(result))
606 got_group_pol = True;
608 /* Step #1: Get a list of user rids that are the members of the
611 result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
612 &group_pol, num_names, &rid_mem,
615 if (!NT_STATUS_IS_OK(result))
618 /* Step #2: Convert list of rids into list of usernames. Do this
619 in bunches of ~1000 to avoid crashing NT4. It looks like there
620 is a buffer overflow or something like that lurking around
623 #define MAX_LOOKUP_RIDS 900
625 *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
626 *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
627 *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));
629 for (j=0;j<(*num_names);j++) {
630 (*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
633 if (*num_names>0 && (!*names || !*name_types)) {
634 result = NT_STATUS_NO_MEMORY;
638 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
639 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
640 uint32 tmp_num_names = 0;
641 char **tmp_names = NULL;
642 uint32 *tmp_types = NULL;
644 /* Lookup a chunk of rids */
646 result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
647 &dom_pol, 1000, /* flags */
651 &tmp_names, &tmp_types);
653 /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
654 the one returned from 2k) */
656 if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
659 /* Copy result into array. The talloc system will take
660 care of freeing the temporary arrays later on. */
662 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
665 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
668 total_names += tmp_num_names;
671 *num_names = total_names;
673 result = NT_STATUS_OK;
677 cli_samr_close(hnd->cli, mem_ctx, &group_pol);
680 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
689 static SIG_ATOMIC_T gotalarm;
691 /***************************************************************
692 Signal function to tell us we timed out.
693 ****************************************************************/
695 static void gotalarm_sig(void)
700 static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
706 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
708 /* End setup timeout. */
710 ldp = ldap_open(server, port);
712 /* Teardown timeout. */
713 CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
719 static int get_ldap_seq(const char *server, int port, uint32 *seq)
723 char *attrs[] = {"highestCommittedUSN", NULL};
724 LDAPMessage *res = NULL;
725 char **values = NULL;
728 *seq = DOM_SEQUENCE_NONE;
731 * 10 second timeout on open. This is needed as the search timeout
732 * doesn't seem to apply to doing an open as well. JRA.
735 if ((ldp = ldap_open_with_timeout(server, port, 10)) == NULL)
738 /* Timeout if no response within 20 seconds. */
742 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
745 if (ldap_count_entries(ldp, res) != 1)
748 values = ldap_get_values(ldp, res, "highestCommittedUSN");
749 if (!values || !values[0])
752 *seq = atoi(values[0]);
758 ldap_value_free(values);
766 /**********************************************************************
767 Get the sequence number for a Windows AD native mode domain using
769 **********************************************************************/
771 int get_ldap_sequence_number( const char* domain, uint32 *seq)
774 int i, port = LDAP_PORT;
775 struct ip_service *ip_list = NULL;
778 if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
779 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
783 /* Finally return first DC that we can contact */
785 for (i = 0; i < count; i++) {
788 /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
789 port = (ip_list[i].port!= PORT_NONE) ? ip_list[i].port : LDAP_PORT;
791 fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
793 if (is_zero_ip(ip_list[i].ip))
796 if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
799 /* add to failed connection cache */
800 add_failed_connection_entry( domain, ipstr, NT_STATUS_UNSUCCESSFUL );
805 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
806 domain, inet_ntoa(ip_list[i].ip), port));
814 #endif /* HAVE_LDAP */
816 /* find the sequence number for a domain */
817 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
822 uint16 switch_value = 2;
825 BOOL got_dom_pol = False;
826 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
829 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
831 *seq = DOM_SEQUENCE_NONE;
833 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
834 return NT_STATUS_NO_MEMORY;
839 if ( domain->native_mode )
841 DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
843 if ( get_ldap_sequence_number( domain->name, seq ) == 0 ) {
844 result = NT_STATUS_OK;
845 DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
846 domain->name, *seq));
850 DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
853 #endif /* HAVE_LDAP */
855 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
858 /* Get domain handle */
859 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
860 des_access, &domain->sid, &dom_pol);
861 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
863 if (!NT_STATUS_IS_OK(result))
868 /* Query domain info */
870 result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
873 if (NT_STATUS_IS_OK(result)) {
874 *seq = ctr.info.inf2.seq_num;
875 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
877 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
878 (unsigned)*seq, domain->name ));
884 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
886 talloc_destroy(mem_ctx);
891 /* get a list of trusted domains */
892 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
900 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
904 DEBUG(3,("rpc: trusted_domains\n"));
911 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd)))
914 result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
915 &hnd->pol, &enum_ctx,
916 num_domains, names, dom_sids);
917 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
923 /* find the domain sid for a domain */
924 static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
926 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
932 DEBUG(3,("rpc: domain_sid\n"));
934 if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
935 return NT_STATUS_NO_MEMORY;
940 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
943 result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
944 &hnd->pol, 0x05, level5_dom, sid);
945 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
948 talloc_destroy(mem_ctx);
952 /* find alternate names list for the domain - none for rpc */
953 static NTSTATUS alternate_name(struct winbindd_domain *domain)
959 /* the rpc backend methods are exposed via this structure */
960 struct winbindd_methods msrpc_methods = {