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->name, &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->name, &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->name, &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->name, &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->name, &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->name, &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->name, &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->name, &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))
635 /* Step #2: Convert list of rids into list of usernames. Do this
636 in bunches of ~1000 to avoid crashing NT4. It looks like there
637 is a buffer overflow or something like that lurking around
640 #define MAX_LOOKUP_RIDS 900
642 *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
643 *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
644 *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));
646 for (j=0;j<(*num_names);j++) {
647 (*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
650 if (*num_names>0 && (!*names || !*name_types)) {
651 result = NT_STATUS_NO_MEMORY;
655 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
656 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
657 uint32 tmp_num_names = 0;
658 char **tmp_names = NULL;
659 uint32 *tmp_types = NULL;
661 /* Lookup a chunk of rids */
663 result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
664 &dom_pol, 1000, /* flags */
668 &tmp_names, &tmp_types);
670 /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
671 the one returned from 2k) */
673 if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
676 /* Copy result into array. The talloc system will take
677 care of freeing the temporary arrays later on. */
679 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
682 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
685 total_names += tmp_num_names;
688 *num_names = total_names;
690 result = NT_STATUS_OK;
694 cli_samr_close(hnd->cli, mem_ctx, &group_pol);
697 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
706 static SIG_ATOMIC_T gotalarm;
708 /***************************************************************
709 Signal function to tell us we timed out.
710 ****************************************************************/
712 static void gotalarm_sig(void)
717 static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
723 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
725 /* End setup timeout. */
727 ldp = ldap_open(server, port);
729 /* Teardown timeout. */
730 CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
736 static int get_ldap_seq(const char *server, int port, uint32 *seq)
740 char *attrs[] = {"highestCommittedUSN", NULL};
741 LDAPMessage *res = NULL;
742 char **values = NULL;
745 *seq = DOM_SEQUENCE_NONE;
748 * 10 second timeout on open. This is needed as the search timeout
749 * doesn't seem to apply to doing an open as well. JRA.
752 if ((ldp = ldap_open_with_timeout(server, port, 10)) == NULL)
755 /* Timeout if no response within 20 seconds. */
759 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
762 if (ldap_count_entries(ldp, res) != 1)
765 values = ldap_get_values(ldp, res, "highestCommittedUSN");
766 if (!values || !values[0])
769 *seq = atoi(values[0]);
775 ldap_value_free(values);
783 /**********************************************************************
784 Get the sequence number for a Windows AD native mode domain using
786 **********************************************************************/
788 int get_ldap_sequence_number( const char* domain, uint32 *seq)
791 int i, port = LDAP_PORT;
792 struct ip_service *ip_list = NULL;
795 if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
796 DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
800 /* Finally return first DC that we can contact */
802 for (i = 0; i < count; i++) {
805 /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
806 port = (ip_list[i].port!= PORT_NONE) ? ip_list[i].port : LDAP_PORT;
808 fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
810 if (is_zero_ip(ip_list[i].ip))
813 if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
816 /* add to failed connection cache */
817 add_failed_connection_entry( domain, ipstr, NT_STATUS_UNSUCCESSFUL );
822 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
823 domain, inet_ntoa(ip_list[i].ip), port));
831 #endif /* HAVE_LDAP */
833 /* find the sequence number for a domain */
834 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
839 uint16 switch_value = 2;
842 BOOL got_dom_pol = False;
843 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
846 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
848 *seq = DOM_SEQUENCE_NONE;
850 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
851 return NT_STATUS_NO_MEMORY;
856 if ( domain->native_mode )
858 DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
860 if ( get_ldap_sequence_number( domain->name, seq ) == 0 ) {
861 result = NT_STATUS_OK;
862 DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
863 domain->name, *seq));
867 DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
870 #endif /* HAVE_LDAP */
872 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
875 /* Get domain handle */
876 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
877 des_access, &domain->sid, &dom_pol);
878 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
880 if (!NT_STATUS_IS_OK(result))
885 /* Query domain info */
887 result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
890 if (NT_STATUS_IS_OK(result)) {
891 *seq = ctr.info.inf2.seq_num;
892 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
894 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
895 (unsigned)*seq, domain->name ));
901 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
903 talloc_destroy(mem_ctx);
908 /* get a list of trusted domains */
909 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
917 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
921 DEBUG(3,("rpc: trusted_domains\n"));
928 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd)))
931 result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
932 &hnd->pol, &enum_ctx,
933 num_domains, names, dom_sids);
934 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
940 /* find the domain sid for a domain */
941 static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
943 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
949 DEBUG(3,("rpc: domain_sid\n"));
951 if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
952 return NT_STATUS_NO_MEMORY;
957 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
960 result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
961 &hnd->pol, 0x05, level5_dom, sid);
962 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
965 talloc_destroy(mem_ctx);
969 /* find alternate names list for the domain - none for rpc */
970 static NTSTATUS alternate_name(struct winbindd_domain *domain)
976 /* the rpc backend methods are exposed via this structure */
977 struct winbindd_methods msrpc_methods = {