s3:winbindd: let winbindd_lookup_sids() dcerpc_binding_handle functions
[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
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;
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         user = netsamlogon_cache_get(tmp_ctx, user_sid);
422         if (user != NULL) {
423                 DEBUG(5,("msrpc_query_user: Cache lookup succeeded for %s\n",
424                         sid_string_dbg(user_sid)));
425
426                 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
427                 sid_compose(&user_info->group_sid, &domain->sid,
428                             user->base.primary_gid);
429
430                 user_info->acct_name = talloc_strdup(user_info,
431                                                      user->base.account_name.string);
432                 user_info->full_name = talloc_strdup(user_info,
433                                                      user->base.full_name.string);
434
435                 status = NT_STATUS_OK;
436                 goto done;
437         }
438
439         if ( !winbindd_can_contact_domain( domain ) ) {
440                 DEBUG(10,("query_user: No incoming trust for domain %s\n",
441                           domain->name));
442                 /* Tell the cache manager not to remember this one */
443                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
444                 goto done;
445         }
446
447         /* no cache; hit the wire */
448         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
449         if (!NT_STATUS_IS_OK(status)) {
450                 goto done;
451         }
452
453         status = rpc_query_user(tmp_ctx,
454                                 samr_pipe,
455                                 &dom_pol,
456                                 &domain->sid,
457                                 user_sid,
458                                 user_info);
459
460 done:
461         TALLOC_FREE(tmp_ctx);
462         return status;
463 }
464
465 /* Lookup groups a user is a member of.  I wish Unix had a call like this! */
466 static NTSTATUS msrpc_lookup_usergroups(struct winbindd_domain *domain,
467                                         TALLOC_CTX *mem_ctx,
468                                         const struct dom_sid *user_sid,
469                                         uint32_t *pnum_groups,
470                                         struct dom_sid **puser_grpsids)
471 {
472         struct rpc_pipe_client *samr_pipe;
473         struct policy_handle dom_pol;
474         struct dom_sid *user_grpsids = NULL;
475         uint32_t num_groups = 0;
476         TALLOC_CTX *tmp_ctx;
477         NTSTATUS status;
478
479         DEBUG(3,("msrpc_lookup_usergroups sid=%s\n", sid_string_dbg(user_sid)));
480
481         *pnum_groups = 0;
482
483         tmp_ctx = talloc_stackframe();
484         if (tmp_ctx == NULL) {
485                 return NT_STATUS_NO_MEMORY;
486         }
487
488         /* Check if we have a cached user_info_3 */
489         status = lookup_usergroups_cached(domain,
490                                           tmp_ctx,
491                                           user_sid,
492                                           &num_groups,
493                                           &user_grpsids);
494         if (NT_STATUS_IS_OK(status)) {
495                 goto cached;
496         }
497
498         if ( !winbindd_can_contact_domain( domain ) ) {
499                 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n",
500                           domain->name));
501
502                 /* Tell the cache manager not to remember this one */
503                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
504                 goto done;
505         }
506
507         /* no cache; hit the wire */
508         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
509         if (!NT_STATUS_IS_OK(status)) {
510                 goto done;
511         }
512
513         status = rpc_lookup_usergroups(tmp_ctx,
514                                        samr_pipe,
515                                        &dom_pol,
516                                        &domain->sid,
517                                        user_sid,
518                                        &num_groups,
519                                        &user_grpsids);
520         if (!NT_STATUS_IS_OK(status)) {
521                 goto done;
522         }
523
524 cached:
525         *pnum_groups = num_groups;
526
527         if (puser_grpsids) {
528                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
529         }
530
531 done:
532         TALLOC_FREE(tmp_ctx);
533         return status;
534         return NT_STATUS_OK;
535 }
536
537 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
538
539 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
540                                          TALLOC_CTX *mem_ctx,
541                                          uint32 num_sids, const struct dom_sid *sids,
542                                          uint32 *pnum_aliases,
543                                          uint32 **palias_rids)
544 {
545         struct rpc_pipe_client *samr_pipe;
546         struct policy_handle dom_pol;
547         uint32_t num_aliases = 0;
548         uint32_t *alias_rids = NULL;
549         TALLOC_CTX *tmp_ctx;
550         NTSTATUS status;
551
552         DEBUG(3,("msrpc_lookup_useraliases\n"));
553
554         if (pnum_aliases) {
555                 *pnum_aliases = 0;
556         }
557
558         tmp_ctx = talloc_stackframe();
559         if (tmp_ctx == NULL) {
560                 return NT_STATUS_NO_MEMORY;
561         }
562
563         if (!winbindd_can_contact_domain(domain)) {
564                 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n",
565                           domain->name));
566                 /* Tell the cache manager not to remember this one */
567                 status = NT_STATUS_SYNCHRONIZATION_REQUIRED;
568                 goto done;
569         }
570
571         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
572         if (!NT_STATUS_IS_OK(status)) {
573                 goto done;
574         }
575
576         status = rpc_lookup_useraliases(tmp_ctx,
577                                         samr_pipe,
578                                         &dom_pol,
579                                         num_sids,
580                                         sids,
581                                         &num_aliases,
582                                         &alias_rids);
583         if (!NT_STATUS_IS_OK(status)) {
584                 goto done;
585         }
586
587         if (pnum_aliases) {
588                 *pnum_aliases = num_aliases;
589         }
590
591         if (palias_rids) {
592                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
593         }
594
595 done:
596         TALLOC_FREE(tmp_ctx);
597         return status;
598 }
599
600
601 /* Lookup group membership given a rid.   */
602 static NTSTATUS msrpc_lookup_groupmem(struct winbindd_domain *domain,
603                                       TALLOC_CTX *mem_ctx,
604                                       const struct dom_sid *group_sid,
605                                       enum lsa_SidType type,
606                                       uint32_t *num_names,
607                                       struct dom_sid **sid_mem,
608                                       char ***names,
609                                       uint32_t **name_types)
610 {
611         NTSTATUS status, result;
612         uint32 i, total_names = 0;
613         struct policy_handle dom_pol, group_pol;
614         uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED;
615         uint32 *rid_mem = NULL;
616         uint32 group_rid;
617         unsigned int j, r;
618         struct rpc_pipe_client *cli;
619         unsigned int orig_timeout;
620         struct samr_RidAttrArray *rids = NULL;
621         struct dcerpc_binding_handle *b;
622
623         DEBUG(3,("msrpc_lookup_groupmem: %s sid=%s\n", domain->name,
624                   sid_string_dbg(group_sid)));
625
626         if ( !winbindd_can_contact_domain( domain ) ) {
627                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
628                           domain->name));
629                 return NT_STATUS_OK;
630         }
631
632         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
633                 return NT_STATUS_UNSUCCESSFUL;
634
635         *num_names = 0;
636
637         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
638         if (!NT_STATUS_IS_OK(result))
639                 return result;
640
641         b = cli->binding_handle;
642
643         status = dcerpc_samr_OpenGroup(b, mem_ctx,
644                                        &dom_pol,
645                                        des_access,
646                                        group_rid,
647                                        &group_pol,
648                                        &result);
649         if (!NT_STATUS_IS_OK(status)) {
650                 return status;
651         }
652         if (!NT_STATUS_IS_OK(result)) {
653                 return result;
654         }
655
656         /* Step #1: Get a list of user rids that are the members of the
657            group. */
658
659         /* This call can take a long time - allow the server to time out.
660            35 seconds should do it. */
661
662         orig_timeout = rpccli_set_timeout(cli, 35000);
663
664         status = dcerpc_samr_QueryGroupMember(b, mem_ctx,
665                                               &group_pol,
666                                               &rids,
667                                               &result);
668
669         /* And restore our original timeout. */
670         rpccli_set_timeout(cli, orig_timeout);
671
672         {
673                 NTSTATUS _result;
674                 dcerpc_samr_Close(b, mem_ctx, &group_pol, &_result);
675         }
676
677         if (!NT_STATUS_IS_OK(status)) {
678                 return status;
679         }
680
681         if (!NT_STATUS_IS_OK(result)) {
682                 return result;
683         }
684
685         if (!rids || !rids->count) {
686                 names = NULL;
687                 name_types = NULL;
688                 sid_mem = NULL;
689                 return NT_STATUS_OK;
690         }
691
692         *num_names = rids->count;
693         rid_mem = rids->rids;
694
695         /* Step #2: Convert list of rids into list of usernames.  Do this
696            in bunches of ~1000 to avoid crashing NT4.  It looks like there
697            is a buffer overflow or something like that lurking around
698            somewhere. */
699
700 #define MAX_LOOKUP_RIDS 900
701
702         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
703         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
704         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);
705
706         for (j=0;j<(*num_names);j++)
707                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
708
709         if (*num_names>0 && (!*names || !*name_types))
710                 return NT_STATUS_NO_MEMORY;
711
712         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
713                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
714                 struct lsa_Strings tmp_names;
715                 struct samr_Ids tmp_types;
716
717                 /* Lookup a chunk of rids */
718
719                 status = dcerpc_samr_LookupRids(b, mem_ctx,
720                                                 &dom_pol,
721                                                 num_lookup_rids,
722                                                 &rid_mem[i],
723                                                 &tmp_names,
724                                                 &tmp_types,
725                                                 &result);
726                 if (!NT_STATUS_IS_OK(status)) {
727                         return status;
728                 }
729
730                 /* see if we have a real error (and yes the
731                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
732
733                 if (!NT_STATUS_IS_OK(result) &&
734                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
735                         return result;
736
737                 /* Copy result into array.  The talloc system will take
738                    care of freeing the temporary arrays later on. */
739
740                 if (tmp_names.count != tmp_types.count) {
741                         return NT_STATUS_UNSUCCESSFUL;
742                 }
743
744                 for (r=0; r<tmp_names.count; r++) {
745                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
746                                 continue;
747                         }
748                         (*names)[total_names] = fill_domain_username_talloc(
749                                 mem_ctx, domain->name,
750                                 tmp_names.names[r].string, true);
751                         (*name_types)[total_names] = tmp_types.ids[r];
752                         total_names += 1;
753                 }
754         }
755
756         *num_names = total_names;
757
758         return NT_STATUS_OK;
759 }
760
761 #ifdef HAVE_LDAP
762
763 #include <ldap.h>
764
765 static int get_ldap_seq(const char *server, int port, uint32 *seq)
766 {
767         int ret = -1;
768         struct timeval to;
769         const char *attrs[] = {"highestCommittedUSN", NULL};
770         LDAPMessage *res = NULL;
771         char **values = NULL;
772         LDAP *ldp = NULL;
773
774         *seq = DOM_SEQUENCE_NONE;
775
776         /*
777          * Parameterised (5) second timeout on open. This is needed as the
778          * search timeout doesn't seem to apply to doing an open as well. JRA.
779          */
780
781         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
782         if (ldp == NULL)
783                 return -1;
784
785         /* Timeout if no response within 20 seconds. */
786         to.tv_sec = 10;
787         to.tv_usec = 0;
788
789         if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
790                            CONST_DISCARD(char **, attrs), 0, &to, &res))
791                 goto done;
792
793         if (ldap_count_entries(ldp, res) != 1)
794                 goto done;
795
796         values = ldap_get_values(ldp, res, "highestCommittedUSN");
797         if (!values || !values[0])
798                 goto done;
799
800         *seq = atoi(values[0]);
801         ret = 0;
802
803   done:
804
805         if (values)
806                 ldap_value_free(values);
807         if (res)
808                 ldap_msgfree(res);
809         if (ldp)
810                 ldap_unbind(ldp);
811         return ret;
812 }
813
814 /**********************************************************************
815  Get the sequence number for a Windows AD native mode domain using
816  LDAP queries.
817 **********************************************************************/
818
819 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
820 {
821         int ret = -1;
822         char addr[INET6_ADDRSTRLEN];
823
824         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
825         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
826                 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
827                           "number for Domain (%s) from DC (%s)\n",
828                         domain->name, addr));
829         }
830         return ret;
831 }
832
833 #endif /* HAVE_LDAP */
834
835 /* find the sequence number for a domain */
836 static NTSTATUS msrpc_sequence_number(struct winbindd_domain *domain,
837                                       uint32_t *pseq)
838 {
839         struct rpc_pipe_client *samr_pipe;
840         struct policy_handle dom_pol;
841         uint32_t seq;
842         TALLOC_CTX *tmp_ctx;
843         NTSTATUS status;
844
845         DEBUG(3, ("msrpc_sequence_number: fetch sequence_number for %s\n", domain->name));
846
847         if (pseq) {
848                 *pseq = DOM_SEQUENCE_NONE;
849         }
850
851         tmp_ctx = talloc_stackframe();
852         if (tmp_ctx == NULL) {
853                 return NT_STATUS_NO_MEMORY;
854         }
855
856         if ( !winbindd_can_contact_domain( domain ) ) {
857                 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
858                           domain->name));
859                 if (pseq) {
860                         *pseq = time(NULL);
861                 }
862                 status = NT_STATUS_OK;
863                 goto done;
864         }
865
866 #ifdef HAVE_LDAP
867         if (domain->active_directory) {
868                 int rc;
869
870                 DEBUG(8,("using get_ldap_seq() to retrieve the "
871                          "sequence number\n"));
872
873                 rc =  get_ldap_sequence_number(domain, &seq);
874                 if (rc == 0) {
875                         DEBUG(10,("domain_sequence_number: LDAP for "
876                                   "domain %s is %u\n",
877                                   domain->name, seq));
878
879                         if (pseq) {
880                                 *pseq = seq;
881                         }
882
883                         status = NT_STATUS_OK;
884                         goto done;
885                 }
886
887                 DEBUG(10,("domain_sequence_number: failed to get LDAP "
888                           "sequence number for domain %s\n",
889                           domain->name ));
890         }
891 #endif /* HAVE_LDAP */
892
893         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
894         if (!NT_STATUS_IS_OK(status)) {
895                 goto done;
896         }
897
898         status = rpc_sequence_number(tmp_ctx,
899                                      samr_pipe,
900                                      &dom_pol,
901                                      domain->name,
902                                      &seq);
903         if (!NT_STATUS_IS_OK(status)) {
904                 goto done;
905         }
906
907         if (pseq) {
908                 *pseq = seq;
909         }
910
911 done:
912         TALLOC_FREE(tmp_ctx);
913         return status;
914 }
915
916 /* get a list of trusted domains */
917 static NTSTATUS msrpc_trusted_domains(struct winbindd_domain *domain,
918                                       TALLOC_CTX *mem_ctx,
919                                       struct netr_DomainTrustList *ptrust_list)
920 {
921         struct rpc_pipe_client *lsa_pipe;
922         struct policy_handle lsa_policy;
923         struct netr_DomainTrust *trusts = NULL;
924         uint32_t num_trusts = 0;
925         TALLOC_CTX *tmp_ctx;
926         NTSTATUS status;
927
928         DEBUG(3,("msrpc_trusted_domains\n"));
929
930         if (ptrust_list) {
931                 ZERO_STRUCTP(ptrust_list);
932         }
933
934         tmp_ctx = talloc_stackframe();
935         if (tmp_ctx == NULL) {
936                 return NT_STATUS_NO_MEMORY;
937         }
938
939         status = cm_connect_lsa(domain, tmp_ctx, &lsa_pipe, &lsa_policy);
940         if (!NT_STATUS_IS_OK(status))
941                 return status;
942
943         status = rpc_trusted_domains(tmp_ctx,
944                                      lsa_pipe,
945                                      &lsa_policy,
946                                      &num_trusts,
947                                      &trusts);
948         if (!NT_STATUS_IS_OK(status)) {
949                 goto done;
950         }
951
952         if (ptrust_list) {
953                 ptrust_list->count = num_trusts;
954                 ptrust_list->array = talloc_move(mem_ctx, &trusts);
955         }
956
957 done:
958         TALLOC_FREE(tmp_ctx);
959         return status;
960 }
961
962 /* find the lockout policy for a domain */
963 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
964                                      TALLOC_CTX *mem_ctx,
965                                      struct samr_DomInfo12 *lockout_policy)
966 {
967         NTSTATUS status, result;
968         struct rpc_pipe_client *cli;
969         struct policy_handle dom_pol;
970         union samr_DomainInfo *info = NULL;
971         struct dcerpc_binding_handle *b;
972
973         DEBUG(3, ("msrpc_lockout_policy: fetch lockout policy for %s\n", domain->name));
974
975         if ( !winbindd_can_contact_domain( domain ) ) {
976                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
977                           domain->name));
978                 return NT_STATUS_NOT_SUPPORTED;
979         }
980
981         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
982         if (!NT_STATUS_IS_OK(status)) {
983                 goto done;
984         }
985
986         b = cli->binding_handle;
987
988         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
989                                              &dom_pol,
990                                              DomainLockoutInformation,
991                                              &info,
992                                              &result);
993         if (!NT_STATUS_IS_OK(status)) {
994                 goto done;
995         }
996         if (!NT_STATUS_IS_OK(result)) {
997                 status = result;
998                 goto done;
999         }
1000
1001         *lockout_policy = info->info12;
1002
1003         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
1004                 info->info12.lockout_threshold));
1005
1006   done:
1007
1008         return status;
1009 }
1010
1011 /* find the password policy for a domain */
1012 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
1013                                       TALLOC_CTX *mem_ctx,
1014                                       struct samr_DomInfo1 *password_policy)
1015 {
1016         NTSTATUS status, result;
1017         struct rpc_pipe_client *cli;
1018         struct policy_handle dom_pol;
1019         union samr_DomainInfo *info = NULL;
1020         struct dcerpc_binding_handle *b;
1021
1022         DEBUG(3, ("msrpc_password_policy: fetch password policy for %s\n",
1023                   domain->name));
1024
1025         if ( !winbindd_can_contact_domain( domain ) ) {
1026                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1027                           domain->name));
1028                 return NT_STATUS_NOT_SUPPORTED;
1029         }
1030
1031         status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1032         if (!NT_STATUS_IS_OK(status)) {
1033                 goto done;
1034         }
1035
1036         b = cli->binding_handle;
1037
1038         status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
1039                                              &dom_pol,
1040                                              DomainPasswordInformation,
1041                                              &info,
1042                                              &result);
1043         if (!NT_STATUS_IS_OK(status)) {
1044                 goto done;
1045         }
1046         if (!NT_STATUS_IS_OK(result)) {
1047                 goto done;
1048         }
1049
1050         *password_policy = info->info1;
1051
1052         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1053                 info->info1.min_password_length));
1054
1055   done:
1056
1057         return status;
1058 }
1059
1060 typedef NTSTATUS (*lookup_sids_fn_t)(struct dcerpc_binding_handle *h,
1061                                      TALLOC_CTX *mem_ctx,
1062                                      struct policy_handle *pol,
1063                                      int num_sids,
1064                                      const struct dom_sid *sids,
1065                                      char ***pdomains,
1066                                      char ***pnames,
1067                                      enum lsa_SidType **ptypes,
1068                                      NTSTATUS *result);
1069
1070 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1071                               struct winbindd_domain *domain,
1072                               uint32_t num_sids,
1073                               const struct dom_sid *sids,
1074                               char ***domains,
1075                               char ***names,
1076                               enum lsa_SidType **types)
1077 {
1078         NTSTATUS status;
1079         NTSTATUS result;
1080         struct rpc_pipe_client *cli = NULL;
1081         struct dcerpc_binding_handle *b = NULL;
1082         struct policy_handle lsa_policy;
1083         unsigned int orig_timeout;
1084         lookup_sids_fn_t lookup_sids_fn = dcerpc_lsa_lookup_sids;
1085
1086         if (domain->can_do_ncacn_ip_tcp) {
1087                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1088                 if (NT_STATUS_IS_OK(status)) {
1089                         lookup_sids_fn = dcerpc_lsa_lookup_sids3;
1090                         goto lookup;
1091                 }
1092                 domain->can_do_ncacn_ip_tcp = false;
1093         }
1094         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1095
1096         if (!NT_STATUS_IS_OK(status)) {
1097                 return status;
1098         }
1099
1100  lookup:
1101         b = cli->binding_handle;
1102
1103         /*
1104          * This call can take a long time
1105          * allow the server to time out.
1106          * 35 seconds should do it.
1107          */
1108         orig_timeout = dcerpc_binding_handle_set_timeout(b, 35000);
1109
1110         status = lookup_sids_fn(b,
1111                                 mem_ctx,
1112                                 &lsa_policy,
1113                                 num_sids,
1114                                 sids,
1115                                 domains,
1116                                 names,
1117                                 types,
1118                                 &result);
1119
1120         /* And restore our original timeout. */
1121         dcerpc_binding_handle_set_timeout(b, orig_timeout);
1122
1123         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1124             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1125                 /*
1126                  * This can happen if the schannel key is not
1127                  * valid anymore, we need to invalidate the
1128                  * all connections to the dc and reestablish
1129                  * a netlogon connection first.
1130                  */
1131                 invalidate_cm_connection(&domain->conn);
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 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1147                                       TALLOC_CTX *mem_ctx,
1148                                       struct policy_handle *pol,
1149                                       int num_names,
1150                                       const char **names,
1151                                       const char ***dom_names,
1152                                       int level,
1153                                       struct dom_sid **sids,
1154                                       enum lsa_SidType **types);
1155
1156 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1157                                struct winbindd_domain *domain,
1158                                uint32_t num_names,
1159                                const char **names,
1160                                const char ***domains,
1161                                struct dom_sid **sids,
1162                                enum lsa_SidType **types)
1163 {
1164         NTSTATUS status;
1165         struct rpc_pipe_client *cli = NULL;
1166         struct policy_handle lsa_policy;
1167         unsigned int orig_timeout = 0;
1168         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1169
1170         if (domain->can_do_ncacn_ip_tcp) {
1171                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1172                 if (NT_STATUS_IS_OK(status)) {
1173                         lookup_names_fn = rpccli_lsa_lookup_names4;
1174                         goto lookup;
1175                 }
1176                 domain->can_do_ncacn_ip_tcp = false;
1177         }
1178         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1179
1180         if (!NT_STATUS_IS_OK(status)) {
1181                 return status;
1182         }
1183
1184  lookup:
1185
1186         /*
1187          * This call can take a long time
1188          * allow the server to time out.
1189          * 35 seconds should do it.
1190          */
1191         orig_timeout = rpccli_set_timeout(cli, 35000);
1192
1193         status = lookup_names_fn(cli,
1194                                  mem_ctx,
1195                                  &lsa_policy,
1196                                  num_names,
1197                                  (const char **) names,
1198                                  domains,
1199                                  1,
1200                                  sids,
1201                                  types);
1202
1203         /* And restore our original timeout. */
1204         rpccli_set_timeout(cli, orig_timeout);
1205
1206         if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED ||
1207             NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) {
1208                 /*
1209                  * This can happen if the schannel key is not
1210                  * valid anymore, we need to invalidate the
1211                  * all connections to the dc and reestablish
1212                  * a netlogon connection first.
1213                  */
1214                 invalidate_cm_connection(&domain->conn);
1215                 status = NT_STATUS_ACCESS_DENIED;
1216         }
1217
1218         if (!NT_STATUS_IS_OK(status)) {
1219                 return status;
1220         }
1221
1222         return status;
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 };