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.
27 #define DBGC_CLASS DBGC_WINBIND
30 /* Query display info for a domain. This returns enough information plus a
31 bit extra to give an overview of domain users for the User Manager
33 static NTSTATUS query_user_list(struct winbindd_domain *domain,
36 WINBIND_USERINFO **info)
39 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
41 BOOL got_dom_pol = False;
42 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
43 unsigned int i, start_idx, retry;
45 DEBUG(3,("rpc: query_user_list\n"));
54 if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
57 /* Get domain handle */
59 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
60 des_access, &domain->sid, &dom_pol);
62 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
64 if (!NT_STATUS_IS_OK(result))
73 uint32 num_dom_users, *dom_rids, j, size = 0xffff;
74 uint16 acb_mask = ACB_NORMAL;
76 if (!(ctx2 = talloc_init("winbindd enum_users"))) {
77 result = NT_STATUS_NO_MEMORY;
81 result = cli_samr_enum_dom_users(
82 hnd->cli, ctx2, &dom_pol, &start_idx, acb_mask,
83 size, &dom_users, &dom_rids, &num_dom_users);
85 *num_entries += num_dom_users;
87 *info = talloc_realloc(
89 (*num_entries) * sizeof(WINBIND_USERINFO));
92 result = NT_STATUS_NO_MEMORY;
97 for (j = 0; j < num_dom_users; i++, j++) {
98 (*info)[i].acct_name =
99 talloc_strdup(mem_ctx, dom_users[j]);
100 (*info)[i].full_name = talloc_strdup(mem_ctx, "");
101 (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, dom_rids[j]);
102 /* For the moment we set the primary group for
103 every user to be the Domain Users group.
104 There are serious problems with determining
105 the actual primary group for large domains.
106 This should really be made into a 'winbind
107 force group' smb.conf parameter or
108 something like that. */
110 = rid_to_talloced_sid(domain,
112 DOMAIN_GROUP_RID_USERS);
115 talloc_destroy(ctx2);
117 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
122 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
127 /* list all domain groups */
128 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
131 struct acct_info **info)
133 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
144 DEBUG(3,("rpc: enum_dom_groups\n"));
148 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
151 status = cli_samr_open_domain(hnd->cli, mem_ctx,
152 &hnd->pol, des_access, &domain->sid, &dom_pol);
153 } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
155 if (!NT_STATUS_IS_OK(status))
159 struct acct_info *info2 = NULL;
161 TALLOC_CTX *mem_ctx2;
163 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
165 /* start is updated by this call. */
166 status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx2, &dom_pol,
168 0xFFFF, /* buffer size? */
171 if (!NT_STATUS_IS_OK(status) &&
172 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
173 talloc_destroy(mem_ctx2);
177 (*info) = talloc_realloc(mem_ctx, *info,
178 sizeof(**info) * ((*num_entries) + count));
180 talloc_destroy(mem_ctx2);
181 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
182 return NT_STATUS_NO_MEMORY;
185 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
186 (*num_entries) += count;
187 talloc_destroy(mem_ctx2);
188 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
190 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
195 /* List all domain groups */
197 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
200 struct acct_info **info)
202 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
213 if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
216 result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
217 des_access, &domain->sid, &dom_pol);
218 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
220 if ( !NT_STATUS_IS_OK(result))
224 struct acct_info *info2 = NULL;
225 uint32 count = 0, start = *num_entries;
226 TALLOC_CTX *mem_ctx2;
228 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
230 result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
231 &start, 0xFFFF, &info2, &count);
233 if ( !NT_STATUS_IS_OK(result)
234 && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
236 talloc_destroy(mem_ctx2);
240 (*info) = talloc_realloc(mem_ctx, *info,
241 sizeof(**info) * ((*num_entries) + count));
243 talloc_destroy(mem_ctx2);
244 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
245 return NT_STATUS_NO_MEMORY;
248 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
249 (*num_entries) += count;
250 talloc_destroy(mem_ctx2);
251 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
253 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
258 /* convert a single name to a sid in a domain */
259 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
263 enum SID_NAME_USE *type)
267 DOM_SID *sids = NULL;
268 uint32 *types = NULL;
269 const char *full_name;
272 DEBUG(3,("rpc: name_to_sid name=%s\n", name));
274 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
277 DEBUG(0, ("talloc_asprintf failed!\n"));
278 return NT_STATUS_NO_MEMORY;
281 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name, domain->name ));
285 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) {
289 result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
290 &full_name, &sids, &types);
291 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
292 hnd && hnd->cli && hnd->cli->fd == -1);
294 /* Return rid and type if lookup successful */
296 if (NT_STATUS_IS_OK(result)) {
297 sid_copy(sid, &sids[0]);
305 convert a domain SID to a user or group name
307 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
311 enum SID_NAME_USE *type)
320 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
325 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
328 result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
329 1, sid, &domains, &names, &types);
330 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
331 hnd && hnd->cli && hnd->cli->fd == -1);
333 if (NT_STATUS_IS_OK(result)) {
336 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
339 if (strcasecmp(domain->name, domains[0]) != 0) {
340 DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
341 return NT_STATUS_UNSUCCESSFUL;
348 /* Lookup user information from a rid or username. */
349 static NTSTATUS query_user(struct winbindd_domain *domain,
352 WINBIND_USERINFO *user_info)
354 CLI_POLICY_HND *hnd = NULL;
355 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
356 POLICY_HND dom_pol, user_pol;
357 BOOL got_dom_pol = False, got_user_pol = False;
358 SAM_USERINFO_CTR *ctr;
362 NET_USER_INFO_3 *user;
364 DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string, user_sid)));
365 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
369 /* try netsamlogon cache first */
371 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
374 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
375 sid_string_static(user_sid)));
377 user_info->user_sid = rid_to_talloced_sid( domain, mem_ctx, user_rid );
378 user_info->group_sid = rid_to_talloced_sid( domain, mem_ctx, user->group_rid );
380 user_info->acct_name = unistr2_tdup(mem_ctx, &user->uni_user_name);
381 user_info->full_name = unistr2_tdup(mem_ctx, &user->uni_full_name);
388 /* no cache; hit the wire */
392 /* Get sam handle; if we fail here there is no hope */
394 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
397 /* Get domain handle */
399 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
400 SEC_RIGHTS_MAXIMUM_ALLOWED,
401 &domain->sid, &dom_pol);
402 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
403 hnd && hnd->cli && hnd->cli->fd == -1);
405 if (!NT_STATUS_IS_OK(result))
410 /* Get user handle */
411 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
412 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
414 if (!NT_STATUS_IS_OK(result))
420 result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol,
423 if (!NT_STATUS_IS_OK(result))
426 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
427 got_user_pol = False;
429 user_info->user_sid = rid_to_talloced_sid(domain, mem_ctx, user_rid);
430 user_info->group_sid = rid_to_talloced_sid(domain, mem_ctx, ctr->info.id21->group_rid);
431 user_info->acct_name = unistr2_tdup(mem_ctx,
432 &ctr->info.id21->uni_user_name);
433 user_info->full_name = unistr2_tdup(mem_ctx,
434 &ctr->info.id21->uni_full_name);
437 /* Clean up policy handles */
439 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
442 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
447 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
448 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
451 uint32 *num_groups, DOM_SID ***user_grpsids)
454 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
455 POLICY_HND dom_pol, user_pol;
456 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
457 BOOL got_dom_pol = False, got_user_pol = False;
458 DOM_GID *user_groups;
463 NET_USER_INFO_3 *user;
465 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string, user_sid)));
468 *user_grpsids = NULL;
470 /* so lets see if we have a cached user_info_3 */
472 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
474 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
475 sid_string_static(user_sid)));
477 *num_groups = user->num_groups;
479 (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
480 for (i=0;i<(*num_groups);i++) {
481 (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user->gids[i].g_rid);
489 /* no cache; hit the wire */
493 /* Get sam handle; if we fail here there is no hope */
495 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
498 /* Get domain handle */
500 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
501 des_access, &domain->sid, &dom_pol);
502 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
503 hnd && hnd->cli && hnd->cli->fd == -1);
505 if (!NT_STATUS_IS_OK(result))
511 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
515 /* Get user handle */
516 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
517 des_access, user_rid, &user_pol);
519 if (!NT_STATUS_IS_OK(result))
524 /* Query user rids */
525 result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol,
526 num_groups, &user_groups);
528 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
531 (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
532 if (!(*user_grpsids)) {
533 result = NT_STATUS_NO_MEMORY;
537 for (i=0;i<(*num_groups);i++) {
538 (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
542 /* Clean up policy handles */
544 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
547 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
553 /* Lookup group membership given a rid. */
554 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
556 DOM_SID *group_sid, uint32 *num_names,
557 DOM_SID ***sid_mem, char ***names,
560 CLI_POLICY_HND *hnd = NULL;
561 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
562 uint32 i, total_names = 0;
563 POLICY_HND dom_pol, group_pol;
564 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
565 BOOL got_dom_pol = False, got_group_pol = False;
566 uint32 *rid_mem = NULL;
572 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, sid_to_string(sid_string, group_sid)));
574 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
583 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
586 /* Get domain handle */
588 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
589 des_access, &domain->sid, &dom_pol);
590 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
592 if (!NT_STATUS_IS_OK(result))
597 /* Get group handle */
599 result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
600 des_access, group_rid, &group_pol);
602 if (!NT_STATUS_IS_OK(result))
605 got_group_pol = True;
607 /* Step #1: Get a list of user rids that are the members of the
610 result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
611 &group_pol, num_names, &rid_mem,
614 if (!NT_STATUS_IS_OK(result))
617 /* Step #2: Convert list of rids into list of usernames. Do this
618 in bunches of ~1000 to avoid crashing NT4. It looks like there
619 is a buffer overflow or something like that lurking around
622 #define MAX_LOOKUP_RIDS 900
624 *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
625 *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
626 *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));
628 for (j=0;j<(*num_names);j++) {
629 (*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
632 if (*num_names>0 && (!*names || !*name_types)) {
633 result = NT_STATUS_NO_MEMORY;
637 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
638 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
639 uint32 tmp_num_names = 0;
640 char **tmp_names = NULL;
641 uint32 *tmp_types = NULL;
643 /* Lookup a chunk of rids */
645 result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
646 &dom_pol, 1000, /* flags */
650 &tmp_names, &tmp_types);
652 /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
653 the one returned from 2k) */
655 if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
658 /* Copy result into array. The talloc system will take
659 care of freeing the temporary arrays later on. */
661 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
664 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
667 total_names += tmp_num_names;
670 *num_names = total_names;
672 result = NT_STATUS_OK;
676 cli_samr_close(hnd->cli, mem_ctx, &group_pol);
679 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
688 static SIG_ATOMIC_T gotalarm;
690 /***************************************************************
691 Signal function to tell us we timed out.
692 ****************************************************************/
694 static void gotalarm_sig(void)
699 static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
705 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
707 /* End setup timeout. */
709 ldp = ldap_open(server, port);
711 /* Teardown timeout. */
712 CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
718 static int get_ldap_seq(const char *server, int port, uint32 *seq)
722 char *attrs[] = {"highestCommittedUSN", NULL};
723 LDAPMessage *res = NULL;
724 char **values = NULL;
727 *seq = DOM_SEQUENCE_NONE;
730 * 10 second timeout on open. This is needed as the search timeout
731 * doesn't seem to apply to doing an open as well. JRA.
734 if ((ldp = ldap_open_with_timeout(server, port, 10)) == NULL)
737 /* Timeout if no response within 20 seconds. */
741 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
744 if (ldap_count_entries(ldp, res) != 1)
747 values = ldap_get_values(ldp, res, "highestCommittedUSN");
748 if (!values || !values[0])
751 *seq = atoi(values[0]);
757 ldap_value_free(values);
765 /**********************************************************************
766 Get the sequence number for a Windows AD native mode domain using
768 **********************************************************************/
770 int get_ldap_sequence_number( const char* domain, uint32 *seq)
773 int i, port = LDAP_PORT;
774 struct ip_service *ip_list = NULL;
777 if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
778 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
782 /* Finally return first DC that we can contact */
784 for (i = 0; i < count; i++) {
787 /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
788 port = (ip_list[i].port!= PORT_NONE) ? ip_list[i].port : LDAP_PORT;
790 fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
792 if (is_zero_ip(ip_list[i].ip))
795 if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
798 /* add to failed connection cache */
799 add_failed_connection_entry( domain, ipstr, NT_STATUS_UNSUCCESSFUL );
804 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
805 domain, inet_ntoa(ip_list[i].ip), port));
813 #endif /* HAVE_LDAP */
815 /* find the sequence number for a domain */
816 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
821 uint16 switch_value = 2;
824 BOOL got_dom_pol = False;
825 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
828 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
830 *seq = DOM_SEQUENCE_NONE;
832 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
833 return NT_STATUS_NO_MEMORY;
838 if ( domain->native_mode )
840 DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
842 if ( get_ldap_sequence_number( domain->name, seq ) == 0 ) {
843 result = NT_STATUS_OK;
844 DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
845 domain->name, *seq));
849 DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
852 #endif /* HAVE_LDAP */
854 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
857 /* Get domain handle */
858 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
859 des_access, &domain->sid, &dom_pol);
860 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
862 if (!NT_STATUS_IS_OK(result))
867 /* Query domain info */
869 result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
872 if (NT_STATUS_IS_OK(result)) {
873 *seq = ctr.info.inf2.seq_num;
874 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
876 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
877 (unsigned)*seq, domain->name ));
883 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
885 talloc_destroy(mem_ctx);
890 /* get a list of trusted domains */
891 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
899 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
903 DEBUG(3,("rpc: trusted_domains\n"));
910 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd)))
913 result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
914 &hnd->pol, &enum_ctx,
915 num_domains, names, dom_sids);
916 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
922 /* find the domain sid for a domain */
923 static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
925 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
931 DEBUG(3,("rpc: domain_sid\n"));
933 if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
934 return NT_STATUS_NO_MEMORY;
939 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
942 result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
943 &hnd->pol, 0x05, level5_dom, sid);
944 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
947 talloc_destroy(mem_ctx);
951 /* find alternate names list for the domain - none for rpc */
952 static NTSTATUS alternate_name(struct winbindd_domain *domain)
958 /* the rpc backend methods are exposed via this structure */
959 struct winbindd_methods msrpc_methods = {