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