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