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