fixed a crash bug in the new winbindd 'sids rule!' code
[Samba/gebeck_regimport.git] / source / nsswitch / winbindd_rpc.c
blob9989f27109d0ad49285b132da17e17033dd22852
1 /*
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.
24 #include "winbindd.h"
26 #undef DBGC_CLASS
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
32 application. */
33 static NTSTATUS query_user_list(struct winbindd_domain *domain,
34 TALLOC_CTX *mem_ctx,
35 uint32 *num_entries,
36 WINBIND_USERINFO **info)
38 CLI_POLICY_HND *hnd;
39 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
40 POLICY_HND dom_pol;
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"));
47 *num_entries = 0;
48 *info = NULL;
50 retry = 0;
51 do {
52 /* Get sam handle */
54 if (!(hnd = cm_get_sam_handle(domain->name)))
55 goto done;
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))
65 goto done;
67 got_dom_pol = True;
69 i = start_idx = 0;
70 do {
71 TALLOC_CTX *ctx2;
72 char **dom_users;
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;
78 goto done;
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(
88 mem_ctx, *info,
89 (*num_entries) * sizeof(WINBIND_USERINFO));
91 if (!(*info)) {
92 result = NT_STATUS_NO_MEMORY;
93 talloc_destroy(ctx2);
94 goto done;
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. */
109 (*info)[i].group_sid
110 = rid_to_talloced_sid(domain,
111 mem_ctx,
112 DOMAIN_GROUP_RID_USERS);
115 talloc_destroy(ctx2);
117 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
119 done:
121 if (got_dom_pol)
122 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
124 return result;
127 /* list all domain groups */
128 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
129 TALLOC_CTX *mem_ctx,
130 uint32 *num_entries,
131 struct acct_info **info)
133 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
134 CLI_POLICY_HND *hnd;
135 POLICY_HND dom_pol;
136 NTSTATUS status;
137 uint32 start = 0;
138 int retry;
140 *num_entries = 0;
141 *info = NULL;
143 DEBUG(3,("rpc: enum_dom_groups\n"));
145 retry = 0;
146 do {
147 if (!(hnd = cm_get_sam_handle(domain->name)))
148 return NT_STATUS_UNSUCCESSFUL;
150 status = cli_samr_open_domain(hnd->cli, mem_ctx,
151 &hnd->pol, des_access, &domain->sid, &dom_pol);
152 } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
154 if (!NT_STATUS_IS_OK(status))
155 return status;
157 do {
158 struct acct_info *info2 = NULL;
159 uint32 count = 0;
160 TALLOC_CTX *mem_ctx2;
162 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
164 /* start is updated by this call. */
165 status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx2, &dom_pol,
166 &start,
167 0xFFFF, /* buffer size? */
168 &info2, &count);
170 if (!NT_STATUS_IS_OK(status) &&
171 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
172 talloc_destroy(mem_ctx2);
173 break;
176 (*info) = talloc_realloc(mem_ctx, *info,
177 sizeof(**info) * ((*num_entries) + count));
178 if (! *info) {
179 talloc_destroy(mem_ctx2);
180 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
181 return NT_STATUS_NO_MEMORY;
184 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
185 (*num_entries) += count;
186 talloc_destroy(mem_ctx2);
187 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
189 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
191 return status;
194 /* List all domain groups */
196 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
197 TALLOC_CTX *mem_ctx,
198 uint32 *num_entries,
199 struct acct_info **info)
201 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
202 CLI_POLICY_HND *hnd;
203 POLICY_HND dom_pol;
204 NTSTATUS result;
205 int retry;
207 *num_entries = 0;
208 *info = NULL;
210 retry = 0;
211 do {
212 if ( !(hnd = cm_get_sam_handle(domain->name)) )
213 return NT_STATUS_UNSUCCESSFUL;
215 result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
216 des_access, &domain->sid, &dom_pol);
217 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
219 if ( !NT_STATUS_IS_OK(result))
220 return result;
222 do {
223 struct acct_info *info2 = NULL;
224 uint32 count = 0, start = *num_entries;
225 TALLOC_CTX *mem_ctx2;
227 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
229 result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
230 &start, 0xFFFF, &info2, &count);
232 if ( !NT_STATUS_IS_OK(result)
233 && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
235 talloc_destroy(mem_ctx2);
236 break;
239 (*info) = talloc_realloc(mem_ctx, *info,
240 sizeof(**info) * ((*num_entries) + count));
241 if (! *info) {
242 talloc_destroy(mem_ctx2);
243 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
244 return NT_STATUS_NO_MEMORY;
247 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
248 (*num_entries) += count;
249 talloc_destroy(mem_ctx2);
250 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
252 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
254 return result;
257 /* convert a single name to a sid in a domain */
258 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
259 TALLOC_CTX *mem_ctx,
260 const char *name,
261 DOM_SID *sid,
262 enum SID_NAME_USE *type)
264 CLI_POLICY_HND *hnd;
265 NTSTATUS status;
266 DOM_SID *sids = NULL;
267 uint32 *types = NULL;
268 const char *full_name;
269 int retry;
271 DEBUG(3,("rpc: name_to_sid name=%s\n", name));
273 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
275 if (!full_name) {
276 DEBUG(0, ("talloc_asprintf failed!\n"));
277 return NT_STATUS_NO_MEMORY;
280 retry = 0;
281 do {
282 if (!(hnd = cm_get_lsa_handle(domain->name))) {
283 return NT_STATUS_UNSUCCESSFUL;
286 status = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
287 &full_name, &sids, &types);
288 } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
290 /* Return rid and type if lookup successful */
292 if (NT_STATUS_IS_OK(status)) {
293 sid_copy(sid, &sids[0]);
294 *type = types[0];
297 return status;
301 convert a domain SID to a user or group name
303 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
304 TALLOC_CTX *mem_ctx,
305 DOM_SID *sid,
306 char **name,
307 enum SID_NAME_USE *type)
309 CLI_POLICY_HND *hnd;
310 char **domains;
311 char **names;
312 uint32 *types;
313 NTSTATUS status;
314 int retry;
316 DEBUG(3,("rpc: sid_to_name\n"));
318 retry = 0;
319 do {
320 if (!(hnd = cm_get_lsa_handle(domain->name)))
321 return NT_STATUS_UNSUCCESSFUL;
323 status = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
324 1, sid, &domains, &names, &types);
325 } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
327 if (NT_STATUS_IS_OK(status)) {
328 *type = types[0];
329 *name = names[0];
330 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
332 /* Paranoia */
333 if (strcasecmp(domain->name, domains[0]) != 0) {
334 DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
335 return NT_STATUS_UNSUCCESSFUL;
338 return status;
341 /* Lookup user information from a rid or username. */
342 static NTSTATUS query_user(struct winbindd_domain *domain,
343 TALLOC_CTX *mem_ctx,
344 DOM_SID *user_sid,
345 WINBIND_USERINFO *user_info)
347 CLI_POLICY_HND *hnd;
348 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
349 POLICY_HND dom_pol, user_pol;
350 BOOL got_dom_pol = False, got_user_pol = False;
351 SAM_USERINFO_CTR *ctr;
352 int retry;
353 fstring sid_string;
354 uint32 user_rid;
356 DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string, user_sid)));
357 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
358 goto done;
361 retry = 0;
362 do {
363 /* Get sam handle */
364 if (!(hnd = cm_get_sam_handle(domain->name)))
365 goto done;
367 /* Get domain handle */
369 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
370 SEC_RIGHTS_MAXIMUM_ALLOWED,
371 &domain->sid, &dom_pol);
372 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
374 if (!NT_STATUS_IS_OK(result))
375 goto done;
377 got_dom_pol = True;
379 /* Get user handle */
380 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
381 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
383 if (!NT_STATUS_IS_OK(result))
384 goto done;
386 got_user_pol = True;
388 /* Get user info */
389 result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol,
390 0x15, &ctr);
392 if (!NT_STATUS_IS_OK(result))
393 goto done;
395 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
396 got_user_pol = False;
398 user_info->user_sid = rid_to_talloced_sid(domain, mem_ctx, user_rid);
399 user_info->group_sid = rid_to_talloced_sid(domain, mem_ctx, ctr->info.id21->group_rid);
400 user_info->acct_name = unistr2_tdup(mem_ctx,
401 &ctr->info.id21->uni_user_name);
402 user_info->full_name = unistr2_tdup(mem_ctx,
403 &ctr->info.id21->uni_full_name);
405 done:
406 /* Clean up policy handles */
407 if (got_user_pol)
408 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
410 if (got_dom_pol)
411 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
413 return result;
416 /* Lookup groups a user is a member of. I wish Unix had a call like this! */
417 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
418 TALLOC_CTX *mem_ctx,
419 DOM_SID *user_sid,
420 uint32 *num_groups, DOM_SID ***user_gids)
422 CLI_POLICY_HND *hnd;
423 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
424 POLICY_HND dom_pol, user_pol;
425 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
426 BOOL got_dom_pol = False, got_user_pol = False;
427 DOM_GID *user_groups;
428 unsigned int i;
429 unsigned int retry;
430 fstring sid_string;
431 uint32 user_rid;
433 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string, user_sid)));
435 *num_groups = 0;
437 /* First try cached universal groups from logon */
438 *user_gids = uni_group_cache_fetch(&domain->sid, user_sid, mem_ctx, num_groups);
439 if((*num_groups > 0) && *user_gids) {
440 return NT_STATUS_OK;
441 } else {
442 *user_gids = NULL;
443 *num_groups = 0;
446 retry = 0;
447 do {
448 /* Get sam handle */
449 if (!(hnd = cm_get_sam_handle(domain->name)))
450 goto done;
452 /* Get domain handle */
453 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
454 des_access, &domain->sid, &dom_pol);
455 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
457 if (!NT_STATUS_IS_OK(result))
458 goto done;
460 got_dom_pol = True;
463 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
464 goto done;
467 /* Get user handle */
468 result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
469 des_access, user_rid, &user_pol);
471 if (!NT_STATUS_IS_OK(result))
472 goto done;
474 got_user_pol = True;
476 /* Query user rids */
477 result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol,
478 num_groups, &user_groups);
480 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
481 goto done;
483 (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups));
484 if (!(*user_gids)) {
485 result = NT_STATUS_NO_MEMORY;
486 goto done;
489 for (i=0;i<(*num_groups);i++) {
490 (*user_gids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
493 done:
494 /* Clean up policy handles */
495 if (got_user_pol)
496 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
498 if (got_dom_pol)
499 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
501 return result;
505 /* Lookup group membership given a rid. */
506 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
507 TALLOC_CTX *mem_ctx,
508 DOM_SID *group_sid, uint32 *num_names,
509 DOM_SID ***sid_mem, char ***names,
510 uint32 **name_types)
512 CLI_POLICY_HND *hnd;
513 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
514 uint32 i, total_names = 0;
515 POLICY_HND dom_pol, group_pol;
516 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
517 BOOL got_dom_pol = False, got_group_pol = False;
518 uint32 *rid_mem = NULL;
519 uint32 group_rid;
520 int retry;
521 unsigned int j;
522 fstring sid_string;
524 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, sid_to_string(sid_string, group_sid)));
526 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) {
527 goto done;
530 *num_names = 0;
532 retry = 0;
533 do {
534 /* Get sam handle */
535 if (!(hnd = cm_get_sam_handle(domain->name)))
536 goto done;
538 /* Get domain handle */
540 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
541 des_access, &domain->sid, &dom_pol);
542 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
544 if (!NT_STATUS_IS_OK(result))
545 goto done;
547 got_dom_pol = True;
549 /* Get group handle */
551 result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
552 des_access, group_rid, &group_pol);
554 if (!NT_STATUS_IS_OK(result))
555 goto done;
557 got_group_pol = True;
559 /* Step #1: Get a list of user rids that are the members of the
560 group. */
562 result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
563 &group_pol, num_names, &rid_mem,
564 name_types);
566 if (!NT_STATUS_IS_OK(result))
567 goto done;
569 /* Step #2: Convert list of rids into list of usernames. Do this
570 in bunches of ~1000 to avoid crashing NT4. It looks like there
571 is a buffer overflow or something like that lurking around
572 somewhere. */
574 #define MAX_LOOKUP_RIDS 900
576 *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
577 *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
578 *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *));
580 for (j=0;j<(*num_names);j++) {
581 (*sid_mem)[j] = rid_to_talloced_sid(domain, mem_ctx, (rid_mem)[j]);
584 if (!*names || !*name_types) {
585 result = NT_STATUS_NO_MEMORY;
586 goto done;
589 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
590 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
591 uint32 tmp_num_names = 0;
592 char **tmp_names = NULL;
593 uint32 *tmp_types = NULL;
595 /* Lookup a chunk of rids */
597 result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
598 &dom_pol, 1000, /* flags */
599 num_lookup_rids,
600 &rid_mem[i],
601 &tmp_num_names,
602 &tmp_names, &tmp_types);
604 if (!NT_STATUS_IS_OK(result))
605 goto done;
607 /* Copy result into array. The talloc system will take
608 care of freeing the temporary arrays later on. */
610 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
611 tmp_num_names);
613 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
614 tmp_num_names);
616 total_names += tmp_num_names;
619 *num_names = total_names;
621 done:
622 if (got_group_pol)
623 cli_samr_close(hnd->cli, mem_ctx, &group_pol);
625 if (got_dom_pol)
626 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
628 return result;
631 /* find the sequence number for a domain */
632 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
634 TALLOC_CTX *mem_ctx;
635 CLI_POLICY_HND *hnd;
636 SAM_UNK_CTR ctr;
637 uint16 switch_value = 2;
638 NTSTATUS result;
639 uint32 seqnum = DOM_SEQUENCE_NONE;
640 POLICY_HND dom_pol;
641 BOOL got_dom_pol = False;
642 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
643 int retry;
645 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
647 *seq = DOM_SEQUENCE_NONE;
649 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
650 return NT_STATUS_NO_MEMORY;
652 retry = 0;
653 do {
654 /* Get sam handle */
655 if (!(hnd = cm_get_sam_handle(domain->name)))
656 goto done;
658 /* Get domain handle */
659 result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
660 des_access, &domain->sid, &dom_pol);
661 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
663 if (!NT_STATUS_IS_OK(result))
664 goto done;
666 got_dom_pol = True;
668 /* Query domain info */
670 result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
671 switch_value, &ctr);
673 if (NT_STATUS_IS_OK(result)) {
674 seqnum = ctr.info.inf2.seq_num;
675 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)seqnum ));
676 } else {
677 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
678 (unsigned)seqnum, domain->name ));
681 done:
683 if (got_dom_pol)
684 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
686 talloc_destroy(mem_ctx);
688 *seq = seqnum;
690 return result;
693 /* get a list of trusted domains */
694 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
695 TALLOC_CTX *mem_ctx,
696 uint32 *num_domains,
697 char ***names,
698 char ***alt_names,
699 DOM_SID **dom_sids)
701 CLI_POLICY_HND *hnd;
702 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
703 uint32 enum_ctx = 0;
704 int retry;
706 DEBUG(3,("rpc: trusted_domains\n"));
708 *num_domains = 0;
709 *alt_names = NULL;
711 retry = 0;
712 do {
713 if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
714 goto done;
716 result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
717 &hnd->pol, &enum_ctx,
718 num_domains, names, dom_sids);
719 } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
721 done:
722 return result;
725 /* find the domain sid for a domain */
726 static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
728 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
729 TALLOC_CTX *mem_ctx;
730 CLI_POLICY_HND *hnd;
731 fstring level5_dom;
732 int retry;
734 DEBUG(3,("rpc: domain_sid\n"));
736 if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
737 return NT_STATUS_NO_MEMORY;
739 retry = 0;
740 do {
741 /* Get sam handle */
742 if (!(hnd = cm_get_lsa_handle(domain->name)))
743 goto done;
745 status = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
746 &hnd->pol, 0x05, level5_dom, sid);
747 } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
749 done:
750 talloc_destroy(mem_ctx);
751 return status;
754 /* find alternate names list for the domain - none for rpc */
755 static NTSTATUS alternate_name(struct winbindd_domain *domain)
757 return NT_STATUS_OK;
761 /* the rpc backend methods are exposed via this structure */
762 struct winbindd_methods msrpc_methods = {
763 False,
764 query_user_list,
765 enum_dom_groups,
766 enum_local_groups,
767 name_to_sid,
768 sid_to_name,
769 query_user,
770 lookup_usergroups,
771 lookup_groupmem,
772 sequence_number,
773 trusted_domains,
774 domain_sid,
775 alternate_name