s3:winbindd: catch lookup_names/sids schannel errors over ncacn_ip_tcp (bug #7944)
[idra/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/ndr_samr_c.h"
30 #include "rpc_client/cli_samr.h"
31 #include "rpc_client/cli_lsarpc.h"
32 #include "../libcli/security/security.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 status, result;
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         struct dcerpc_binding_handle *b;
623
624         DEBUG(3,("msrpc_lookup_groupmem: %s sid=%s\n", domain->name,
625                   sid_string_dbg(group_sid)));
626
627         if ( !winbindd_can_contact_domain( domain ) ) {
628                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
629                           domain->name));
630                 return NT_STATUS_OK;
631         }
632
633         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
634                 return NT_STATUS_UNSUCCESSFUL;
635
636         *num_names = 0;
637
638         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
639         if (!NT_STATUS_IS_OK(result))
640                 return result;
641
642         b = cli->binding_handle;
643
644         status = dcerpc_samr_OpenGroup(b, mem_ctx,
645                                        &dom_pol,
646                                        des_access,
647                                        group_rid,
648                                        &group_pol,
649                                        &result);
650         if (!NT_STATUS_IS_OK(status)) {
651                 return status;
652         }
653         if (!NT_STATUS_IS_OK(result)) {
654                 return result;
655         }
656
657         /* Step #1: Get a list of user rids that are the members of the
658            group. */
659
660         /* This call can take a long time - allow the server to time out.
661            35 seconds should do it. */
662
663         orig_timeout = rpccli_set_timeout(cli, 35000);
664
665         status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
666                                               &group_pol,
667                                               &rids,
668                                               &result);
669
670         /* And restore our original timeout. */
671         rpccli_set_timeout(cli, orig_timeout);
672
673         {
674                 NTSTATUS _result;
675                 dcerpc_samr_Close(b, mem_ctx, &group_pol, &_result);
676         }
677
678         if (!NT_STATUS_IS_OK(status)) {
679                 return status;
680         }
681
682         if (!NT_STATUS_IS_OK(result)) {
683                 return result;
684         }
685
686         if (!rids || !rids->count) {
687                 names = NULL;
688                 name_types = NULL;
689                 sid_mem = NULL;
690                 return NT_STATUS_OK;
691         }
692
693         *num_names = rids->count;
694         rid_mem = rids->rids;
695
696         /* Step #2: Convert list of rids into list of usernames.  Do this
697            in bunches of ~1000 to avoid crashing NT4.  It looks like there
698            is a buffer overflow or something like that lurking around
699            somewhere. */
700
701 #define MAX_LOOKUP_RIDS 900
702
703         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
704         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
705         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);
706
707         for (j=0;j<(*num_names);j++)
708                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
709
710         if (*num_names>0 && (!*names || !*name_types))
711                 return NT_STATUS_NO_MEMORY;
712
713         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
714                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
715                 struct lsa_Strings tmp_names;
716                 struct samr_Ids tmp_types;
717
718                 /* Lookup a chunk of rids */
719
720                 status = dcerpc_samr_LookupRids(b, mem_ctx,
721                                                 &dom_pol,
722                                                 num_lookup_rids,
723                                                 &rid_mem[i],
724                                                 &tmp_names,
725                                                 &tmp_types,
726                                                 &result);
727                 if (!NT_STATUS_IS_OK(status)) {
728                         return status;
729                 }
730
731                 /* see if we have a real error (and yes the
732                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
733
734                 if (!NT_STATUS_IS_OK(result) &&
735                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
736                         return result;
737
738                 /* Copy result into array.  The talloc system will take
739                    care of freeing the temporary arrays later on. */
740
741                 if (tmp_names.count != tmp_types.count) {
742                         return NT_STATUS_UNSUCCESSFUL;
743                 }
744
745                 for (r=0; r<tmp_names.count; r++) {
746                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
747                                 continue;
748                         }
749                         (*names)[total_names] = fill_domain_username_talloc(
750                                 mem_ctx, domain->name,
751                                 tmp_names.names[r].string, true);
752                         (*name_types)[total_names] = tmp_types.ids[r];
753                         total_names += 1;
754                 }
755         }
756
757         *num_names = total_names;
758
759         return NT_STATUS_OK;
760 }
761
762 #ifdef HAVE_LDAP
763
764 #include <ldap.h>
765
766 static int get_ldap_seq(const char *server, int port, uint32 *seq)
767 {
768         int ret = -1;
769         struct timeval to;
770         const char *attrs[] = {"highestCommittedUSN", NULL};
771         LDAPMessage *res = NULL;
772         char **values = NULL;
773         LDAP *ldp = NULL;
774
775         *seq = DOM_SEQUENCE_NONE;
776
777         /*
778          * Parameterised (5) second timeout on open. This is needed as the
779          * search timeout doesn't seem to apply to doing an open as well. JRA.
780          */
781
782         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
783         if (ldp == NULL)
784                 return -1;
785
786         /* Timeout if no response within 20 seconds. */
787         to.tv_sec = 10;
788         to.tv_usec = 0;
789
790         if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
791                            CONST_DISCARD(char **, attrs), 0, &to, &res))
792                 goto done;
793
794         if (ldap_count_entries(ldp, res) != 1)
795                 goto done;
796
797         values = ldap_get_values(ldp, res, "highestCommittedUSN");
798         if (!values || !values[0])
799                 goto done;
800
801         *seq = atoi(values[0]);
802         ret = 0;
803
804   done:
805
806         if (values)
807                 ldap_value_free(values);
808         if (res)
809                 ldap_msgfree(res);
810         if (ldp)
811                 ldap_unbind(ldp);
812         return ret;
813 }
814
815 /**********************************************************************
816  Get the sequence number for a Windows AD native mode domain using
817  LDAP queries.
818 **********************************************************************/
819
820 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
821 {
822         int ret = -1;
823         char addr[INET6_ADDRSTRLEN];
824
825         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
826         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
827                 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
828                           "number for Domain (%s) from DC (%s)\n",
829                         domain->name, addr));
830         }
831         return ret;
832 }
833
834 #endif /* HAVE_LDAP */
835
836 /* find the sequence number for a domain */
837 static NTSTATUS msrpc_sequence_number(struct winbindd_domain *domain,
838                                       uint32_t *pseq)
839 {
840         struct rpc_pipe_client *samr_pipe;
841         struct policy_handle dom_pol;
842         uint32_t seq;
843         TALLOC_CTX *tmp_ctx;
844         NTSTATUS status;
845
846         DEBUG(3, ("msrpc_sequence_number: fetch sequence_number for %s\n", domain->name));
847
848         if (pseq) {
849                 *pseq = DOM_SEQUENCE_NONE;
850         }
851
852         tmp_ctx = talloc_stackframe();
853         if (tmp_ctx == NULL) {
854                 return NT_STATUS_NO_MEMORY;
855         }
856
857         if ( !winbindd_can_contact_domain( domain ) ) {
858                 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
859                           domain->name));
860                 if (pseq) {
861                         *pseq = time(NULL);
862                 }
863                 status = NT_STATUS_OK;
864                 goto done;
865         }
866
867 #ifdef HAVE_LDAP
868         if (domain->active_directory) {
869                 int rc;
870
871                 DEBUG(8,("using get_ldap_seq() to retrieve the "
872                          "sequence number\n"));
873
874                 rc =  get_ldap_sequence_number(domain, &seq);
875                 if (rc == 0) {
876                         DEBUG(10,("domain_sequence_number: LDAP for "
877                                   "domain %s is %u\n",
878                                   domain->name, seq));
879
880                         if (pseq) {
881                                 *pseq = seq;
882                         }
883
884                         status = NT_STATUS_OK;
885                         goto done;
886                 }
887
888                 DEBUG(10,("domain_sequence_number: failed to get LDAP "
889                           "sequence number for domain %s\n",
890                           domain->name ));
891         }
892 #endif /* HAVE_LDAP */
893
894         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
895         if (!NT_STATUS_IS_OK(status)) {
896                 goto done;
897         }
898
899         status = rpc_sequence_number(tmp_ctx,
900                                      samr_pipe,
901                                      &dom_pol,
902                                      domain->name,
903                                      &seq);
904         if (!NT_STATUS_IS_OK(status)) {
905                 goto done;
906         }
907
908         if (pseq) {
909                 *pseq = seq;
910         }
911
912 done:
913         TALLOC_FREE(tmp_ctx);
914         return status;
915 }
916
917 /* get a list of trusted domains */
918 static NTSTATUS msrpc_trusted_domains(struct winbindd_domain *domain,
919                                       TALLOC_CTX *mem_ctx,
920                                       struct netr_DomainTrustList *ptrust_list)
921 {
922         struct rpc_pipe_client *lsa_pipe;
923         struct policy_handle lsa_policy;
924         struct netr_DomainTrust *trusts = NULL;
925         uint32_t num_trusts = 0;
926         TALLOC_CTX *tmp_ctx;
927         NTSTATUS status;
928
929         DEBUG(3,("msrpc_trusted_domains\n"));
930
931         if (ptrust_list) {
932                 ZERO_STRUCTP(ptrust_list);
933         }
934
935         tmp_ctx = talloc_stackframe();
936         if (tmp_ctx == NULL) {
937                 return NT_STATUS_NO_MEMORY;
938         }
939
940         status = cm_connect_lsa(domain, tmp_ctx, &lsa_pipe, &lsa_policy);
941         if (!NT_STATUS_IS_OK(status))
942                 return status;
943
944         status = rpc_trusted_domains(tmp_ctx,
945                                      lsa_pipe,
946                                      &lsa_policy,
947                                      &num_trusts,
948                                      &trusts);
949         if (!NT_STATUS_IS_OK(status)) {
950                 goto done;
951         }
952
953         if (ptrust_list) {
954                 ptrust_list->count = num_trusts;
955                 ptrust_list->array = talloc_move(mem_ctx, &trusts);
956         }
957
958 done:
959         TALLOC_FREE(tmp_ctx);
960         return status;
961 }
962
963 /* find the lockout policy for a domain */
964 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
965                                      TALLOC_CTX *mem_ctx,
966                                      struct samr_DomInfo12 *lockout_policy)
967 {
968         NTSTATUS status, result;
969         struct rpc_pipe_client *cli;
970         struct policy_handle dom_pol;
971         union samr_DomainInfo *info = NULL;
972         struct dcerpc_binding_handle *b;
973
974         DEBUG(3, ("msrpc_lockout_policy: fetch lockout policy for %s\n", domain->name));
975
976         if ( !winbindd_can_contact_domain( domain ) ) {
977                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
978                           domain->name));
979                 return NT_STATUS_NOT_SUPPORTED;
980         }
981
982         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
983         if (!NT_STATUS_IS_OK(status)) {
984                 goto done;
985         }
986
987         b = cli->binding_handle;
988
989         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
990                                              &dom_pol,
991                                              12,
992                                              &info,
993                                              &result);
994         if (!NT_STATUS_IS_OK(status)) {
995                 goto done;
996         }
997         if (!NT_STATUS_IS_OK(result)) {
998                 status = result;
999                 goto done;
1000         }
1001
1002         *lockout_policy = info->info12;
1003
1004         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1005                 info->info12.lockout_threshold));
1006
1007   done:
1008
1009         return status;
1010 }
1011
1012 /* find the password policy for a domain */
1013 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1014                                       TALLOC_CTX *mem_ctx,
1015                                       struct samr_DomInfo1 *password_policy)
1016 {
1017         NTSTATUS status, result;
1018         struct rpc_pipe_client *cli;
1019         struct policy_handle dom_pol;
1020         union samr_DomainInfo *info = NULL;
1021         struct dcerpc_binding_handle *b;
1022
1023         DEBUG(3, ("msrpc_password_policy: fetch password policy for %s\n",
1024                   domain->name));
1025
1026         if ( !winbindd_can_contact_domain( domain ) ) {
1027                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1028                           domain->name));
1029                 return NT_STATUS_NOT_SUPPORTED;
1030         }
1031
1032         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1033         if (!NT_STATUS_IS_OK(status)) {
1034                 goto done;
1035         }
1036
1037         b = cli->binding_handle;
1038
1039         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
1040                                              &dom_pol,
1041                                              1,
1042                                              &info,
1043                                              &result);
1044         if (!NT_STATUS_IS_OK(status)) {
1045                 goto done;
1046         }
1047         if (!NT_STATUS_IS_OK(result)) {
1048                 goto done;
1049         }
1050
1051         *password_policy = info->info1;
1052
1053         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1054                 info->info1.min_password_length));
1055
1056   done:
1057
1058         return status;
1059 }
1060
1061 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1062                                      TALLOC_CTX *mem_ctx,
1063                                      struct policy_handle *pol,
1064                                      int num_sids,
1065                                      const struct dom_sid *sids,
1066                                      char ***pdomains,
1067                                      char ***pnames,
1068                                      enum lsa_SidType **ptypes);
1069
1070 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1071                               struct winbindd_domain *domain,
1072                               uint32_t num_sids,
1073                               const struct dom_sid *sids,
1074                               char ***domains,
1075                               char ***names,
1076                               enum lsa_SidType **types)
1077 {
1078         NTSTATUS status;
1079         struct rpc_pipe_client *cli = NULL;
1080         struct policy_handle lsa_policy;
1081         unsigned int orig_timeout;
1082         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1083
1084         if (domain->can_do_ncacn_ip_tcp) {
1085                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1086                 if (NT_STATUS_IS_OK(status)) {
1087                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
1088                         goto lookup;
1089                 }
1090                 domain->can_do_ncacn_ip_tcp = false;
1091         }
1092         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1093
1094         if (!NT_STATUS_IS_OK(status)) {
1095                 return status;
1096         }
1097
1098  lookup:
1099         /*
1100          * This call can take a long time
1101          * allow the server to time out.
1102          * 35 seconds should do it.
1103          */
1104         orig_timeout = rpccli_set_timeout(cli, 35000);
1105
1106         status = lookup_sids_fn(cli,
1107                                 mem_ctx,
1108                                 &lsa_policy,
1109                                 num_sids,
1110                                 sids,
1111                                 domains,
1112                                 names,
1113                                 types);
1114
1115         /* And restore our original timeout. */
1116         rpccli_set_timeout(cli, orig_timeout);
1117
1118         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1119             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1120                 /*
1121                  * This can happen if the schannel key is not
1122                  * valid anymore, we need to invalidate the
1123                  * all connections to the dc and reestablish
1124                  * a netlogon connection first.
1125                  */
1126                 invalidate_cm_connection(&domain->conn);
1127                 status = NT_STATUS_ACCESS_DENIED;
1128         }
1129
1130         if (!NT_STATUS_IS_OK(status)) {
1131                 return status;
1132         }
1133
1134         return status;
1135 }
1136
1137 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1138                                       TALLOC_CTX *mem_ctx,
1139                                       struct policy_handle *pol,
1140                                       int num_names,
1141                                       const char **names,
1142                                       const char ***dom_names,
1143                                       int level,
1144                                       struct dom_sid **sids,
1145                                       enum lsa_SidType **types);
1146
1147 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1148                                struct winbindd_domain *domain,
1149                                uint32_t num_names,
1150                                const char **names,
1151                                const char ***domains,
1152                                struct dom_sid **sids,
1153                                enum lsa_SidType **types)
1154 {
1155         NTSTATUS status;
1156         struct rpc_pipe_client *cli = NULL;
1157         struct policy_handle lsa_policy;
1158         unsigned int orig_timeout = 0;
1159         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1160
1161         if (domain->can_do_ncacn_ip_tcp) {
1162                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1163                 if (NT_STATUS_IS_OK(status)) {
1164                         lookup_names_fn = rpccli_lsa_lookup_names4;
1165                         goto lookup;
1166                 }
1167                 domain->can_do_ncacn_ip_tcp = false;
1168         }
1169         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1170
1171         if (!NT_STATUS_IS_OK(status)) {
1172                 return status;
1173         }
1174
1175  lookup:
1176
1177         /*
1178          * This call can take a long time
1179          * allow the server to time out.
1180          * 35 seconds should do it.
1181          */
1182         orig_timeout = rpccli_set_timeout(cli, 35000);
1183
1184         status = lookup_names_fn(cli,
1185                                  mem_ctx,
1186                                  &lsa_policy,
1187                                  num_names,
1188                                  (const char **) names,
1189                                  domains,
1190                                  1,
1191                                  sids,
1192                                  types);
1193
1194         /* And restore our original timeout. */
1195         rpccli_set_timeout(cli, orig_timeout);
1196
1197         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1198             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1199                 /*
1200                  * This can happen if the schannel key is not
1201                  * valid anymore, we need to invalidate the
1202                  * all connections to the dc and reestablish
1203                  * a netlogon connection first.
1204                  */
1205                 invalidate_cm_connection(&domain->conn);
1206                 status = NT_STATUS_ACCESS_DENIED;
1207         }
1208
1209         if (!NT_STATUS_IS_OK(status)) {
1210                 return status;
1211         }
1212
1213         return status;
1214 }
1215
1216 /* the rpc backend methods are exposed via this structure */
1217 struct winbindd_methods msrpc_methods = {
1218         False,
1219         msrpc_query_user_list,
1220         msrpc_enum_dom_groups,
1221         msrpc_enum_local_groups,
1222         msrpc_name_to_sid,
1223         msrpc_sid_to_name,
1224         msrpc_rids_to_names,
1225         msrpc_query_user,
1226         msrpc_lookup_usergroups,
1227         msrpc_lookup_useraliases,
1228         msrpc_lookup_groupmem,
1229         msrpc_sequence_number,
1230         msrpc_lockout_policy,
1231         msrpc_password_policy,
1232         msrpc_trusted_domains,
1233 };