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