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;
47 DEBUG(3,("rpc: query_user_list\n"));
56 if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) )
59 /* Get domain handle */
61 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
62 des_access, &domain->sid, &dom_pol);
64 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
66 if (!NT_STATUS_IS_OK(result))
76 uint32 num_dom_users, j;
77 uint32 max_entries, max_size;
83 ctr.sam.info1 = &info1;
85 if (!(ctx2 = talloc_init("winbindd enum_users"))) {
86 result = NT_STATUS_NO_MEMORY;
90 /* this next bit is copied from net_user_list_internal() */
92 get_query_dispinfo_params( loop_count, &max_entries, &max_size );
94 result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, &dom_pol,
95 &start_idx, 1, &num_dom_users, max_entries, max_size, &ctr);
99 *num_entries += num_dom_users;
101 *info = talloc_realloc( mem_ctx, *info,
102 (*num_entries) * sizeof(WINBIND_USERINFO));
105 result = NT_STATUS_NO_MEMORY;
106 talloc_destroy(ctx2);
110 for (j = 0; j < num_dom_users; i++, j++) {
111 fstring username, fullname;
112 uint32 rid = ctr.sam.info1->sam[j].rid_user;
114 unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1);
115 unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
117 (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
118 (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
119 (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, rid );
121 /* For the moment we set the primary group for
122 every user to be the Domain Users group.
123 There are serious problems with determining
124 the actual primary group for large domains.
125 This should really be made into a 'winbind
126 force group' smb.conf parameter or
127 something like that. */
129 (*info)[i].group_sid = rid_to_talloced_sid(domain,
130 mem_ctx, DOMAIN_GROUP_RID_USERS);
133 talloc_destroy(ctx2);
135 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
140 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
145 /* list all domain groups */
146 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
149 struct acct_info **info)
151 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
162 DEBUG(3,("rpc: enum_dom_groups\n"));
166 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
169 status = cli_samr_open_domain(hnd->cli, mem_ctx,
170 &hnd->pol, des_access, &domain->sid, &dom_pol);
171 } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
173 if (!NT_STATUS_IS_OK(status))
177 struct acct_info *info2 = NULL;
179 TALLOC_CTX *mem_ctx2;
181 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
183 /* start is updated by this call. */
184 status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx2, &dom_pol,
186 0xFFFF, /* buffer size? */
189 if (!NT_STATUS_IS_OK(status) &&
190 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
191 talloc_destroy(mem_ctx2);
195 (*info) = talloc_realloc(mem_ctx, *info,
196 sizeof(**info) * ((*num_entries) + count));
198 talloc_destroy(mem_ctx2);
199 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
200 return NT_STATUS_NO_MEMORY;
203 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
204 (*num_entries) += count;
205 talloc_destroy(mem_ctx2);
206 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
208 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
213 /* List all domain groups */
215 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
218 struct acct_info **info)
220 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
231 if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)) )
234 result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
235 des_access, &domain->sid, &dom_pol);
236 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
238 if ( !NT_STATUS_IS_OK(result))
242 struct acct_info *info2 = NULL;
243 uint32 count = 0, start = *num_entries;
244 TALLOC_CTX *mem_ctx2;
246 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
248 result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
249 &start, 0xFFFF, &info2, &count);
251 if ( !NT_STATUS_IS_OK(result)
252 && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
254 talloc_destroy(mem_ctx2);
258 (*info) = talloc_realloc(mem_ctx, *info,
259 sizeof(**info) * ((*num_entries) + count));
261 talloc_destroy(mem_ctx2);
262 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
263 return NT_STATUS_NO_MEMORY;
266 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
267 (*num_entries) += count;
268 talloc_destroy(mem_ctx2);
269 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
271 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
276 /* convert a single name to a sid in a domain */
277 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
281 enum SID_NAME_USE *type)
285 DOM_SID *sids = NULL;
286 uint32 *types = NULL;
287 const char *full_name;
290 DEBUG(3,("rpc: name_to_sid name=%s\n", name));
292 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
295 DEBUG(0, ("talloc_asprintf failed!\n"));
296 return NT_STATUS_NO_MEMORY;
299 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name, domain->name ));
303 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd))) {
307 result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
308 &full_name, &sids, &types);
309 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
310 hnd && hnd->cli && hnd->cli->fd == -1);
312 /* Return rid and type if lookup successful */
314 if (NT_STATUS_IS_OK(result)) {
315 sid_copy(sid, &sids[0]);
316 *type = (enum SID_NAME_USE)types[0];
323 convert a domain SID to a user or group name
325 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
329 enum SID_NAME_USE *type)
338 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
343 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd)))
346 result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
347 1, sid, &domains, &names, &types);
348 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
349 hnd && hnd->cli && hnd->cli->fd == -1);
351 if (NT_STATUS_IS_OK(result)) {
352 *type = (enum SID_NAME_USE)types[0];
354 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
357 if (!strequal(domain->name, domains[0])) {
358 DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
359 return NT_STATUS_UNSUCCESSFUL;
366 /* Lookup user information from a rid or username. */
367 static NTSTATUS query_user(struct winbindd_domain *domain,
370 WINBIND_USERINFO *user_info)
372 CLI_POLICY_HND *hnd = NULL;
373 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
374 POLICY_HND dom_pol, user_pol;
375 BOOL got_dom_pol = False, got_user_pol = False;
376 SAM_USERINFO_CTR *ctr;
380 NET_USER_INFO_3 *user;
382 DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string, user_sid)));
383 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
387 /* try netsamlogon cache first */
389 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
392 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
393 sid_string_static(user_sid)));
395 user_info->user_sid = rid_to_talloced_sid( domain, mem_ctx, user_rid );
396 user_info->group_sid = rid_to_talloced_sid( domain, mem_ctx, user->group_rid );
398 user_info->acct_name = unistr2_tdup(mem_ctx, &user->uni_user_name);
399 user_info->full_name = unistr2_tdup(mem_ctx, &user->uni_full_name);
406 /* no cache; hit the wire */
410 /* Get sam handle; if we fail here there is no hope */
412 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
415 /* Get domain handle */
417 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
418 SEC_RIGHTS_MAXIMUM_ALLOWED,
419 &domain->sid, &dom_pol);
420 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
421 hnd && hnd->cli && hnd->cli->fd == -1);
423 if (!NT_STATUS_IS_OK(result))
428 /* Get user handle */
429 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
430 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
432 if (!NT_STATUS_IS_OK(result))
438 result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol,
441 if (!NT_STATUS_IS_OK(result))
444 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
445 got_user_pol = False;
447 user_info->user_sid = rid_to_talloced_sid(domain, mem_ctx, user_rid);
448 user_info->group_sid = rid_to_talloced_sid(domain, mem_ctx, ctr->info.id21->group_rid);
449 user_info->acct_name = unistr2_tdup(mem_ctx,
450 &ctr->info.id21->uni_user_name);
451 user_info->full_name = unistr2_tdup(mem_ctx,
452 &ctr->info.id21->uni_full_name);
455 /* Clean up policy handles */
457 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
460 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
465 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
466 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
469 uint32 *num_groups, DOM_SID ***user_grpsids)
472 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
473 POLICY_HND dom_pol, user_pol;
474 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
475 BOOL got_dom_pol = False, got_user_pol = False;
476 DOM_GID *user_groups;
481 NET_USER_INFO_3 *user;
483 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string, user_sid)));
486 *user_grpsids = NULL;
488 /* so lets see if we have a cached user_info_3 */
490 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
492 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
493 sid_string_static(user_sid)));
495 *num_groups = user->num_groups;
497 (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
498 for (i=0;i<(*num_groups);i++) {
499 (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user->gids[i].g_rid);
507 /* no cache; hit the wire */
511 /* Get sam handle; if we fail here there is no hope */
513 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
516 /* Get domain handle */
518 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
519 des_access, &domain->sid, &dom_pol);
520 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
521 hnd && hnd->cli && hnd->cli->fd == -1);
523 if (!NT_STATUS_IS_OK(result))
529 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
533 /* Get user handle */
534 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
535 des_access, user_rid, &user_pol);
537 if (!NT_STATUS_IS_OK(result))
542 /* Query user rids */
543 result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol,
544 num_groups, &user_groups);
546 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
549 (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
550 if (!(*user_grpsids)) {
551 result = NT_STATUS_NO_MEMORY;
555 for (i=0;i<(*num_groups);i++) {
556 (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
560 /* Clean up policy handles */
562 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
565 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
571 /* Lookup group membership given a rid. */
572 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
574 DOM_SID *group_sid, uint32 *num_names,
575 DOM_SID ***sid_mem, char ***names,
578 CLI_POLICY_HND *hnd = NULL;
579 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
580 uint32 i, total_names = 0;
581 POLICY_HND dom_pol, group_pol;
582 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
583 BOOL got_dom_pol = False, got_group_pol = False;
584 uint32 *rid_mem = NULL;
590 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, sid_to_string(sid_string, group_sid)));
592 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
601 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
604 /* Get domain handle */
606 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
607 des_access, &domain->sid, &dom_pol);
608 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
610 if (!NT_STATUS_IS_OK(result))
615 /* Get group handle */
617 result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
618 des_access, group_rid, &group_pol);
620 if (!NT_STATUS_IS_OK(result))
623 got_group_pol = True;
625 /* Step #1: Get a list of user rids that are the members of the
628 result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
629 &group_pol, num_names, &rid_mem,
632 if (!NT_STATUS_IS_OK(result))
642 /* Step #2: Convert list of rids into list of usernames. Do this
643 in bunches of ~1000 to avoid crashing NT4. It looks like there
644 is a buffer overflow or something like that lurking around
647 #define MAX_LOOKUP_RIDS 900
649 *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
650 *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
651 *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));
653 for (j=0;j<(*num_names);j++) {
654 (*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
657 if (*num_names>0 && (!*names || !*name_types)) {
658 result = NT_STATUS_NO_MEMORY;
662 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
663 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
664 uint32 tmp_num_names = 0;
665 char **tmp_names = NULL;
666 uint32 *tmp_types = NULL;
668 /* Lookup a chunk of rids */
670 result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
671 &dom_pol, 1000, /* flags */
675 &tmp_names, &tmp_types);
677 /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
678 the one returned from 2k) */
680 if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
683 /* Copy result into array. The talloc system will take
684 care of freeing the temporary arrays later on. */
686 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
689 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
692 total_names += tmp_num_names;
695 *num_names = total_names;
697 result = NT_STATUS_OK;
701 cli_samr_close(hnd->cli, mem_ctx, &group_pol);
704 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
713 static SIG_ATOMIC_T gotalarm;
715 /***************************************************************
716 Signal function to tell us we timed out.
717 ****************************************************************/
719 static void gotalarm_sig(void)
724 static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
730 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
732 /* End setup timeout. */
734 ldp = ldap_open(server, port);
736 /* Teardown timeout. */
737 CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
743 static int get_ldap_seq(const char *server, int port, uint32 *seq)
747 char *attrs[] = {"highestCommittedUSN", NULL};
748 LDAPMessage *res = NULL;
749 char **values = NULL;
752 *seq = DOM_SEQUENCE_NONE;
755 * 10 second timeout on open. This is needed as the search timeout
756 * doesn't seem to apply to doing an open as well. JRA.
759 if ((ldp = ldap_open_with_timeout(server, port, 10)) == NULL)
762 /* Timeout if no response within 20 seconds. */
766 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
769 if (ldap_count_entries(ldp, res) != 1)
772 values = ldap_get_values(ldp, res, "highestCommittedUSN");
773 if (!values || !values[0])
776 *seq = atoi(values[0]);
782 ldap_value_free(values);
790 /**********************************************************************
791 Get the sequence number for a Windows AD native mode domain using
793 **********************************************************************/
795 static int get_ldap_sequence_number( const char* domain, uint32 *seq)
798 int i, port = LDAP_PORT;
799 struct ip_service *ip_list = NULL;
802 if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
803 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
807 /* Finally return first DC that we can contact */
809 for (i = 0; i < count; i++) {
812 /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
813 port = (ip_list[i].port!= PORT_NONE) ? ip_list[i].port : LDAP_PORT;
815 fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
817 if (is_zero_ip(ip_list[i].ip))
820 if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
823 /* add to failed connection cache */
824 add_failed_connection_entry( domain, ipstr, NT_STATUS_UNSUCCESSFUL );
829 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
830 domain, inet_ntoa(ip_list[i].ip), port));
838 #endif /* HAVE_LDAP */
840 /* find the sequence number for a domain */
841 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
846 uint16 switch_value = 2;
849 BOOL got_dom_pol = False;
850 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
853 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
855 *seq = DOM_SEQUENCE_NONE;
857 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
858 return NT_STATUS_NO_MEMORY;
863 if ( domain->native_mode )
865 DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
867 if ( get_ldap_sequence_number( domain->name, seq ) == 0 ) {
868 result = NT_STATUS_OK;
869 DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
870 domain->name, *seq));
874 DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
877 #endif /* HAVE_LDAP */
879 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain, &hnd)))
882 /* Get domain handle */
883 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
884 des_access, &domain->sid, &dom_pol);
885 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
887 if (!NT_STATUS_IS_OK(result))
892 /* Query domain info */
894 result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
897 if (NT_STATUS_IS_OK(result)) {
898 *seq = ctr.info.inf2.seq_num;
899 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
901 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
902 (unsigned)*seq, domain->name ));
908 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
910 talloc_destroy(mem_ctx);
915 /* get a list of trusted domains */
916 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
924 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
928 DEBUG(3,("rpc: trusted_domains\n"));
935 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(find_our_domain(), &hnd)))
938 result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
939 &hnd->pol, &enum_ctx,
940 num_domains, names, dom_sids);
941 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
947 /* find the domain sid for a domain */
948 static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
950 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
957 DEBUG(3,("rpc: domain_sid\n"));
959 if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
960 return NT_STATUS_NO_MEMORY;
965 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain, &hnd)))
968 result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
969 &hnd->pol, 0x05, &level5_dom, &alloc_sid);
970 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
972 if (NT_STATUS_IS_OK(result)) {
974 sid_copy(sid, alloc_sid);
976 result = NT_STATUS_NO_MEMORY;
981 talloc_destroy(mem_ctx);
985 /* find alternate names list for the domain - none for rpc */
986 static NTSTATUS alternate_name(struct winbindd_domain *domain)
992 /* the rpc backend methods are exposed via this structure */
993 struct winbindd_methods msrpc_methods = {