samr: for correctness, rename samr_RidTypeArray to samr_RidAttrArray.
[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, ("msrpc_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 msrpc_enum_local_groups(struct winbindd_domain *domain,
160                                         TALLOC_CTX *mem_ctx,
161                                         uint32_t *pnum_info,
162                                         struct acct_info **pinfo)
163 {
164         struct rpc_pipe_client *samr_pipe;
165         struct policy_handle dom_pol;
166         struct acct_info *info = NULL;
167         uint32_t num_info = 0;
168         TALLOC_CTX *tmp_ctx;
169         NTSTATUS status;
170
171         DEBUG(3,("msrpc_enum_local_groups\n"));
172
173         if (pnum_info) {
174                 *pnum_info = 0;
175         }
176
177         tmp_ctx = talloc_stackframe();
178         if (tmp_ctx == NULL) {
179                 return NT_STATUS_NO_MEMORY;
180         }
181
182         if ( !winbindd_can_contact_domain( domain ) ) {
183                 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n",
184                           domain->name));
185                 status = NT_STATUS_OK;
186                 goto done;
187         }
188
189         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
190         if (!NT_STATUS_IS_OK(status)) {
191                 goto done;
192         }
193
194         status = rpc_enum_local_groups(mem_ctx,
195                                        samr_pipe,
196                                        &dom_pol,
197                                        &num_info,
198                                        &info);
199         if (!NT_STATUS_IS_OK(status)) {
200                 goto done;
201         }
202
203         if (pnum_info) {
204                 *pnum_info = num_info;
205         }
206
207         if (pinfo) {
208                 *pinfo = talloc_move(mem_ctx, &info);
209         }
210
211 done:
212         TALLOC_FREE(tmp_ctx);
213         return status;
214 }
215
216 /* convert a single name to a sid in a domain */
217 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
218                                   TALLOC_CTX *mem_ctx,
219                                   const char *domain_name,
220                                   const char *name,
221                                   uint32_t flags,
222                                   struct dom_sid *sid,
223                                   enum lsa_SidType *type)
224 {
225         NTSTATUS result;
226         struct dom_sid *sids = NULL;
227         enum lsa_SidType *types = NULL;
228         char *full_name = NULL;
229         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
230         char *mapped_name = NULL;
231
232         if (name == NULL || *name=='\0') {
233                 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
234         } else if (domain_name == NULL || *domain_name == '\0') {
235                 full_name = talloc_asprintf(mem_ctx, "%s", name);
236         } else {
237                 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
238         }
239         if (!full_name) {
240                 DEBUG(0, ("talloc_asprintf failed!\n"));
241                 return NT_STATUS_NO_MEMORY;
242         }
243
244         DEBUG(3, ("msrpc_name_to_sid: name=%s\n", full_name));
245
246         name_map_status = normalize_name_unmap(mem_ctx, full_name,
247                                                &mapped_name);
248
249         /* Reset the full_name pointer if we mapped anytthing */
250
251         if (NT_STATUS_IS_OK(name_map_status) ||
252             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
253         {
254                 full_name = mapped_name;
255         }
256
257         DEBUG(3,("name_to_sid [rpc] %s for domain %s\n",
258                  full_name?full_name:"", domain_name ));
259
260         result = winbindd_lookup_names(mem_ctx, domain, 1,
261                                        (const char **)&full_name, NULL,
262                                        &sids, &types);
263         if (!NT_STATUS_IS_OK(result))
264                 return result;
265
266         /* Return rid and type if lookup successful */
267
268         sid_copy(sid, &sids[0]);
269         *type = types[0];
270
271         return NT_STATUS_OK;
272 }
273
274 /*
275   convert a domain SID to a user or group name
276 */
277 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
278                                   TALLOC_CTX *mem_ctx,
279                                   const struct dom_sid *sid,
280                                   char **domain_name,
281                                   char **name,
282                                   enum lsa_SidType *type)
283 {
284         char **domains;
285         char **names;
286         enum lsa_SidType *types = NULL;
287         NTSTATUS result;
288         NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
289         char *mapped_name = NULL;
290
291         DEBUG(3, ("msrpc_sid_to_name: %s for domain %s\n", sid_string_dbg(sid),
292                  domain->name ));
293
294         result = winbindd_lookup_sids(mem_ctx,
295                                       domain,
296                                       1,
297                                       sid,
298                                       &domains,
299                                       &names,
300                                       &types);
301         if (!NT_STATUS_IS_OK(result)) {
302                 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n",
303                         nt_errstr(result)));
304                 return result;
305         }
306
307
308         *type = (enum lsa_SidType)types[0];
309         *domain_name = domains[0];
310         *name = names[0];
311
312         DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
313
314         name_map_status = normalize_name_map(mem_ctx, domain, *name,
315                                              &mapped_name);
316         if (NT_STATUS_IS_OK(name_map_status) ||
317             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
318         {
319                 *name = mapped_name;
320                 DEBUG(5,("returning mapped name -- %s\n", *name));
321         }
322
323         return NT_STATUS_OK;
324 }
325
326 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
327                                     TALLOC_CTX *mem_ctx,
328                                     const struct dom_sid *sid,
329                                     uint32 *rids,
330                                     size_t num_rids,
331                                     char **domain_name,
332                                     char ***names,
333                                     enum lsa_SidType **types)
334 {
335         char **domains;
336         NTSTATUS result;
337         struct dom_sid *sids;
338         size_t i;
339         char **ret_names;
340
341         DEBUG(3, ("msrpc_rids_to_names: domain %s\n", domain->name ));
342
343         if (num_rids) {
344                 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);
345                 if (sids == NULL) {
346                         return NT_STATUS_NO_MEMORY;
347                 }
348         } else {
349                 sids = NULL;
350         }
351
352         for (i=0; i<num_rids; i++) {
353                 if (!sid_compose(&sids[i], sid, rids[i])) {
354                         return NT_STATUS_INTERNAL_ERROR;
355                 }
356         }
357
358         result = winbindd_lookup_sids(mem_ctx,
359                                       domain,
360                                       num_rids,
361                                       sids,
362                                       &domains,
363                                       names,
364                                       types);
365
366         if (!NT_STATUS_IS_OK(result) &&
367             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
368                 return result;
369         }
370
371         ret_names = *names;
372         for (i=0; i<num_rids; i++) {
373                 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;
374                 char *mapped_name = NULL;
375
376                 if ((*types)[i] != SID_NAME_UNKNOWN) {
377                         name_map_status = normalize_name_map(mem_ctx,
378                                                              domain,
379                                                              ret_names[i],
380                                                              &mapped_name);
381                         if (NT_STATUS_IS_OK(name_map_status) ||
382                             NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))
383                         {
384                                 ret_names[i] = mapped_name;
385                         }
386
387                         *domain_name = domains[i];
388                 }
389         }
390
391         return result;
392 }
393
394 /* Lookup user information from a rid or username. */
395 static NTSTATUS msrpc_query_user(struct winbindd_domain *domain,
396                            TALLOC_CTX *mem_ctx, 
397                            const struct dom_sid *user_sid,
398                            struct wbint_userinfo *user_info)
399 {
400         struct rpc_pipe_client *samr_pipe;
401         struct policy_handle dom_pol;
402         struct netr_SamInfo3 *user;
403         TALLOC_CTX *tmp_ctx;
404         NTSTATUS status;
405
406         DEBUG(3,("msrpc_query_user sid=%s\n", sid_string_dbg(user_sid)));
407
408         tmp_ctx = talloc_stackframe();
409         if (tmp_ctx == NULL) {
410                 return NT_STATUS_NO_MEMORY;
411         }
412
413         if (user_info) {
414                 user_info->homedir = NULL;
415                 user_info->shell = NULL;
416                 user_info->primary_gid = (gid_t)-1;
417         }
418
419         /* try netsamlogon cache first */
420         user = netsamlogon_cache_get(tmp_ctx, user_sid);
421         if (user != NULL) {
422                 DEBUG(5,("msrpc_query_user: Cache lookup succeeded for %s\n",
423                         sid_string_dbg(user_sid)));
424
425                 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
426                 sid_compose(&user_info->group_sid, &domain->sid,
427                             user->base.primary_gid);
428
429                 user_info->acct_name = talloc_strdup(user_info,
430                                                      user->base.account_name.string);
431                 user_info->full_name = talloc_strdup(user_info,
432                                                      user->base.full_name.string);
433
434                 status = NT_STATUS_OK;
435                 goto done;
436         }
437
438         if ( !winbindd_can_contact_domain( domain ) ) {
439                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
440                           domain->name));
441                 /* Tell the cache manager not to remember this one */
442                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
443                 goto done;
444         }
445
446         /* no cache; hit the wire */
447         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
448         if (!NT_STATUS_IS_OK(status)) {
449                 goto done;
450         }
451
452         status = rpc_query_user(tmp_ctx,
453                                 samr_pipe,
454                                 &dom_pol,
455                                 &domain->sid,
456                                 user_sid,
457                                 user_info);
458
459 done:
460         TALLOC_FREE(tmp_ctx);
461         return status;
462 }
463
464 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
465 static NTSTATUS msrpc_lookup_usergroups(struct winbindd_domain *domain,
466                                         TALLOC_CTX *mem_ctx,
467                                         const struct dom_sid *user_sid,
468                                         uint32_t *pnum_groups,
469                                         struct dom_sid **puser_grpsids)
470 {
471         struct rpc_pipe_client *samr_pipe;
472         struct policy_handle dom_pol;
473         struct dom_sid *user_grpsids = NULL;
474         uint32_t num_groups = 0;
475         TALLOC_CTX *tmp_ctx;
476         NTSTATUS status;
477
478         DEBUG(3,("msrpc_lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
479
480         *pnum_groups = 0;
481
482         tmp_ctx = talloc_stackframe();
483         if (tmp_ctx == NULL) {
484                 return NT_STATUS_NO_MEMORY;
485         }
486
487         /* Check if we have a cached user_info_3 */
488         status = lookup_usergroups_cached(domain,
489                                           tmp_ctx,
490                                           user_sid,
491                                           &num_groups,
492                                           &user_grpsids);
493         if (NT_STATUS_IS_OK(status)) {
494                 goto cached;
495         }
496
497         if ( !winbindd_can_contact_domain( domain ) ) {
498                 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
499                           domain->name));
500
501                 /* Tell the cache manager not to remember this one */
502                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
503                 goto done;
504         }
505
506         /* no cache; hit the wire */
507         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
508         if (!NT_STATUS_IS_OK(status)) {
509                 goto done;
510         }
511
512         status = rpc_lookup_usergroups(tmp_ctx,
513                                        samr_pipe,
514                                        &dom_pol,
515                                        &domain->sid,
516                                        user_sid,
517                                        &num_groups,
518                                        &user_grpsids);
519         if (!NT_STATUS_IS_OK(status)) {
520                 goto done;
521         }
522
523 cached:
524         if (pnum_groups) {
525                 *pnum_groups = num_groups;
526         }
527
528         if (puser_grpsids) {
529                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
530         }
531
532 done:
533         TALLOC_FREE(tmp_ctx);
534         return status;
535         return NT_STATUS_OK;
536 }
537
538 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
539
540 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
541                                          TALLOC_CTX *mem_ctx,
542                                          uint32 num_sids, const struct dom_sid *sids,
543                                          uint32 *pnum_aliases,
544                                          uint32 **palias_rids)
545 {
546         struct rpc_pipe_client *samr_pipe;
547         struct policy_handle dom_pol;
548         uint32_t num_aliases = 0;
549         uint32_t *alias_rids = NULL;
550         TALLOC_CTX *tmp_ctx;
551         NTSTATUS status;
552
553         DEBUG(3,("msrpc_lookup_useraliases\n"));
554
555         if (pnum_aliases) {
556                 *pnum_aliases = 0;
557         }
558
559         tmp_ctx = talloc_stackframe();
560         if (tmp_ctx == NULL) {
561                 return NT_STATUS_NO_MEMORY;
562         }
563
564         if (!winbindd_can_contact_domain(domain)) {
565                 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
566                           domain->name));
567                 /* Tell the cache manager not to remember this one */
568                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
569                 goto done;
570         }
571
572         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
573         if (!NT_STATUS_IS_OK(status)) {
574                 goto done;
575         }
576
577         status = rpc_lookup_useraliases(tmp_ctx,
578                                         samr_pipe,
579                                         &dom_pol,
580                                         num_sids,
581                                         sids,
582                                         &num_aliases,
583                                         &alias_rids);
584         if (!NT_STATUS_IS_OK(status)) {
585                 goto done;
586         }
587
588         if (pnum_aliases) {
589                 *pnum_aliases = num_aliases;
590         }
591
592         if (palias_rids) {
593                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
594         }
595
596 done:
597         TALLOC_FREE(tmp_ctx);
598         return status;
599 }
600
601
602 /* Lookup group membership given a rid.   */
603 static NTSTATUS msrpc_lookup_groupmem(struct winbindd_domain *domain,
604                                       TALLOC_CTX *mem_ctx,
605                                       const struct dom_sid *group_sid,
606                                       enum lsa_SidType type,
607                                       uint32_t *num_names,
608                                       struct dom_sid **sid_mem,
609                                       char ***names,
610                                       uint32_t **name_types)
611 {
612         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
613         uint32 i, total_names = 0;
614         struct policy_handle dom_pol, group_pol;
615         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
616         uint32 *rid_mem = NULL;
617         uint32 group_rid;
618         unsigned int j, r;
619         struct rpc_pipe_client *cli;
620         unsigned int orig_timeout;
621         struct samr_RidAttrArray *rids = NULL;
622
623         DEBUG(3,("msrpc_lookup_groupmem: %s sid=%s\n", domain->name,
624                   sid_string_dbg(group_sid)));
625
626         if ( !winbindd_can_contact_domain( domain ) ) {
627                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
628                           domain->name));
629                 return NT_STATUS_OK;
630         }
631
632         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
633                 return NT_STATUS_UNSUCCESSFUL;
634
635         *num_names = 0;
636
637         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
638         if (!NT_STATUS_IS_OK(result))
639                 return result;
640
641         result = rpccli_samr_OpenGroup(cli, mem_ctx,
642                                        &dom_pol,
643                                        des_access,
644                                        group_rid,
645                                        &group_pol);
646
647         if (!NT_STATUS_IS_OK(result))
648                 return result;
649
650         /* Step #1: Get a list of user rids that are the members of the
651            group. */
652
653         /* This call can take a long time - allow the server to time out.
654            35 seconds should do it. */
655
656         orig_timeout = rpccli_set_timeout(cli, 35000);
657
658         result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
659                                               &group_pol,
660                                               &rids);
661
662         /* And restore our original timeout. */
663         rpccli_set_timeout(cli, orig_timeout);
664
665         rpccli_samr_Close(cli, mem_ctx, &group_pol);
666
667         if (!NT_STATUS_IS_OK(result))
668                 return result;
669
670         if (!rids || !rids->count) {
671                 names = NULL;
672                 name_types = NULL;
673                 sid_mem = NULL;
674                 return NT_STATUS_OK;
675         }
676
677         *num_names = rids->count;
678         rid_mem = rids->rids;
679
680         /* Step #2: Convert list of rids into list of usernames.  Do this
681            in bunches of ~1000 to avoid crashing NT4.  It looks like there
682            is a buffer overflow or something like that lurking around
683            somewhere. */
684
685 #define MAX_LOOKUP_RIDS 900
686
687         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
688         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
689         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);
690
691         for (j=0;j<(*num_names);j++)
692                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
693
694         if (*num_names>0 && (!*names || !*name_types))
695                 return NT_STATUS_NO_MEMORY;
696
697         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
698                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
699                 struct lsa_Strings tmp_names;
700                 struct samr_Ids tmp_types;
701
702                 /* Lookup a chunk of rids */
703
704                 result = rpccli_samr_LookupRids(cli, mem_ctx,
705                                                 &dom_pol,
706                                                 num_lookup_rids,
707                                                 &rid_mem[i],
708                                                 &tmp_names,
709                                                 &tmp_types);
710
711                 /* see if we have a real error (and yes the
712                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
713
714                 if (!NT_STATUS_IS_OK(result) &&
715                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
716                         return result;
717
718                 /* Copy result into array.  The talloc system will take
719                    care of freeing the temporary arrays later on. */
720
721                 if (tmp_names.count != tmp_types.count) {
722                         return NT_STATUS_UNSUCCESSFUL;
723                 }
724
725                 for (r=0; r<tmp_names.count; r++) {
726                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
727                                 continue;
728                         }
729                         (*names)[total_names] = fill_domain_username_talloc(
730                                 mem_ctx, domain->name,
731                                 tmp_names.names[r].string, true);
732                         (*name_types)[total_names] = tmp_types.ids[r];
733                         total_names += 1;
734                 }
735         }
736
737         *num_names = total_names;
738
739         return NT_STATUS_OK;
740 }
741
742 #ifdef HAVE_LDAP
743
744 #include <ldap.h>
745
746 static int get_ldap_seq(const char *server, int port, uint32 *seq)
747 {
748         int ret = -1;
749         struct timeval to;
750         const char *attrs[] = {"highestCommittedUSN", NULL};
751         LDAPMessage *res = NULL;
752         char **values = NULL;
753         LDAP *ldp = NULL;
754
755         *seq = DOM_SEQUENCE_NONE;
756
757         /*
758          * Parameterised (5) second timeout on open. This is needed as the
759          * search timeout doesn't seem to apply to doing an open as well. JRA.
760          */
761
762         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
763         if (ldp == NULL)
764                 return -1;
765
766         /* Timeout if no response within 20 seconds. */
767         to.tv_sec = 10;
768         to.tv_usec = 0;
769
770         if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
771                            CONST_DISCARD(char **, attrs), 0, &to, &res))
772                 goto done;
773
774         if (ldap_count_entries(ldp, res) != 1)
775                 goto done;
776
777         values = ldap_get_values(ldp, res, "highestCommittedUSN");
778         if (!values || !values[0])
779                 goto done;
780
781         *seq = atoi(values[0]);
782         ret = 0;
783
784   done:
785
786         if (values)
787                 ldap_value_free(values);
788         if (res)
789                 ldap_msgfree(res);
790         if (ldp)
791                 ldap_unbind(ldp);
792         return ret;
793 }
794
795 /**********************************************************************
796  Get the sequence number for a Windows AD native mode domain using
797  LDAP queries.
798 **********************************************************************/
799
800 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
801 {
802         int ret = -1;
803         char addr[INET6_ADDRSTRLEN];
804
805         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
806         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
807                 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
808                           "number for Domain (%s) from DC (%s)\n",
809                         domain->name, addr));
810         }
811         return ret;
812 }
813
814 #endif /* HAVE_LDAP */
815
816 /* find the sequence number for a domain */
817 static NTSTATUS msrpc_sequence_number(struct winbindd_domain *domain,
818                                       uint32_t *pseq)
819 {
820         struct rpc_pipe_client *samr_pipe;
821         struct policy_handle dom_pol;
822         uint32_t seq;
823         TALLOC_CTX *tmp_ctx;
824         NTSTATUS status;
825
826         DEBUG(3, ("msrpc_sequence_number: fetch sequence_number for %s\n", domain->name));
827
828         if (pseq) {
829                 *pseq = DOM_SEQUENCE_NONE;
830         }
831
832         tmp_ctx = talloc_stackframe();
833         if (tmp_ctx == NULL) {
834                 return NT_STATUS_NO_MEMORY;
835         }
836
837         if ( !winbindd_can_contact_domain( domain ) ) {
838                 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
839                           domain->name));
840                 if (pseq) {
841                         *pseq = time(NULL);
842                 }
843                 status = NT_STATUS_OK;
844                 goto done;
845         }
846
847 #ifdef HAVE_LDAP
848         if (domain->active_directory) {
849                 int rc;
850
851                 DEBUG(8,("using get_ldap_seq() to retrieve the "
852                          "sequence number\n"));
853
854                 rc =  get_ldap_sequence_number(domain, &seq);
855                 if (rc == 0) {
856                         DEBUG(10,("domain_sequence_number: LDAP for "
857                                   "domain %s is %u\n",
858                                   domain->name, seq));
859
860                         if (pseq) {
861                                 *pseq = seq;
862                         }
863
864                         status = NT_STATUS_OK;
865                         goto done;
866                 }
867
868                 DEBUG(10,("domain_sequence_number: failed to get LDAP "
869                           "sequence number for domain %s\n",
870                           domain->name ));
871         }
872 #endif /* HAVE_LDAP */
873
874         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
875         if (!NT_STATUS_IS_OK(status)) {
876                 goto done;
877         }
878
879         status = rpc_sequence_number(tmp_ctx,
880                                      samr_pipe,
881                                      &dom_pol,
882                                      domain->name,
883                                      &seq);
884         if (!NT_STATUS_IS_OK(status)) {
885                 goto done;
886         }
887
888         if (pseq) {
889                 *pseq = seq;
890         }
891
892 done:
893         TALLOC_FREE(tmp_ctx);
894         return status;
895 }
896
897 /* get a list of trusted domains */
898 static NTSTATUS msrpc_trusted_domains(struct winbindd_domain *domain,
899                                       TALLOC_CTX *mem_ctx,
900                                       struct netr_DomainTrustList *ptrust_list)
901 {
902         struct rpc_pipe_client *lsa_pipe;
903         struct policy_handle lsa_policy;
904         struct netr_DomainTrust *trusts = NULL;
905         uint32_t num_trusts = 0;
906         TALLOC_CTX *tmp_ctx;
907         NTSTATUS status;
908
909         DEBUG(3,("msrpc_trusted_domains\n"));
910
911         if (ptrust_list) {
912                 ZERO_STRUCTP(ptrust_list);
913         }
914
915         tmp_ctx = talloc_stackframe();
916         if (tmp_ctx == NULL) {
917                 return NT_STATUS_NO_MEMORY;
918         }
919
920         status = cm_connect_lsa(domain, tmp_ctx, &lsa_pipe, &lsa_policy);
921         if (!NT_STATUS_IS_OK(status))
922                 return status;
923
924         status = rpc_trusted_domains(tmp_ctx,
925                                      lsa_pipe,
926                                      &lsa_policy,
927                                      &num_trusts,
928                                      &trusts);
929         if (!NT_STATUS_IS_OK(status)) {
930                 goto done;
931         }
932
933         if (ptrust_list) {
934                 ptrust_list->count = num_trusts;
935                 ptrust_list->array = talloc_move(mem_ctx, &trusts);
936         }
937
938 done:
939         TALLOC_FREE(tmp_ctx);
940         return status;
941 }
942
943 /* find the lockout policy for a domain */
944 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
945                                      TALLOC_CTX *mem_ctx,
946                                      struct samr_DomInfo12 *lockout_policy)
947 {
948         NTSTATUS result;
949         struct rpc_pipe_client *cli;
950         struct policy_handle dom_pol;
951         union samr_DomainInfo *info = NULL;
952
953         DEBUG(3, ("msrpc_lockout_policy: fetch lockout policy for %s\n", domain->name));
954
955         if ( !winbindd_can_contact_domain( domain ) ) {
956                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
957                           domain->name));
958                 return NT_STATUS_NOT_SUPPORTED;
959         }
960
961         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
962         if (!NT_STATUS_IS_OK(result)) {
963                 goto done;
964         }
965
966         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
967                                              &dom_pol,
968                                              12,
969                                              &info);
970         if (!NT_STATUS_IS_OK(result)) {
971                 goto done;
972         }
973
974         *lockout_policy = info->info12;
975
976         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
977                 info->info12.lockout_threshold));
978
979   done:
980
981         return result;
982 }
983
984 /* find the password policy for a domain */
985 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
986                                       TALLOC_CTX *mem_ctx,
987                                       struct samr_DomInfo1 *password_policy)
988 {
989         NTSTATUS result;
990         struct rpc_pipe_client *cli;
991         struct policy_handle dom_pol;
992         union samr_DomainInfo *info = NULL;
993
994         DEBUG(3, ("msrpc_password_policy: fetch password policy for %s\n",
995                   domain->name));
996
997         if ( !winbindd_can_contact_domain( domain ) ) {
998                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
999                           domain->name));
1000                 return NT_STATUS_NOT_SUPPORTED;
1001         }
1002
1003         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1004         if (!NT_STATUS_IS_OK(result)) {
1005                 goto done;
1006         }
1007
1008         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1009                                              &dom_pol,
1010                                              1,
1011                                              &info);
1012         if (!NT_STATUS_IS_OK(result)) {
1013                 goto done;
1014         }
1015
1016         *password_policy = info->info1;
1017
1018         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1019                 info->info1.min_password_length));
1020
1021   done:
1022
1023         return result;
1024 }
1025
1026 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1027                                      TALLOC_CTX *mem_ctx,
1028                                      struct policy_handle *pol,
1029                                      int num_sids,
1030                                      const struct dom_sid *sids,
1031                                      char ***pdomains,
1032                                      char ***pnames,
1033                                      enum lsa_SidType **ptypes);
1034
1035 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1036                               struct winbindd_domain *domain,
1037                               uint32_t num_sids,
1038                               const struct dom_sid *sids,
1039                               char ***domains,
1040                               char ***names,
1041                               enum lsa_SidType **types)
1042 {
1043         NTSTATUS status;
1044         struct rpc_pipe_client *cli = NULL;
1045         struct policy_handle lsa_policy;
1046         unsigned int orig_timeout;
1047         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1048
1049         if (domain->can_do_ncacn_ip_tcp) {
1050                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1051                 if (NT_STATUS_IS_OK(status)) {
1052                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
1053                         goto lookup;
1054                 }
1055                 domain->can_do_ncacn_ip_tcp = false;
1056         }
1057         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1058
1059         if (!NT_STATUS_IS_OK(status)) {
1060                 return status;
1061         }
1062
1063  lookup:
1064         /*
1065          * This call can take a long time
1066          * allow the server to time out.
1067          * 35 seconds should do it.
1068          */
1069         orig_timeout = rpccli_set_timeout(cli, 35000);
1070
1071         status = lookup_sids_fn(cli,
1072                                 mem_ctx,
1073                                 &lsa_policy,
1074                                 num_sids,
1075                                 sids,
1076                                 domains,
1077                                 names,
1078                                 types);
1079
1080         /* And restore our original timeout. */
1081         rpccli_set_timeout(cli, orig_timeout);
1082
1083         return status;
1084 }
1085
1086 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1087                                       TALLOC_CTX *mem_ctx,
1088                                       struct policy_handle *pol,
1089                                       int num_names,
1090                                       const char **names,
1091                                       const char ***dom_names,
1092                                       int level,
1093                                       struct dom_sid **sids,
1094                                       enum lsa_SidType **types);
1095
1096 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1097                                struct winbindd_domain *domain,
1098                                uint32_t num_names,
1099                                const char **names,
1100                                const char ***domains,
1101                                struct dom_sid **sids,
1102                                enum lsa_SidType **types)
1103 {
1104         NTSTATUS status;
1105         struct rpc_pipe_client *cli = NULL;
1106         struct policy_handle lsa_policy;
1107         unsigned int orig_timeout = 0;
1108         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1109
1110         if (domain->can_do_ncacn_ip_tcp) {
1111                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1112                 if (NT_STATUS_IS_OK(status)) {
1113                         lookup_names_fn = rpccli_lsa_lookup_names4;
1114                         goto lookup;
1115                 }
1116                 domain->can_do_ncacn_ip_tcp = false;
1117         }
1118         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1119
1120         if (!NT_STATUS_IS_OK(status)) {
1121                 return status;
1122         }
1123
1124  lookup:
1125
1126         /*
1127          * This call can take a long time
1128          * allow the server to time out.
1129          * 35 seconds should do it.
1130          */
1131         orig_timeout = rpccli_set_timeout(cli, 35000);
1132
1133         status = lookup_names_fn(cli,
1134                                  mem_ctx,
1135                                  &lsa_policy,
1136                                  num_names,
1137                                  (const char **) names,
1138                                  domains,
1139                                  1,
1140                                  sids,
1141                                  types);
1142
1143         /* And restore our original timeout. */
1144         rpccli_set_timeout(cli, orig_timeout);
1145
1146         if (!NT_STATUS_IS_OK(status)) {
1147                 return status;
1148         }
1149
1150         return status;
1151 }
1152
1153 /* the rpc backend methods are exposed via this structure */
1154 struct winbindd_methods msrpc_methods = {
1155         False,
1156         msrpc_query_user_list,
1157         msrpc_enum_dom_groups,
1158         msrpc_enum_local_groups,
1159         msrpc_name_to_sid,
1160         msrpc_sid_to_name,
1161         msrpc_rids_to_names,
1162         msrpc_query_user,
1163         msrpc_lookup_usergroups,
1164         msrpc_lookup_useraliases,
1165         msrpc_lookup_groupmem,
1166         msrpc_sequence_number,
1167         msrpc_lockout_policy,
1168         msrpc_password_policy,
1169         msrpc_trusted_domains,
1170 };