update copyright notice since it we are now almost 4 months into 2003
[Samba.git] / source / nsswitch / winbindd_rpc.c
blob93df063b6d644f4456adcba4e042645615f5ddcf
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind rpc backend functions
6 Copyright (C) Tim Potter 2000-2001
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.
24 #include "winbindd.h"
26 /*******************************************************************
27 Duplicate a UNISTR2 string into a UNIX codepage null terminated char*
28 using a talloc context
29 ********************************************************************/
31 static char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
33 char *s;
34 int maxlen = (str->uni_str_len+1)*4;
35 if (!str->buffer)
36 return NULL;
37 s = (char *)talloc(ctx, maxlen); /* convervative */
38 if (!s)
39 return NULL;
40 unistr2_to_unix(s, str, maxlen);
41 return s;
44 /* Query display info for a domain. This returns enough information plus a
45 bit extra to give an overview of domain users for the User Manager
46 application. */
47 static NTSTATUS query_user_list(struct winbindd_domain *domain,
48 TALLOC_CTX *mem_ctx,
49 uint32 *num_entries,
50 WINBIND_USERINFO **info)
52 CLI_POLICY_HND *hnd;
53 NTSTATUS result;
54 POLICY_HND dom_pol;
55 BOOL got_dom_pol = False;
56 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
57 int i, loop_count = 0;
58 int retry;
60 *num_entries = 0;
61 *info = NULL;
63 retry = 0;
64 do {
65 /* Get sam handle */
67 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
68 goto done;
70 /* Get domain handle */
72 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
73 des_access, &domain->sid, &dom_pol);
74 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
75 hnd && hnd->cli && hnd->cli->fd == -1);
77 if (!NT_STATUS_IS_OK(result))
78 goto done;
80 got_dom_pol = True;
82 i = 0;
83 do {
84 SAM_DISPINFO_CTR ctr;
85 SAM_DISPINFO_1 info1;
86 uint32 count = 0, start=i, max_entries, max_size;
87 int j;
88 TALLOC_CTX *ctx2;
90 ctr.sam.info1 = &info1;
92 ctx2 = talloc_init_named("winbindd dispinfo");
93 if (!ctx2) {
94 result = NT_STATUS_NO_MEMORY;
95 goto done;
98 get_query_dispinfo_params(
99 loop_count, &max_entries, &max_size);
101 /* Query display info level 1 */
102 result = cli_samr_query_dispinfo(
103 hnd->cli, ctx2, &dom_pol, &start, 1, &count,
104 max_entries, max_size, &ctr);
106 loop_count++;
108 if (!NT_STATUS_IS_OK(result) &&
109 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break;
111 (*num_entries) += count;
113 /* now map the result into the WINBIND_USERINFO structure */
114 (*info) = talloc_realloc(mem_ctx, *info,
115 (*num_entries)*sizeof(WINBIND_USERINFO));
116 if (!(*info)) {
117 result = NT_STATUS_NO_MEMORY;
118 talloc_destroy(ctx2);
119 goto done;
122 for (j=0;j<count;i++, j++) {
123 /* unistr2_tdup converts to UNIX charset. */
124 (*info)[i].acct_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_acct_name);
125 (*info)[i].full_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_full_name);
126 (*info)[i].user_rid = info1.sam[j].rid_user;
127 /* For the moment we set the primary group for
128 every user to be the Domain Users group.
129 There are serious problems with determining
130 the actual primary group for large domains.
131 This should really be made into a 'winbind
132 force group' smb.conf parameter or
133 something like that. */
134 (*info)[i].group_rid = DOMAIN_GROUP_RID_USERS;
137 talloc_destroy(ctx2);
138 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
140 done:
142 if (got_dom_pol)
143 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
145 return result;
148 /* List all domain groups */
150 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
151 TALLOC_CTX *mem_ctx,
152 uint32 *num_entries,
153 struct acct_info **info)
155 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
156 CLI_POLICY_HND *hnd;
157 POLICY_HND dom_pol;
158 NTSTATUS result;
159 uint32 start = 0;
160 int retry;
162 *num_entries = 0;
163 *info = NULL;
165 retry = 0;
166 do {
167 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
168 return result;
170 result = cli_samr_open_domain(hnd->cli, mem_ctx,
171 &hnd->pol, des_access, &domain->sid, &dom_pol);
172 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
173 hnd && hnd->cli && hnd->cli->fd == -1);
175 if (!NT_STATUS_IS_OK(result))
176 return result;
178 do {
179 struct acct_info *info2 = NULL;
180 uint32 count = 0;
181 TALLOC_CTX *mem_ctx2;
183 mem_ctx2 = talloc_init_named("enum_dom_groups[rpc]");
185 /* This call updates 'start' */
186 result = cli_samr_enum_dom_groups(
187 hnd->cli, mem_ctx2, &dom_pol, &start,
188 0xFFFF, /* buffer size? */ &info2, &count);
190 if (!NT_STATUS_IS_OK(result) &&
191 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
192 talloc_destroy(mem_ctx2);
193 break;
196 (*info) = talloc_realloc(mem_ctx, *info,
197 sizeof(**info) * ((*num_entries) + count));
198 if (! *info) {
199 talloc_destroy(mem_ctx2);
200 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
201 return NT_STATUS_NO_MEMORY;
204 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
205 (*num_entries) += count;
206 talloc_destroy(mem_ctx2);
207 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
209 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
211 return result;
214 /* convert a single name to a sid in a domain */
215 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
216 const char *name,
217 DOM_SID *sid,
218 enum SID_NAME_USE *type)
220 TALLOC_CTX *mem_ctx;
221 CLI_POLICY_HND *hnd;
222 NTSTATUS result;
223 DOM_SID *sids = NULL;
224 uint32 *types = NULL;
225 const char *full_name;
226 int retry;
228 if (!(mem_ctx = talloc_init_named("name_to_sid[rpc] for [%s]\\[%s]", domain->name, name))) {
229 DEBUG(0, ("talloc_init failed!\n"));
230 return NT_STATUS_NO_MEMORY;
233 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
235 if (!full_name) {
236 DEBUG(0, ("talloc_asprintf failed!\n"));
237 talloc_destroy(mem_ctx);
238 return NT_STATUS_NO_MEMORY;
241 retry = 0;
242 do {
243 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) {
244 talloc_destroy(mem_ctx);
245 return NT_STATUS_UNSUCCESSFUL;
248 result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
249 &full_name, &sids, &types);
250 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
251 hnd && hnd->cli && hnd->cli->fd == -1);
253 /* Return rid and type if lookup successful */
255 if (NT_STATUS_IS_OK(result)) {
256 sid_copy(sid, &sids[0]);
257 *type = types[0];
260 talloc_destroy(mem_ctx);
261 return result;
265 convert a domain SID to a user or group name
267 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
268 TALLOC_CTX *mem_ctx,
269 DOM_SID *sid,
270 char **name,
271 enum SID_NAME_USE *type)
273 CLI_POLICY_HND *hnd;
274 char **domains;
275 char **names;
276 uint32 *types;
277 NTSTATUS result;
278 int retry;
280 retry = 0;
281 do {
282 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
283 return NT_STATUS_UNSUCCESSFUL;
285 result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
286 1, sid, &domains, &names, &types);
287 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
288 hnd && hnd->cli && hnd->cli->fd == -1);
290 if (NT_STATUS_IS_OK(result)) {
291 *type = types[0];
292 *name = names[0];
293 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
295 /* Paranoia */
296 if (strcasecmp(domain->name, domains[0]) != 0) {
297 DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
298 return NT_STATUS_UNSUCCESSFUL;
302 return result;
305 /* Lookup user information from a rid or username. */
306 static NTSTATUS query_user(struct winbindd_domain *domain,
307 TALLOC_CTX *mem_ctx,
308 uint32 user_rid,
309 WINBIND_USERINFO *user_info)
311 CLI_POLICY_HND *hnd;
312 NTSTATUS result;
313 POLICY_HND dom_pol, user_pol;
314 BOOL got_dom_pol = False, got_user_pol = False;
315 SAM_USERINFO_CTR *ctr;
316 int retry;
318 retry = 0;
319 do {
320 /* Get sam handle */
321 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
322 goto done;
324 /* Get domain handle */
325 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
326 SEC_RIGHTS_MAXIMUM_ALLOWED,
327 &domain->sid, &dom_pol);
328 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
329 hnd && hnd->cli && hnd->cli->fd == -1);
331 if (!NT_STATUS_IS_OK(result))
332 goto done;
334 got_dom_pol = True;
336 /* Get user handle */
337 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
338 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
340 if (!NT_STATUS_IS_OK(result))
341 goto done;
343 got_user_pol = True;
345 /* Get user info */
346 result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol,
347 0x15, &ctr);
349 if (!NT_STATUS_IS_OK(result))
350 goto done;
352 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
353 got_user_pol = False;
355 user_info->user_rid = user_rid;
356 user_info->group_rid = ctr->info.id21->group_rid;
357 user_info->acct_name = unistr2_tdup(mem_ctx,
358 &ctr->info.id21->uni_user_name);
359 user_info->full_name = unistr2_tdup(mem_ctx,
360 &ctr->info.id21->uni_full_name);
362 done:
363 /* Clean up policy handles */
364 if (got_user_pol)
365 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
367 if (got_dom_pol)
368 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
370 return result;
373 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
374 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
375 TALLOC_CTX *mem_ctx,
376 uint32 user_rid,
377 uint32 *num_groups, uint32 **user_gids)
379 CLI_POLICY_HND *hnd;
380 NTSTATUS result;
381 POLICY_HND dom_pol, user_pol;
382 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
383 BOOL got_dom_pol = False, got_user_pol = False;
384 DOM_GID *user_groups;
385 int i;
386 int retry;
388 *num_groups = 0;
389 *user_gids = NULL;
391 retry = 0;
392 do {
393 /* Get sam handle */
394 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
395 goto done;
397 /* Get domain handle */
398 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
399 des_access, &domain->sid, &dom_pol);
400 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
401 hnd && hnd->cli && hnd->cli->fd == -1);
403 if (!NT_STATUS_IS_OK(result))
404 goto done;
406 got_dom_pol = True;
408 /* Get user handle */
409 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
410 des_access, user_rid, &user_pol);
412 if (!NT_STATUS_IS_OK(result))
413 goto done;
415 got_user_pol = True;
417 /* Query user rids */
418 result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol,
419 num_groups, &user_groups);
421 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
422 goto done;
424 (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups));
425 for (i=0;i<(*num_groups);i++) {
426 (*user_gids)[i] = user_groups[i].g_rid;
429 done:
430 /* Clean up policy handles */
431 if (got_user_pol)
432 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
434 if (got_dom_pol)
435 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
437 return result;
441 /* Lookup group membership given a rid. */
442 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
443 TALLOC_CTX *mem_ctx,
444 uint32 group_rid, uint32 *num_names,
445 uint32 **rid_mem, char ***names,
446 uint32 **name_types)
448 CLI_POLICY_HND *hnd;
449 NTSTATUS result;
450 uint32 i, total_names = 0;
451 POLICY_HND dom_pol, group_pol;
452 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
453 BOOL got_dom_pol = False, got_group_pol = False;
454 int retry;
456 *num_names = 0;
458 retry = 0;
459 do {
460 /* Get sam handle */
461 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
462 goto done;
464 /* Get domain handle */
465 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
466 des_access, &domain->sid, &dom_pol);
467 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
468 hnd && hnd->cli && hnd->cli->fd == -1);
470 if (!NT_STATUS_IS_OK(result))
471 goto done;
473 got_dom_pol = True;
475 /* Get group handle */
477 result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
478 des_access, group_rid, &group_pol);
480 if (!NT_STATUS_IS_OK(result))
481 goto done;
483 got_group_pol = True;
485 /* Step #1: Get a list of user rids that are the members of the
486 group. */
488 result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
489 &group_pol, num_names, rid_mem,
490 name_types);
492 if (!NT_STATUS_IS_OK(result))
493 goto done;
495 /* Step #2: Convert list of rids into list of usernames. Do this
496 in bunches of ~1000 to avoid crashing NT4. It looks like there
497 is a buffer overflow or something like that lurking around
498 somewhere. */
500 #define MAX_LOOKUP_RIDS 900
502 *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
503 *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
505 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
506 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
507 uint32 tmp_num_names = 0;
508 char **tmp_names = NULL;
509 uint32 *tmp_types = NULL;
511 /* Lookup a chunk of rids */
513 result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
514 &dom_pol, 1000, /* flags */
515 num_lookup_rids,
516 &(*rid_mem)[i],
517 &tmp_num_names,
518 &tmp_names, &tmp_types);
520 if (!NT_STATUS_IS_OK(result))
521 goto done;
523 /* Copy result into array. The talloc system will take
524 care of freeing the temporary arrays later on. */
526 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
527 tmp_num_names);
529 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
530 tmp_num_names);
532 total_names += tmp_num_names;
535 *num_names = total_names;
537 done:
538 if (got_group_pol)
539 cli_samr_close(hnd->cli, mem_ctx, &group_pol);
541 if (got_dom_pol)
542 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
544 return result;
547 /* find the sequence number for a domain */
549 #ifdef WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK
550 #include <ldap.h>
552 static SIG_ATOMIC_T gotalarm;
554 /***************************************************************
555 Signal function to tell us we timed out.
556 ****************************************************************/
558 static void gotalarm_sig(void)
560 gotalarm = 1;
563 static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
565 LDAP *ldp = NULL;
567 /* Setup timeout */
568 gotalarm = 0;
569 CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
570 alarm(to);
571 /* End setup timeout. */
573 ldp = ldap_open(server, port);
575 /* Teardown timeout. */
576 CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
577 alarm(0);
579 return ldp;
582 int get_ldap_seq(const char *server, uint32 *seq)
584 int ret = -1;
585 struct timeval to;
586 char *attrs[] = {"highestCommittedUSN", NULL};
587 LDAPMessage *res = NULL;
588 char **values = NULL;
589 LDAP *ldp = NULL;
591 *seq = DOM_SEQUENCE_NONE;
594 * 10 second timeout on open. This is needed as the search timeout
595 * doesn't seem to apply to doing an open as well. JRA.
598 if ((ldp = ldap_open_with_timeout(server, LDAP_PORT, 10)) == NULL)
599 return -1;
601 #if 0
602 /* As per tridge comment this doesn't seem to be needed. JRA */
603 if ((err = ldap_simple_bind_s(ldp, NULL, NULL)) != 0)
604 goto done;
605 #endif
607 /* Timeout if no response within 20 seconds. */
608 to.tv_sec = 10;
609 to.tv_usec = 0;
611 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
612 goto done;
614 if (ldap_count_entries(ldp, res) != 1)
615 goto done;
617 values = ldap_get_values(ldp, res, "highestCommittedUSN");
618 if (!values || !values[0])
619 goto done;
621 *seq = atoi(values[0]);
622 ret = 0;
624 done:
626 if (values)
627 ldap_value_free(values);
628 if (res)
629 ldap_msgfree(res);
630 if (ldp)
631 ldap_unbind(ldp);
632 return ret;
634 #endif /* WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK */
636 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
638 TALLOC_CTX *mem_ctx;
639 CLI_POLICY_HND *hnd;
640 SAM_UNK_CTR ctr;
641 uint16 switch_value = 2;
642 NTSTATUS result;
643 uint32 seqnum = DOM_SEQUENCE_NONE;
644 POLICY_HND dom_pol;
645 BOOL got_dom_pol = False;
646 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
647 int retry;
649 *seq = DOM_SEQUENCE_NONE;
651 if (!(mem_ctx = talloc_init_named("sequence_number[rpc]")))
652 return NT_STATUS_NO_MEMORY;
654 retry = 0;
655 do {
656 /* Get sam handle */
657 if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
658 goto done;
660 #ifdef WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK
661 if (get_ldap_seq( inet_ntoa(hnd->cli->dest_ip), seq) == 0) {
662 result = NT_STATUS_OK;
663 seqnum = *seq;
664 DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
665 domain->name, (unsigned)seqnum ));
666 goto done;
669 DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number (%u) for domain %s\n",
670 (unsigned)seqnum, domain->name ));
672 #endif /* WITH_HORRIBLE_LDAP_NATIVE_MODE_HACK */
674 /* Get domain handle */
675 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
676 des_access, &domain->sid, &dom_pol);
677 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
678 hnd && hnd->cli && hnd->cli->fd == -1);
680 if (!NT_STATUS_IS_OK(result))
681 goto done;
683 got_dom_pol = True;
685 /* Query domain info */
687 result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
688 switch_value, &ctr);
690 if (NT_STATUS_IS_OK(result)) {
691 seqnum = ctr.info.inf2.seq_num;
692 seqnum += ctr.info.inf2.num_domain_usrs;
693 seqnum += ctr.info.inf2.num_domain_grps;
694 seqnum += ctr.info.inf2.num_local_grps;
695 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)seqnum ));
696 } else {
697 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
698 (unsigned)seqnum, domain->name ));
701 done:
703 if (got_dom_pol)
704 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
706 talloc_destroy(mem_ctx);
708 *seq = seqnum;
710 return result;
713 /* get a list of trusted domains */
714 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
715 TALLOC_CTX *mem_ctx,
716 uint32 *num_domains,
717 char ***names,
718 DOM_SID **dom_sids)
720 CLI_POLICY_HND *hnd;
721 NTSTATUS result;
722 uint32 enum_ctx = 0;
723 int retry;
725 *num_domains = 0;
727 retry = 0;
728 do {
729 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd)))
730 goto done;
732 result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
733 &hnd->pol, &enum_ctx, num_domains,
734 names, dom_sids);
735 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
736 hnd && hnd->cli && hnd->cli->fd == -1);
737 done:
738 return result;
741 /* find the domain sid for a domain */
742 static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
744 NTSTATUS result;
745 TALLOC_CTX *mem_ctx;
746 CLI_POLICY_HND *hnd;
747 fstring level5_dom;
748 int retry;
750 if (!(mem_ctx = talloc_init_named("domain_sid[rpc]")))
751 return NT_STATUS_NO_MEMORY;
753 retry = 0;
754 do {
755 /* Get lsa handle */
756 if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
757 goto done;
759 result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
760 &hnd->pol, 0x05, level5_dom, sid);
762 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
763 hnd && hnd->cli && hnd->cli->fd == -1);
764 done:
765 talloc_destroy(mem_ctx);
766 return result;
769 /* the rpc backend methods are exposed via this structure */
770 struct winbindd_methods msrpc_methods = {
771 False,
772 query_user_list,
773 enum_dom_groups,
774 name_to_sid,
775 sid_to_name,
776 query_user,
777 lookup_usergroups,
778 lookup_groupmem,
779 sequence_number,
780 trusted_domains,
781 domain_sid