Forward port the change to talloc_init() to make all talloc contexts
[tprouty/samba.git] / source3 / nsswitch / winbindd_rpc.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Winbind rpc backend functions
5
6    Copyright (C) Tim Potter 2000-2001
7    Copyright (C) Andrew Tridgell 2001
8    
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.
13    
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.
18    
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.
22 */
23
24 #include "winbindd.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_WINBIND
28
29 /* Query display info for a domain.  This returns enough information plus a
30    bit extra to give an overview of domain users for the User Manager
31    application. */
32 static NTSTATUS query_user_list(struct winbindd_domain *domain,
33                                TALLOC_CTX *mem_ctx,
34                                uint32 *num_entries, 
35                                WINBIND_USERINFO **info)
36 {
37         CLI_POLICY_HND *hnd;
38         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
39         POLICY_HND dom_pol;
40         BOOL got_dom_pol = False;
41         uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
42         int i;
43
44         DEBUG(3,("rpc: query_user_list\n"));
45
46         *num_entries = 0;
47         *info = NULL;
48
49         /* Get sam handle */
50
51         if (!(hnd = cm_get_sam_handle(domain->name)))
52                 goto done;
53
54         /* Get domain handle */
55
56         result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
57                                         des_access, &domain->sid, &dom_pol);
58
59         if (!NT_STATUS_IS_OK(result))
60                 goto done;
61
62         got_dom_pol = True;
63
64         i = 0;
65         do {
66                 SAM_DISPINFO_CTR ctr;
67                 SAM_DISPINFO_1 info1;
68                 uint32 count = 0, start=i;
69                 int j;
70                 TALLOC_CTX *ctx2;
71
72                 ctr.sam.info1 = &info1;
73
74                 ctx2 = talloc_init("winbindd dispinfo");
75                 if (!ctx2) {
76                         result = NT_STATUS_NO_MEMORY;
77                         goto done;
78                 }
79                 
80                 /* Query display info level 1 */
81                 result = cli_samr_query_dispinfo(hnd->cli, ctx2,
82                                                  &dom_pol, &start, 1,
83                                                  &count, 0xFFFF, &ctr);
84
85                 if (!NT_STATUS_IS_OK(result) && 
86                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break;
87
88                 (*num_entries) += count;
89
90                 /* now map the result into the WINBIND_USERINFO structure */
91                 (*info) = talloc_realloc(mem_ctx, *info,
92                                          (*num_entries)*sizeof(WINBIND_USERINFO));
93                 if (!(*info)) {
94                         result = NT_STATUS_NO_MEMORY;
95                         talloc_destroy(ctx2);
96                         goto done;
97                 }
98
99                 for (j=0;j<count;i++, j++) {
100                         (*info)[i].acct_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_acct_name);
101                         (*info)[i].full_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_full_name);
102                         (*info)[i].user_rid = info1.sam[j].rid_user;
103                         /* For the moment we set the primary group for
104                            every user to be the Domain Users group.
105                            There are serious problems with determining
106                            the actual primary group for large domains.
107                            This should really be made into a 'winbind
108                            force group' smb.conf parameter or
109                            something like that. */
110                         (*info)[i].group_rid = DOMAIN_GROUP_RID_USERS;
111                 }
112
113                 talloc_destroy(ctx2);
114         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
115
116  done:
117
118         if (got_dom_pol)
119                 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
120
121         return result;
122 }
123
124 /* list all domain groups */
125 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
126                                 TALLOC_CTX *mem_ctx,
127                                 uint32 *num_entries, 
128                                 struct acct_info **info)
129 {
130         uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
131         CLI_POLICY_HND *hnd;
132         POLICY_HND dom_pol;
133         NTSTATUS status;
134
135         *num_entries = 0;
136         *info = NULL;
137
138         DEBUG(3,("rpc: enum_dom_groups\n"));
139
140         if (!(hnd = cm_get_sam_handle(domain->name))) {
141                 return NT_STATUS_UNSUCCESSFUL;
142         }
143
144         status = cli_samr_open_domain(hnd->cli, mem_ctx,
145                                       &hnd->pol, des_access, &domain->sid, &dom_pol);
146         if (!NT_STATUS_IS_OK(status)) {
147                 return status;
148         }
149
150         do {
151                 struct acct_info *info2 = NULL;
152                 uint32 count = 0, start = *num_entries;
153                 TALLOC_CTX *mem_ctx2;
154
155                 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
156
157                 status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx2, &dom_pol,
158                                                   &start,
159                                                   0xFFFF, /* buffer size? */
160                                                   &info2, &count);
161
162                 if (!NT_STATUS_IS_OK(status) && 
163                     !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
164                         talloc_destroy(mem_ctx2);
165                         break;
166                 }
167
168                 (*info) = talloc_realloc(mem_ctx, *info, 
169                                          sizeof(**info) * ((*num_entries) + count));
170                 if (! *info) {
171                         talloc_destroy(mem_ctx2);
172                         cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
173                         return NT_STATUS_NO_MEMORY;
174                 }
175
176                 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
177                 (*num_entries) += count;
178                 talloc_destroy(mem_ctx2);
179         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
180
181         cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
182
183         return status;
184 }
185
186 /* List all domain groups */
187
188 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
189                                 TALLOC_CTX *mem_ctx,
190                                 uint32 *num_entries, 
191                                 struct acct_info **info)
192 {
193         uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
194         CLI_POLICY_HND *hnd;
195         POLICY_HND dom_pol;
196         NTSTATUS result;
197
198         *num_entries = 0;
199         *info = NULL;
200
201         if ( !(hnd = cm_get_sam_handle(domain->name)) )
202                 return NT_STATUS_UNSUCCESSFUL;
203
204         if ( !NT_STATUS_IS_OK(result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol, 
205                                                 des_access, &domain->sid, &dom_pol)) )
206         {
207                 return result;
208         }
209
210         do {
211                 struct acct_info *info2 = NULL;
212                 uint32 count = 0, start = *num_entries;
213                 TALLOC_CTX *mem_ctx2;
214
215                 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
216
217                 result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
218                                           &start, 0xFFFF, &info2, &count);
219                                           
220                 if ( !NT_STATUS_IS_OK(result) 
221                         && !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) ) 
222                 {
223                         talloc_destroy(mem_ctx2);
224                         break;
225                 }
226
227                 (*info) = talloc_realloc(mem_ctx, *info, 
228                                          sizeof(**info) * ((*num_entries) + count));
229                 if (! *info) {
230                         talloc_destroy(mem_ctx2);
231                         cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
232                         return NT_STATUS_NO_MEMORY;
233                 }
234
235                 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
236                 (*num_entries) += count;
237                 talloc_destroy(mem_ctx2);
238         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
239
240         cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
241
242         return result;
243 }
244
245 /* convert a single name to a sid in a domain */
246 static NTSTATUS name_to_sid(struct winbindd_domain *domain,
247                             const char *name,
248                             DOM_SID *sid,
249                             enum SID_NAME_USE *type)
250 {
251         TALLOC_CTX *mem_ctx;
252         CLI_POLICY_HND *hnd;
253         NTSTATUS status;
254         DOM_SID *sids = NULL;
255         uint32 *types = NULL;
256         const char *full_name;
257
258         DEBUG(3,("rpc: name_to_sid name=%s\n", name));
259
260         if (!(mem_ctx = talloc_init("name_to_sid[rpc] for [%s]\\[%s]", domain->name, name))) {
261                 DEBUG(0, ("talloc_init failed!\n"));
262                 return NT_STATUS_NO_MEMORY;
263         }
264         
265         if (!(hnd = cm_get_lsa_handle(domain->name))) {
266                 talloc_destroy(mem_ctx);
267                 return NT_STATUS_UNSUCCESSFUL;
268         }
269         
270         full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain->name, name);
271         
272         if (!full_name) {
273                 DEBUG(0, ("talloc_asprintf failed!\n"));
274                 talloc_destroy(mem_ctx);
275                 return NT_STATUS_NO_MEMORY;
276         }
277
278         status = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1, 
279                                       &full_name, &sids, &types);
280         
281         /* Return rid and type if lookup successful */
282
283         if (NT_STATUS_IS_OK(status)) {
284                 sid_copy(sid, &sids[0]);
285                 *type = types[0];
286         }
287
288         talloc_destroy(mem_ctx);
289         return status;
290 }
291
292 /*
293   convert a domain SID to a user or group name
294 */
295 static NTSTATUS sid_to_name(struct winbindd_domain *domain,
296                             TALLOC_CTX *mem_ctx,
297                             DOM_SID *sid,
298                             char **name,
299                             enum SID_NAME_USE *type)
300 {
301         CLI_POLICY_HND *hnd;
302         char **domains;
303         char **names;
304         uint32 *types;
305         NTSTATUS status;
306
307         DEBUG(3,("rpc: sid_to_name\n"));
308
309         if (!(hnd = cm_get_lsa_handle(domain->name)))
310                 return NT_STATUS_UNSUCCESSFUL;
311         
312         status = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
313                                      1, sid, &domains, &names, &types);
314
315         if (NT_STATUS_IS_OK(status)) {
316                 *type = types[0];
317                 *name = names[0];
318                 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
319
320                 /* Paranoia */
321                 if (strcasecmp(domain->name, domains[0]) != 0) {
322                         DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0]));
323                         return NT_STATUS_UNSUCCESSFUL;
324                 }
325         }
326         return status;
327 }
328
329 /* Lookup user information from a rid or username. */
330 static NTSTATUS query_user(struct winbindd_domain *domain, 
331                            TALLOC_CTX *mem_ctx, 
332                            uint32 user_rid, 
333                            WINBIND_USERINFO *user_info)
334 {
335         CLI_POLICY_HND *hnd;
336         NTSTATUS result;
337         POLICY_HND dom_pol, user_pol;
338         BOOL got_dom_pol = False, got_user_pol = False;
339         SAM_USERINFO_CTR *ctr;
340
341         DEBUG(3,("rpc: query_user rid=%u\n", user_rid));
342
343         /* Get sam handle */
344         if (!(hnd = cm_get_sam_handle(domain->name)))
345                 goto done;
346
347         /* Get domain handle */
348
349         result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
350                                       SEC_RIGHTS_MAXIMUM_ALLOWED, 
351                                       &domain->sid, &dom_pol);
352
353         if (!NT_STATUS_IS_OK(result))
354                 goto done;
355
356         got_dom_pol = True;
357
358         /* Get user handle */
359         result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
360                                     SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
361
362         if (!NT_STATUS_IS_OK(result))
363                 goto done;
364
365         got_user_pol = True;
366
367         /* Get user info */
368         result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &user_pol, 
369                                          0x15, &ctr);
370
371         if (!NT_STATUS_IS_OK(result))
372                 goto done;
373
374         cli_samr_close(hnd->cli, mem_ctx, &user_pol);
375         got_user_pol = False;
376
377         user_info->user_rid = user_rid;
378         user_info->group_rid = ctr->info.id21->group_rid;
379         user_info->acct_name = unistr2_tdup(mem_ctx, 
380                                             &ctr->info.id21->uni_user_name);
381         user_info->full_name = unistr2_tdup(mem_ctx, 
382                                             &ctr->info.id21->uni_full_name);
383
384  done:
385         /* Clean up policy handles */
386         if (got_user_pol)
387                 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
388
389         if (got_dom_pol)
390                 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
391
392         return result;
393 }                                   
394
395 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
396 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
397                                   TALLOC_CTX *mem_ctx,
398                                   uint32 user_rid, 
399                                   uint32 *num_groups, uint32 **user_gids)
400 {
401         CLI_POLICY_HND *hnd;
402         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
403         POLICY_HND dom_pol, user_pol;
404         uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
405         BOOL got_dom_pol = False, got_user_pol = False;
406         DOM_GID *user_groups;
407         int i;
408
409         DEBUG(3,("rpc: lookup_usergroups rid=%u\n", user_rid));
410
411         *num_groups = 0;
412
413         /* First try cached universal groups from logon */
414         *user_gids = uni_group_cache_fetch(&domain->sid, user_rid, mem_ctx, num_groups);
415         if((*num_groups > 0) && *user_gids) {
416                 return NT_STATUS_OK;
417         } else {
418             *user_gids = NULL;
419             *num_groups = 0;
420         }
421
422         /* Get sam handle */
423         if (!(hnd = cm_get_sam_handle(domain->name)))
424                 goto done;
425
426         /* Get domain handle */
427         result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
428                                         des_access, &domain->sid, &dom_pol);
429
430         if (!NT_STATUS_IS_OK(result))
431                 goto done;
432
433         got_dom_pol = True;
434
435         /* Get user handle */
436         result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol,
437                                         des_access, user_rid, &user_pol);
438
439         if (!NT_STATUS_IS_OK(result))
440                 goto done;
441
442         got_user_pol = True;
443
444         /* Query user rids */
445         result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol, 
446                                            num_groups, &user_groups);
447
448         if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
449                 goto done;
450
451         (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups));
452         for (i=0;i<(*num_groups);i++) {
453                 (*user_gids)[i] = user_groups[i].g_rid;
454         }
455         
456  done:
457         /* Clean up policy handles */
458         if (got_user_pol)
459                 cli_samr_close(hnd->cli, mem_ctx, &user_pol);
460
461         if (got_dom_pol)
462                 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
463
464         return result;
465 }
466
467
468 /* Lookup group membership given a rid.   */
469 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
470                                 TALLOC_CTX *mem_ctx,
471                                 uint32 group_rid, uint32 *num_names, 
472                                 uint32 **rid_mem, char ***names, 
473                                 uint32 **name_types)
474 {
475         CLI_POLICY_HND *hnd;
476         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
477         uint32 i, total_names = 0;
478         POLICY_HND dom_pol, group_pol;
479         uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
480         BOOL got_dom_pol = False, got_group_pol = False;
481
482         DEBUG(10,("rpc: lookup_groupmem %s rid=%u\n", domain->name, group_rid));
483
484         *num_names = 0;
485
486         /* Get sam handle */
487
488         if (!(hnd = cm_get_sam_handle(domain->name)))
489                 goto done;
490
491         /* Get domain handle */
492
493         result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
494                                       des_access, &domain->sid, &dom_pol);
495
496         if (!NT_STATUS_IS_OK(result))
497                 goto done;
498
499         got_dom_pol = True;
500
501         /* Get group handle */
502
503         result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol,
504                                      des_access, group_rid, &group_pol);
505
506         if (!NT_STATUS_IS_OK(result))
507                 goto done;
508
509         got_group_pol = True;
510
511         /* Step #1: Get a list of user rids that are the members of the
512            group. */
513
514         result = cli_samr_query_groupmem(hnd->cli, mem_ctx,
515                                          &group_pol, num_names, rid_mem,
516                                          name_types);
517
518         if (!NT_STATUS_IS_OK(result))
519                 goto done;
520
521         /* Step #2: Convert list of rids into list of usernames.  Do this
522            in bunches of ~1000 to avoid crashing NT4.  It looks like there
523            is a buffer overflow or something like that lurking around
524            somewhere. */
525
526 #define MAX_LOOKUP_RIDS 900
527
528         *names = talloc_zero(mem_ctx, *num_names * sizeof(char *));
529         *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32));
530
531         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
532                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
533                 uint32 tmp_num_names = 0;
534                 char **tmp_names = NULL;
535                 uint32 *tmp_types = NULL;
536
537                 /* Lookup a chunk of rids */
538
539                 result = cli_samr_lookup_rids(hnd->cli, mem_ctx,
540                                               &dom_pol, 1000, /* flags */
541                                               num_lookup_rids,
542                                               &(*rid_mem)[i],
543                                               &tmp_num_names,
544                                               &tmp_names, &tmp_types);
545
546                 if (!NT_STATUS_IS_OK(result))
547                         goto done;
548
549                 /* Copy result into array.  The talloc system will take
550                    care of freeing the temporary arrays later on. */
551
552                 memcpy(&(*names)[i], tmp_names, sizeof(char *) * 
553                        tmp_num_names);
554
555                 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
556                        tmp_num_names);
557
558                 total_names += tmp_num_names;
559         }
560
561         *num_names = total_names;
562
563  done:
564         if (got_group_pol)
565                 cli_samr_close(hnd->cli, mem_ctx, &group_pol);
566
567         if (got_dom_pol)
568                 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
569
570         return result;
571 }
572
573 /* find the sequence number for a domain */
574 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
575 {
576         TALLOC_CTX *mem_ctx;
577         CLI_POLICY_HND *hnd;
578         SAM_UNK_CTR ctr;
579         uint16 switch_value = 2;
580         NTSTATUS result;
581         uint32 seqnum = DOM_SEQUENCE_NONE;
582         POLICY_HND dom_pol;
583         BOOL got_dom_pol = False;
584         uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
585
586         DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
587
588         *seq = DOM_SEQUENCE_NONE;
589
590         if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
591                 return NT_STATUS_NO_MEMORY;
592
593         /* Get sam handle */
594
595         if (!(hnd = cm_get_sam_handle(domain->name)))
596                 goto done;
597
598         /* Get domain handle */
599
600         result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, 
601                                       des_access, &domain->sid, &dom_pol);
602
603         if (!NT_STATUS_IS_OK(result))
604                 goto done;
605
606         got_dom_pol = True;
607
608         /* Query domain info */
609
610         result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
611                                          switch_value, &ctr);
612
613         if (NT_STATUS_IS_OK(result)) {
614                 seqnum = ctr.info.inf2.seq_num;
615                 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)seqnum ));
616         } else {
617                 DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
618                         (unsigned)seqnum, domain->name ));
619         }
620
621   done:
622
623         if (got_dom_pol)
624                 cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
625
626         talloc_destroy(mem_ctx);
627
628         *seq = seqnum;
629
630         return result;
631 }
632
633 /* get a list of trusted domains */
634 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
635                                 TALLOC_CTX *mem_ctx,
636                                 uint32 *num_domains,
637                                 char ***names,
638                                 char ***alt_names,
639                                 DOM_SID **dom_sids)
640 {
641         CLI_POLICY_HND *hnd;
642         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
643         uint32 enum_ctx = 0;
644
645         DEBUG(3,("rpc: trusted_domains\n"));
646
647         *num_domains = 0;
648         *alt_names = NULL;
649
650         if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
651                 goto done;
652
653         result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
654                                         &hnd->pol, &enum_ctx,
655                                         num_domains, names, dom_sids);
656 done:
657         return result;
658 }
659
660 /* find the domain sid for a domain */
661 static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
662 {
663         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
664         TALLOC_CTX *mem_ctx;
665         CLI_POLICY_HND *hnd;
666         fstring level5_dom;
667
668         DEBUG(3,("rpc: domain_sid\n"));
669
670         if (!(mem_ctx = talloc_init("domain_sid[rpc]")))
671                 return NT_STATUS_NO_MEMORY;
672
673         /* Get sam handle */
674         if (!(hnd = cm_get_lsa_handle(domain->name)))
675                 goto done;
676
677         status = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
678                                            &hnd->pol, 0x05, level5_dom, sid);
679
680 done:
681         talloc_destroy(mem_ctx);
682         return status;
683 }
684
685 /* find alternate names list for the domain - none for rpc */
686 static NTSTATUS alternate_name(struct winbindd_domain *domain)
687 {
688         return NT_STATUS_OK;
689 }
690
691
692 /* the rpc backend methods are exposed via this structure */
693 struct winbindd_methods msrpc_methods = {
694         False,
695         query_user_list,
696         enum_dom_groups,
697         enum_local_groups,
698         name_to_sid,
699         sid_to_name,
700         query_user,
701         lookup_usergroups,
702         lookup_groupmem,
703         sequence_number,
704         trusted_domains,
705         domain_sid,
706         alternate_name
707 };