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