s3-winbind: Use rpc_query_user_list in msrpc.
[mat/samba.git] / source3 / winbindd / winbindd_msrpc.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    Copyright (C) Volker Lendecke 2005
9    Copyright (C) Guenther Deschner 2008 (pidl conversion)
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "winbindd.h"
27 #include "winbindd_rpc.h"
28
29 #include "../librpc/gen_ndr/cli_samr.h"
30 #include "rpc_client/cli_samr.h"
31 #include "../librpc/gen_ndr/cli_lsa.h"
32 #include "rpc_client/cli_lsarpc.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_WINBIND
36
37
38 /* Query display info for a domain.  This returns enough information plus a
39    bit extra to give an overview of domain users for the User Manager
40    application. */
41 static NTSTATUS msrpc_query_user_list(struct winbindd_domain *domain,
42                                       TALLOC_CTX *mem_ctx,
43                                       uint32_t *pnum_info,
44                                       struct wbint_userinfo **pinfo)
45 {
46         struct rpc_pipe_client *samr_pipe = NULL;
47         struct policy_handle dom_pol;
48         struct wbint_userinfo *info = NULL;
49         uint32_t num_info = 0;
50         TALLOC_CTX *tmp_ctx;
51         NTSTATUS status;
52
53         DEBUG(3,("rpc_query_user_list\n"));
54
55         if (pnum_info) {
56                 *pnum_info = 0;
57         }
58
59         tmp_ctx = talloc_stackframe();
60         if (tmp_ctx == NULL) {
61                 return NT_STATUS_NO_MEMORY;
62         }
63
64         if ( !winbindd_can_contact_domain( domain ) ) {
65                 DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
66                           domain->name));
67                 status = NT_STATUS_OK;
68                 goto done;
69         }
70
71         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
72         if (!NT_STATUS_IS_OK(status)) {
73                 goto done;
74         }
75
76         status = rpc_query_user_list(tmp_ctx,
77                                      samr_pipe,
78                                      &dom_pol,
79                                      &domain->sid,
80                                      &num_info,
81                                      &info);
82         if (!NT_STATUS_IS_OK(status)) {
83                 goto done;
84         }
85
86         if (pnum_info) {
87                 *pnum_info = num_info;
88         }
89
90         if (pinfo) {
91                 *pinfo = talloc_move(mem_ctx, &info);
92         }
93
94 done:
95         TALLOC_FREE(tmp_ctx);
96         return status;
97 }
98
99 /* list all domain groups */
100 static NTSTATUS msrpc_enum_dom_groups(struct winbindd_domain *domain,
101                                       TALLOC_CTX *mem_ctx,
102                                       uint32_t *pnum_info,
103                                       struct acct_info **pinfo)
104 {
105         struct rpc_pipe_client *samr_pipe;
106         struct policy_handle dom_pol;
107         struct acct_info *info = NULL;
108         uint32_t num_info = 0;
109         TALLOC_CTX *tmp_ctx;
110         NTSTATUS status;
111
112         DEBUG(3,("msrpc_enum_dom_groups\n"));
113
114         if (pnum_info) {
115                 *pnum_info = 0;
116         }
117
118         tmp_ctx = talloc_stackframe();
119         if (tmp_ctx == NULL) {
120                 return NT_STATUS_NO_MEMORY;
121         }
122
123         if ( !winbindd_can_contact_domain( domain ) ) {
124                 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n",
125                           domain->name));
126                 status = NT_STATUS_OK;
127                 goto done;
128         }
129
130         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
131         if (!NT_STATUS_IS_OK(status)) {
132                 goto done;
133         }
134
135         status = rpc_enum_dom_groups(tmp_ctx,
136                                      samr_pipe,
137                                      &dom_pol,
138                                      &num_info,
139                                      &info);
140         if (!NT_STATUS_IS_OK(status)) {
141                 goto done;
142         }
143
144         if (pnum_info) {
145                 *pnum_info = num_info;
146         }
147
148         if (pinfo) {
149                 *pinfo = talloc_move(mem_ctx, &info);
150         }
151
152 done:
153         TALLOC_FREE(tmp_ctx);
154         return status;
155 }
156
157 /* List all domain groups */
158
159 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
160                                 TALLOC_CTX *mem_ctx,
161                                 uint32 *num_entries, 
162                                 struct acct_info **info)
163 {
164         struct policy_handle dom_pol;
165         NTSTATUS result;
166         struct rpc_pipe_client *cli;
167
168         *num_entries = 0;
169         *info = NULL;
170
171         DEBUG(3,("rpc: enum_local_groups\n"));
172
173         if ( !winbindd_can_contact_domain( domain ) ) {
174                 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
175                           domain->name));
176                 return NT_STATUS_OK;
177         }
178
179         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
180         if (!NT_STATUS_IS_OK(result))
181                 return result;
182
183         do {
184                 struct samr_SamArray *sam_array = NULL;
185                 uint32 count = 0, start = *num_entries;
186                 TALLOC_CTX *mem_ctx2;
187                 int g;
188
189                 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
190
191                 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
192                                                        &dom_pol,
193                                                        &start,
194                                                        &sam_array,
195                                                        0xFFFF, /* buffer size? */
196                                                        &count);
197                 if (!NT_STATUS_IS_OK(result) &&
198                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
199                 {
200                         talloc_destroy(mem_ctx2);
201                         return result;
202                 }
203
204                 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
205                                                struct acct_info,
206                                                (*num_entries) + count);
207                 if (! *info) {
208                         talloc_destroy(mem_ctx2);
209                         return NT_STATUS_NO_MEMORY;
210                 }
211
212                 for (g=0; g < count; g++) {
213
214                         fstrcpy((*info)[*num_entries + g].acct_name,
215                                 sam_array->entries[g].name.string);
216                         (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
217                 }
218
219                 (*num_entries) += count;
220                 talloc_destroy(mem_ctx2);
221
222         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
223
224         return result;
225 }
226
227 /* convert a single name to a sid in a domain */
228 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
229                                   TALLOC_CTX *mem_ctx,
230                                   const char *domain_name,
231                                   const char *name,
232                                   uint32_t flags,
233                                   struct dom_sid *sid,
234                                   enum lsa_SidType *type)
235 {
236         NTSTATUS result;
237         struct dom_sid *sids = NULL;
238         enum lsa_SidType *types = NULL;
239         char *full_name = NULL;
240         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
241         char *mapped_name = NULL;
242
243         if (name == NULL || *name=='\0') {
244                 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
245         } else if (domain_name == NULL || *domain_name == '\0') {
246                 full_name = talloc_asprintf(mem_ctx, "%s", name);
247         } else {
248                 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
249         }
250         if (!full_name) {
251                 DEBUG(0, ("talloc_asprintf failed!\n"));
252                 return NT_STATUS_NO_MEMORY;
253         }
254
255         DEBUG(3,("rpc: name_to_sid name=%s\n", full_name));
256
257         name_map_status = normalize_name_unmap(mem_ctx, full_name,
258                                                &mapped_name);
259
260         /* Reset the full_name pointer if we mapped anytthing */
261
262         if (NT_STATUS_IS_OK(name_map_status) ||
263             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
264         {
265                 full_name = mapped_name;
266         }
267
268         DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
269                  full_name?full_name:"", domain_name ));
270
271         result = winbindd_lookup_names(mem_ctx, domain, 1,
272                                        (const char **)&full_name, NULL,
273                                        &sids, &types);
274         if (!NT_STATUS_IS_OK(result))
275                 return result;
276
277         /* Return rid and type if lookup successful */
278
279         sid_copy(sid, &sids[0]);
280         *type = types[0];
281
282         return NT_STATUS_OK;
283 }
284
285 /*
286   convert a domain SID to a user or group name
287 */
288 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
289                                   TALLOC_CTX *mem_ctx,
290                                   const struct dom_sid *sid,
291                                   char **domain_name,
292                                   char **name,
293                                   enum lsa_SidType *type)
294 {
295         char **domains;
296         char **names;
297         enum lsa_SidType *types = NULL;
298         NTSTATUS result;
299         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
300         char *mapped_name = NULL;
301
302         DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid),
303                  domain->name ));
304
305         result = winbindd_lookup_sids(mem_ctx,
306                                       domain,
307                                       1,
308                                       sid,
309                                       &domains,
310                                       &names,
311                                       &types);
312         if (!NT_STATUS_IS_OK(result)) {
313                 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
314                         nt_errstr(result)));
315                 return result;
316         }
317
318
319         *type = (enum lsa_SidType)types[0];
320         *domain_name = domains[0];
321         *name = names[0];
322
323         DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
324
325         name_map_status = normalize_name_map(mem_ctx, domain, *name,
326                                              &mapped_name);
327         if (NT_STATUS_IS_OK(name_map_status) ||
328             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
329         {
330                 *name = mapped_name;
331                 DEBUG(5,("returning mapped name -- %s\n", *name));
332         }
333
334         return NT_STATUS_OK;
335 }
336
337 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
338                                     TALLOC_CTX *mem_ctx,
339                                     const struct dom_sid *sid,
340                                     uint32 *rids,
341                                     size_t num_rids,
342                                     char **domain_name,
343                                     char ***names,
344                                     enum lsa_SidType **types)
345 {
346         char **domains;
347         NTSTATUS result;
348         struct dom_sid *sids;
349         size_t i;
350         char **ret_names;
351
352         DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
353
354         if (num_rids) {
355                 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
356                 if (sids == NULL) {
357                         return NT_STATUS_NO_MEMORY;
358                 }
359         } else {
360                 sids = NULL;
361         }
362
363         for (i=0; i<num_rids; i++) {
364                 if (!sid_compose(&sids[i], sid, rids[i])) {
365                         return NT_STATUS_INTERNAL_ERROR;
366                 }
367         }
368
369         result = winbindd_lookup_sids(mem_ctx,
370                                       domain,
371                                       num_rids,
372                                       sids,
373                                       &domains,
374                                       names,
375                                       types);
376
377         if (!NT_STATUS_IS_OK(result) &&
378             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
379                 return result;
380         }
381
382         ret_names = *names;
383         for (i=0; i<num_rids; i++) {
384                 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
385                 char *mapped_name = NULL;
386
387                 if ((*types)[i] != SID_NAME_UNKNOWN) {
388                         name_map_status = normalize_name_map(mem_ctx,
389                                                              domain,
390                                                              ret_names[i],
391                                                              &mapped_name);
392                         if (NT_STATUS_IS_OK(name_map_status) ||
393                             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
394                         {
395                                 ret_names[i] = mapped_name;
396                         }
397
398                         *domain_name = domains[i];
399                 }
400         }
401
402         return result;
403 }
404
405 /* Lookup user information from a rid or username. */
406 static NTSTATUS query_user(struct winbindd_domain *domain, 
407                            TALLOC_CTX *mem_ctx, 
408                            const struct dom_sid *user_sid,
409                            struct wbint_userinfo *user_info)
410 {
411         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
412         struct policy_handle dom_pol, user_pol;
413         union samr_UserInfo *info = NULL;
414         uint32 user_rid;
415         struct netr_SamInfo3 *user;
416         struct rpc_pipe_client *cli;
417
418         DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
419
420         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
421                 return NT_STATUS_UNSUCCESSFUL;
422
423         user_info->homedir = NULL;
424         user_info->shell = NULL;
425         user_info->primary_gid = (gid_t)-1;
426
427         /* try netsamlogon cache first */
428
429         if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) 
430         {
431
432                 DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 
433                         sid_string_dbg(user_sid)));
434
435                 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
436                 sid_compose(&user_info->group_sid, &domain->sid,
437                             user->base.primary_gid);
438
439                 user_info->acct_name = talloc_strdup(mem_ctx,
440                                                      user->base.account_name.string);
441                 user_info->full_name = talloc_strdup(mem_ctx,
442                                                      user->base.full_name.string);
443
444                 TALLOC_FREE(user);
445
446                 return NT_STATUS_OK;
447         }
448
449         if ( !winbindd_can_contact_domain( domain ) ) {
450                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
451                           domain->name));
452                 return NT_STATUS_OK;
453         }
454
455         /* no cache; hit the wire */
456
457         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
458         if (!NT_STATUS_IS_OK(result))
459                 return result;
460
461         /* Get user handle */
462         result = rpccli_samr_OpenUser(cli, mem_ctx,
463                                       &dom_pol,
464                                       SEC_FLAG_MAXIMUM_ALLOWED,
465                                       user_rid,
466                                       &user_pol);
467
468         if (!NT_STATUS_IS_OK(result))
469                 return result;
470
471         /* Get user info */
472         result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
473                                            &user_pol,
474                                            0x15,
475                                            &info);
476
477         rpccli_samr_Close(cli, mem_ctx, &user_pol);
478
479         if (!NT_STATUS_IS_OK(result))
480                 return result;
481
482         sid_compose(&user_info->user_sid, &domain->sid, user_rid);
483         sid_compose(&user_info->group_sid, &domain->sid,
484                     info->info21.primary_gid);
485         user_info->acct_name = talloc_strdup(mem_ctx,
486                                              info->info21.account_name.string);
487         user_info->full_name = talloc_strdup(mem_ctx,
488                                              info->info21.full_name.string);
489         user_info->homedir = NULL;
490         user_info->shell = NULL;
491         user_info->primary_gid = (gid_t)-1;
492
493         return NT_STATUS_OK;
494 }                                   
495
496 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
497 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
498                                   TALLOC_CTX *mem_ctx,
499                                   const struct dom_sid *user_sid,
500                                   uint32 *num_groups, struct dom_sid **user_grpsids)
501 {
502         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
503         struct policy_handle dom_pol, user_pol;
504         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
505         struct samr_RidWithAttributeArray *rid_array = NULL;
506         unsigned int i;
507         uint32 user_rid;
508         struct rpc_pipe_client *cli;
509
510         DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
511
512         if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
513                 return NT_STATUS_UNSUCCESSFUL;
514
515         *num_groups = 0;
516         *user_grpsids = NULL;
517
518         /* so lets see if we have a cached user_info_3 */
519         result = lookup_usergroups_cached(domain, mem_ctx, user_sid, 
520                                           num_groups, user_grpsids);
521
522         if (NT_STATUS_IS_OK(result)) {
523                 return NT_STATUS_OK;
524         }
525
526         if ( !winbindd_can_contact_domain( domain ) ) {
527                 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
528                           domain->name));
529
530                 /* Tell the cache manager not to remember this one */
531
532                 return NT_STATUS_SYNCHRONIZATION_REQUIRED;
533         }
534
535         /* no cache; hit the wire */
536
537         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
538         if (!NT_STATUS_IS_OK(result))
539                 return result;
540
541         /* Get user handle */
542         result = rpccli_samr_OpenUser(cli, mem_ctx,
543                                       &dom_pol,
544                                       des_access,
545                                       user_rid,
546                                       &user_pol);
547
548         if (!NT_STATUS_IS_OK(result))
549                 return result;
550
551         /* Query user rids */
552         result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
553                                               &user_pol,
554                                               &rid_array);
555         *num_groups = rid_array->count;
556
557         rpccli_samr_Close(cli, mem_ctx, &user_pol);
558
559         if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
560                 return result;
561
562         (*user_grpsids) = TALLOC_ARRAY(mem_ctx, struct dom_sid, *num_groups);
563         if (!(*user_grpsids))
564                 return NT_STATUS_NO_MEMORY;
565
566         for (i=0;i<(*num_groups);i++) {
567                 sid_compose(&((*user_grpsids)[i]), &domain->sid,
568                             rid_array->rids[i].rid);
569         }
570
571         return NT_STATUS_OK;
572 }
573
574 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
575
576 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
577                                          TALLOC_CTX *mem_ctx,
578                                          uint32 num_sids, const struct dom_sid *sids,
579                                          uint32 *num_aliases,
580                                          uint32 **alias_rids)
581 {
582         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
583         struct policy_handle dom_pol;
584         uint32 num_query_sids = 0;
585         int i;
586         struct rpc_pipe_client *cli;
587         struct samr_Ids alias_rids_query;
588         int rangesize = MAX_SAM_ENTRIES_W2K;
589         uint32 total_sids = 0;
590         int num_queries = 1;
591
592         *num_aliases = 0;
593         *alias_rids = NULL;
594
595         DEBUG(3,("rpc: lookup_useraliases\n"));
596
597         if ( !winbindd_can_contact_domain( domain ) ) {
598                 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
599                           domain->name));
600                 return NT_STATUS_OK;
601         }
602
603         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
604         if (!NT_STATUS_IS_OK(result))
605                 return result;
606
607         do {
608                 /* prepare query */
609                 struct lsa_SidArray sid_array;
610
611                 ZERO_STRUCT(sid_array);
612
613                 num_query_sids = MIN(num_sids - total_sids, rangesize);
614
615                 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 
616                         num_queries, num_query_sids));  
617
618                 if (num_query_sids) {
619                         sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
620                         if (sid_array.sids == NULL) {
621                                 return NT_STATUS_NO_MEMORY;
622                         }
623                 } else {
624                         sid_array.sids = NULL;
625                 }
626
627                 for (i=0; i<num_query_sids; i++) {
628                         sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
629                         if (!sid_array.sids[i].sid) {
630                                 TALLOC_FREE(sid_array.sids);
631                                 return NT_STATUS_NO_MEMORY;
632                         }
633                 }
634                 sid_array.num_sids = num_query_sids;
635
636                 /* do request */
637                 result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
638                                                         &dom_pol,
639                                                         &sid_array,
640                                                         &alias_rids_query);
641
642                 if (!NT_STATUS_IS_OK(result)) {
643                         *num_aliases = 0;
644                         *alias_rids = NULL;
645                         TALLOC_FREE(sid_array.sids);
646                         goto done;
647                 }
648
649                 /* process output */
650
651                 for (i=0; i<alias_rids_query.count; i++) {
652                         size_t na = *num_aliases;
653                         if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
654                                                 alias_rids, &na)) {
655                                 return NT_STATUS_NO_MEMORY;
656                         }
657                         *num_aliases = na;
658                 }
659
660                 TALLOC_FREE(sid_array.sids);
661
662                 num_queries++;
663
664         } while (total_sids < num_sids);
665
666  done:
667         DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
668                 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
669
670         return result;
671 }
672
673
674 /* Lookup group membership given a rid.   */
675 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
676                                 TALLOC_CTX *mem_ctx,
677                                 const struct dom_sid *group_sid,
678                                 enum lsa_SidType type,
679                                 uint32 *num_names,
680                                 struct dom_sid **sid_mem, char ***names,
681                                 uint32 **name_types)
682 {
683         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
684         uint32 i, total_names = 0;
685         struct policy_handle dom_pol, group_pol;
686         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
687         uint32 *rid_mem = NULL;
688         uint32 group_rid;
689         unsigned int j, r;
690         struct rpc_pipe_client *cli;
691         unsigned int orig_timeout;
692         struct samr_RidTypeArray *rids = NULL;
693
694         DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
695                   sid_string_dbg(group_sid)));
696
697         if ( !winbindd_can_contact_domain( domain ) ) {
698                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
699                           domain->name));
700                 return NT_STATUS_OK;
701         }
702
703         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
704                 return NT_STATUS_UNSUCCESSFUL;
705
706         *num_names = 0;
707
708         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
709         if (!NT_STATUS_IS_OK(result))
710                 return result;
711
712         result = rpccli_samr_OpenGroup(cli, mem_ctx,
713                                        &dom_pol,
714                                        des_access,
715                                        group_rid,
716                                        &group_pol);
717
718         if (!NT_STATUS_IS_OK(result))
719                 return result;
720
721         /* Step #1: Get a list of user rids that are the members of the
722            group. */
723
724         /* This call can take a long time - allow the server to time out.
725            35 seconds should do it. */
726
727         orig_timeout = rpccli_set_timeout(cli, 35000);
728
729         result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
730                                               &group_pol,
731                                               &rids);
732
733         /* And restore our original timeout. */
734         rpccli_set_timeout(cli, orig_timeout);
735
736         rpccli_samr_Close(cli, mem_ctx, &group_pol);
737
738         if (!NT_STATUS_IS_OK(result))
739                 return result;
740
741         if (!rids || !rids->count) {
742                 names = NULL;
743                 name_types = NULL;
744                 sid_mem = NULL;
745                 return NT_STATUS_OK;
746         }
747
748         *num_names = rids->count;
749         rid_mem = rids->rids;
750
751         /* Step #2: Convert list of rids into list of usernames.  Do this
752            in bunches of ~1000 to avoid crashing NT4.  It looks like there
753            is a buffer overflow or something like that lurking around
754            somewhere. */
755
756 #define MAX_LOOKUP_RIDS 900
757
758         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
759         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
760         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);
761
762         for (j=0;j<(*num_names);j++)
763                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
764
765         if (*num_names>0 && (!*names || !*name_types))
766                 return NT_STATUS_NO_MEMORY;
767
768         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
769                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
770                 struct lsa_Strings tmp_names;
771                 struct samr_Ids tmp_types;
772
773                 /* Lookup a chunk of rids */
774
775                 result = rpccli_samr_LookupRids(cli, mem_ctx,
776                                                 &dom_pol,
777                                                 num_lookup_rids,
778                                                 &rid_mem[i],
779                                                 &tmp_names,
780                                                 &tmp_types);
781
782                 /* see if we have a real error (and yes the
783                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
784
785                 if (!NT_STATUS_IS_OK(result) &&
786                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
787                         return result;
788
789                 /* Copy result into array.  The talloc system will take
790                    care of freeing the temporary arrays later on. */
791
792                 if (tmp_names.count != tmp_types.count) {
793                         return NT_STATUS_UNSUCCESSFUL;
794                 }
795
796                 for (r=0; r<tmp_names.count; r++) {
797                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
798                                 continue;
799                         }
800                         (*names)[total_names] = fill_domain_username_talloc(
801                                 mem_ctx, domain->name,
802                                 tmp_names.names[r].string, true);
803                         (*name_types)[total_names] = tmp_types.ids[r];
804                         total_names += 1;
805                 }
806         }
807
808         *num_names = total_names;
809
810         return NT_STATUS_OK;
811 }
812
813 #ifdef HAVE_LDAP
814
815 #include <ldap.h>
816
817 static int get_ldap_seq(const char *server, int port, uint32 *seq)
818 {
819         int ret = -1;
820         struct timeval to;
821         const char *attrs[] = {"highestCommittedUSN", NULL};
822         LDAPMessage *res = NULL;
823         char **values = NULL;
824         LDAP *ldp = NULL;
825
826         *seq = DOM_SEQUENCE_NONE;
827
828         /*
829          * Parameterised (5) second timeout on open. This is needed as the
830          * search timeout doesn't seem to apply to doing an open as well. JRA.
831          */
832
833         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
834         if (ldp == NULL)
835                 return -1;
836
837         /* Timeout if no response within 20 seconds. */
838         to.tv_sec = 10;
839         to.tv_usec = 0;
840
841         if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
842                            CONST_DISCARD(char **, attrs), 0, &to, &res))
843                 goto done;
844
845         if (ldap_count_entries(ldp, res) != 1)
846                 goto done;
847
848         values = ldap_get_values(ldp, res, "highestCommittedUSN");
849         if (!values || !values[0])
850                 goto done;
851
852         *seq = atoi(values[0]);
853         ret = 0;
854
855   done:
856
857         if (values)
858                 ldap_value_free(values);
859         if (res)
860                 ldap_msgfree(res);
861         if (ldp)
862                 ldap_unbind(ldp);
863         return ret;
864 }
865
866 /**********************************************************************
867  Get the sequence number for a Windows AD native mode domain using
868  LDAP queries.
869 **********************************************************************/
870
871 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
872 {
873         int ret = -1;
874         char addr[INET6_ADDRSTRLEN];
875
876         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
877         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
878                 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
879                           "number for Domain (%s) from DC (%s)\n",
880                         domain->name, addr));
881         }
882         return ret;
883 }
884
885 #endif /* HAVE_LDAP */
886
887 /* find the sequence number for a domain */
888 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
889 {
890         TALLOC_CTX *mem_ctx;
891         union samr_DomainInfo *info = NULL;
892         NTSTATUS result;
893         struct policy_handle dom_pol;
894         bool got_seq_num = False;
895         struct rpc_pipe_client *cli;
896
897         DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
898
899         if ( !winbindd_can_contact_domain( domain ) ) {
900                 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
901                           domain->name));
902                 *seq = time(NULL);
903                 return NT_STATUS_OK;
904         }
905
906         *seq = DOM_SEQUENCE_NONE;
907
908         if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
909                 return NT_STATUS_NO_MEMORY;
910
911 #ifdef HAVE_LDAP
912         if ( domain->active_directory ) 
913         {
914                 int res;
915
916                 DEBUG(8,("using get_ldap_seq() to retrieve the "
917                          "sequence number\n"));
918
919                 res =  get_ldap_sequence_number( domain, seq );
920                 if (res == 0)
921                 {                       
922                         result = NT_STATUS_OK;
923                         DEBUG(10,("domain_sequence_number: LDAP for "
924                                   "domain %s is %u\n",
925                                   domain->name, *seq));
926                         goto done;
927                 }
928
929                 DEBUG(10,("domain_sequence_number: failed to get LDAP "
930                           "sequence number for domain %s\n",
931                           domain->name ));
932         }
933 #endif /* HAVE_LDAP */
934
935         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
936         if (!NT_STATUS_IS_OK(result)) {
937                 goto done;
938         }
939
940         /* Query domain info */
941
942         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
943                                              &dom_pol,
944                                              8,
945                                              &info);
946
947         if (NT_STATUS_IS_OK(result)) {
948                 *seq = info->info8.sequence_num;
949                 got_seq_num = True;
950                 goto seq_num;
951         }
952
953         /* retry with info-level 2 in case the dc does not support info-level 8
954          * (like all older samba2 and samba3 dc's) - Guenther */
955
956         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
957                                              &dom_pol,
958                                              2,
959                                              &info);
960
961         if (NT_STATUS_IS_OK(result)) {
962                 *seq = info->general.sequence_num;
963                 got_seq_num = True;
964         }
965
966  seq_num:
967         if (got_seq_num) {
968                 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
969                           domain->name, (unsigned)*seq));
970         } else {
971                 DEBUG(10,("domain_sequence_number: failed to get sequence "
972                           "number (%u) for domain %s\n",
973                           (unsigned)*seq, domain->name ));
974         }
975
976   done:
977
978         talloc_destroy(mem_ctx);
979
980         return result;
981 }
982
983 /* get a list of trusted domains */
984 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
985                                 TALLOC_CTX *mem_ctx,
986                                 struct netr_DomainTrustList *trusts)
987 {
988         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
989         uint32 enum_ctx = 0;
990         struct rpc_pipe_client *cli;
991         struct policy_handle lsa_policy;
992
993         DEBUG(3,("rpc: trusted_domains\n"));
994
995         ZERO_STRUCTP(trusts);
996
997         result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
998         if (!NT_STATUS_IS_OK(result))
999                 return result;
1000
1001         result = STATUS_MORE_ENTRIES;
1002
1003         while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
1004                 uint32 start_idx;
1005                 int i;
1006                 struct lsa_DomainList dom_list;
1007
1008                 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
1009                                                  &lsa_policy,
1010                                                  &enum_ctx,
1011                                                  &dom_list,
1012                                                  (uint32_t)-1);
1013
1014                 if (!NT_STATUS_IS_OK(result) &&
1015                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
1016                         break;
1017
1018                 start_idx = trusts->count;
1019                 trusts->count += dom_list.count;
1020
1021                 trusts->array = talloc_realloc(
1022                         mem_ctx, trusts->array, struct netr_DomainTrust,
1023                         trusts->count);
1024                 if (trusts->array == NULL) {
1025                         return NT_STATUS_NO_MEMORY;
1026                 }
1027
1028                 for (i=0; i<dom_list.count; i++) {
1029                         struct netr_DomainTrust *trust = &trusts->array[i];
1030                         struct dom_sid *sid;
1031
1032                         ZERO_STRUCTP(trust);
1033
1034                         trust->netbios_name = talloc_move(
1035                                 trusts->array,
1036                                 &dom_list.domains[i].name.string);
1037                         trust->dns_name = NULL;
1038
1039                         sid = talloc(trusts->array, struct dom_sid);
1040                         if (sid == NULL) {
1041                                 return NT_STATUS_NO_MEMORY;
1042                         }
1043                         sid_copy(sid, dom_list.domains[i].sid);
1044                         trust->sid = sid;
1045                 }
1046         }
1047         return result;
1048 }
1049
1050 /* find the lockout policy for a domain */
1051 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
1052                                      TALLOC_CTX *mem_ctx,
1053                                      struct samr_DomInfo12 *lockout_policy)
1054 {
1055         NTSTATUS result;
1056         struct rpc_pipe_client *cli;
1057         struct policy_handle dom_pol;
1058         union samr_DomainInfo *info = NULL;
1059
1060         DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
1061
1062         if ( !winbindd_can_contact_domain( domain ) ) {
1063                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
1064                           domain->name));
1065                 return NT_STATUS_NOT_SUPPORTED;
1066         }
1067
1068         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1069         if (!NT_STATUS_IS_OK(result)) {
1070                 goto done;
1071         }
1072
1073         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1074                                              &dom_pol,
1075                                              12,
1076                                              &info);
1077         if (!NT_STATUS_IS_OK(result)) {
1078                 goto done;
1079         }
1080
1081         *lockout_policy = info->info12;
1082
1083         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1084                 info->info12.lockout_threshold));
1085
1086   done:
1087
1088         return result;
1089 }
1090
1091 /* find the password policy for a domain */
1092 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1093                                       TALLOC_CTX *mem_ctx,
1094                                       struct samr_DomInfo1 *password_policy)
1095 {
1096         NTSTATUS result;
1097         struct rpc_pipe_client *cli;
1098         struct policy_handle dom_pol;
1099         union samr_DomainInfo *info = NULL;
1100
1101         DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
1102
1103         if ( !winbindd_can_contact_domain( domain ) ) {
1104                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1105                           domain->name));
1106                 return NT_STATUS_NOT_SUPPORTED;
1107         }
1108
1109         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1110         if (!NT_STATUS_IS_OK(result)) {
1111                 goto done;
1112         }
1113
1114         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1115                                              &dom_pol,
1116                                              1,
1117                                              &info);
1118         if (!NT_STATUS_IS_OK(result)) {
1119                 goto done;
1120         }
1121
1122         *password_policy = info->info1;
1123
1124         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1125                 info->info1.min_password_length));
1126
1127   done:
1128
1129         return result;
1130 }
1131
1132 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1133                                      TALLOC_CTX *mem_ctx,
1134                                      struct policy_handle *pol,
1135                                      int num_sids,
1136                                      const struct dom_sid *sids,
1137                                      char ***pdomains,
1138                                      char ***pnames,
1139                                      enum lsa_SidType **ptypes);
1140
1141 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1142                               struct winbindd_domain *domain,
1143                               uint32_t num_sids,
1144                               const struct dom_sid *sids,
1145                               char ***domains,
1146                               char ***names,
1147                               enum lsa_SidType **types)
1148 {
1149         NTSTATUS status;
1150         struct rpc_pipe_client *cli = NULL;
1151         struct policy_handle lsa_policy;
1152         unsigned int orig_timeout;
1153         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1154
1155         if (domain->can_do_ncacn_ip_tcp) {
1156                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1157                 if (NT_STATUS_IS_OK(status)) {
1158                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
1159                         goto lookup;
1160                 }
1161                 domain->can_do_ncacn_ip_tcp = false;
1162         }
1163         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1164
1165         if (!NT_STATUS_IS_OK(status)) {
1166                 return status;
1167         }
1168
1169  lookup:
1170         /*
1171          * This call can take a long time
1172          * allow the server to time out.
1173          * 35 seconds should do it.
1174          */
1175         orig_timeout = rpccli_set_timeout(cli, 35000);
1176
1177         status = lookup_sids_fn(cli,
1178                                 mem_ctx,
1179                                 &lsa_policy,
1180                                 num_sids,
1181                                 sids,
1182                                 domains,
1183                                 names,
1184                                 types);
1185
1186         /* And restore our original timeout. */
1187         rpccli_set_timeout(cli, orig_timeout);
1188
1189         if (!NT_STATUS_IS_OK(status)) {
1190                 return status;
1191         }
1192
1193         return status;
1194 }
1195
1196 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1197                                       TALLOC_CTX *mem_ctx,
1198                                       struct policy_handle *pol,
1199                                       int num_names,
1200                                       const char **names,
1201                                       const char ***dom_names,
1202                                       int level,
1203                                       struct dom_sid **sids,
1204                                       enum lsa_SidType **types);
1205
1206 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1207                                struct winbindd_domain *domain,
1208                                uint32_t num_names,
1209                                const char **names,
1210                                const char ***domains,
1211                                struct dom_sid **sids,
1212                                enum lsa_SidType **types)
1213 {
1214         NTSTATUS status;
1215         struct rpc_pipe_client *cli = NULL;
1216         struct policy_handle lsa_policy;
1217         unsigned int orig_timeout = 0;
1218         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1219
1220         if (domain->can_do_ncacn_ip_tcp) {
1221                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1222                 if (NT_STATUS_IS_OK(status)) {
1223                         lookup_names_fn = rpccli_lsa_lookup_names4;
1224                         goto lookup;
1225                 }
1226                 domain->can_do_ncacn_ip_tcp = false;
1227         }
1228         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1229
1230         if (!NT_STATUS_IS_OK(status)) {
1231                 return status;
1232         }
1233
1234  lookup:
1235
1236         /*
1237          * This call can take a long time
1238          * allow the server to time out.
1239          * 35 seconds should do it.
1240          */
1241         orig_timeout = rpccli_set_timeout(cli, 35000);
1242
1243         status = lookup_names_fn(cli,
1244                                  mem_ctx,
1245                                  &lsa_policy,
1246                                  num_names,
1247                                  (const char **) names,
1248                                  domains,
1249                                  1,
1250                                  sids,
1251                                  types);
1252
1253         /* And restore our original timeout. */
1254         rpccli_set_timeout(cli, orig_timeout);
1255
1256         if (!NT_STATUS_IS_OK(status)) {
1257                 return status;
1258         }
1259
1260         return status;
1261 }
1262
1263 /* the rpc backend methods are exposed via this structure */
1264 struct winbindd_methods msrpc_methods = {
1265         False,
1266         msrpc_query_user_list,
1267         msrpc_enum_dom_groups,
1268         enum_local_groups,
1269         msrpc_name_to_sid,
1270         msrpc_sid_to_name,
1271         msrpc_rids_to_names,
1272         query_user,
1273         lookup_usergroups,
1274         msrpc_lookup_useraliases,
1275         lookup_groupmem,
1276         sequence_number,
1277         msrpc_lockout_policy,
1278         msrpc_password_policy,
1279         trusted_domains,
1280 };