libcli/security Provide a common, top level libcli/security/security.h
[samba.git] / source3 / winbindd / winbindd_msrpc.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Winbind rpc backend functions
5
6    Copyright (C) Tim Potter 2000-2001,2003
7    Copyright (C) Andrew Tridgell 2001
8    Copyright (C) Volker Lendecke 2005
9    Copyright (C) Guenther Deschner 2008 (pidl conversion)
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "winbindd.h"
27 #include "winbindd_rpc.h"
28
29 #include "../librpc/gen_ndr/cli_samr.h"
30 #include "rpc_client/cli_samr.h"
31 #include "../librpc/gen_ndr/cli_lsa.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 acct_info **pinfo)
105 {
106         struct rpc_pipe_client *samr_pipe;
107         struct policy_handle dom_pol;
108         struct 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 acct_info **pinfo)
164 {
165         struct rpc_pipe_client *samr_pipe;
166         struct policy_handle dom_pol;
167         struct 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         if (pnum_groups) {
526                 *pnum_groups = num_groups;
527         }
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 result = NT_STATUS_UNSUCCESSFUL;
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
624         DEBUG(3,("msrpc_lookup_groupmem: %s sid=%s\n", domain->name,
625                   sid_string_dbg(group_sid)));
626
627         if ( !winbindd_can_contact_domain( domain ) ) {
628                 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
629                           domain->name));
630                 return NT_STATUS_OK;
631         }
632
633         if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
634                 return NT_STATUS_UNSUCCESSFUL;
635
636         *num_names = 0;
637
638         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
639         if (!NT_STATUS_IS_OK(result))
640                 return result;
641
642         result = rpccli_samr_OpenGroup(cli, mem_ctx,
643                                        &dom_pol,
644                                        des_access,
645                                        group_rid,
646                                        &group_pol);
647
648         if (!NT_STATUS_IS_OK(result))
649                 return result;
650
651         /* Step #1: Get a list of user rids that are the members of the
652            group. */
653
654         /* This call can take a long time - allow the server to time out.
655            35 seconds should do it. */
656
657         orig_timeout = rpccli_set_timeout(cli, 35000);
658
659         result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
660                                               &group_pol,
661                                               &rids);
662
663         /* And restore our original timeout. */
664         rpccli_set_timeout(cli, orig_timeout);
665
666         rpccli_samr_Close(cli, mem_ctx, &group_pol);
667
668         if (!NT_STATUS_IS_OK(result))
669                 return result;
670
671         if (!rids || !rids->count) {
672                 names = NULL;
673                 name_types = NULL;
674                 sid_mem = NULL;
675                 return NT_STATUS_OK;
676         }
677
678         *num_names = rids->count;
679         rid_mem = rids->rids;
680
681         /* Step #2: Convert list of rids into list of usernames.  Do this
682            in bunches of ~1000 to avoid crashing NT4.  It looks like there
683            is a buffer overflow or something like that lurking around
684            somewhere. */
685
686 #define MAX_LOOKUP_RIDS 900
687
688         *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
689         *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
690         *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);
691
692         for (j=0;j<(*num_names);j++)
693                 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
694
695         if (*num_names>0 && (!*names || !*name_types))
696                 return NT_STATUS_NO_MEMORY;
697
698         for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
699                 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
700                 struct lsa_Strings tmp_names;
701                 struct samr_Ids tmp_types;
702
703                 /* Lookup a chunk of rids */
704
705                 result = rpccli_samr_LookupRids(cli, mem_ctx,
706                                                 &dom_pol,
707                                                 num_lookup_rids,
708                                                 &rid_mem[i],
709                                                 &tmp_names,
710                                                 &tmp_types);
711
712                 /* see if we have a real error (and yes the
713                    STATUS_SOME_UNMAPPED is the one returned from 2k) */
714
715                 if (!NT_STATUS_IS_OK(result) &&
716                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
717                         return result;
718
719                 /* Copy result into array.  The talloc system will take
720                    care of freeing the temporary arrays later on. */
721
722                 if (tmp_names.count != tmp_types.count) {
723                         return NT_STATUS_UNSUCCESSFUL;
724                 }
725
726                 for (r=0; r<tmp_names.count; r++) {
727                         if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
728                                 continue;
729                         }
730                         (*names)[total_names] = fill_domain_username_talloc(
731                                 mem_ctx, domain->name,
732                                 tmp_names.names[r].string, true);
733                         (*name_types)[total_names] = tmp_types.ids[r];
734                         total_names += 1;
735                 }
736         }
737
738         *num_names = total_names;
739
740         return NT_STATUS_OK;
741 }
742
743 #ifdef HAVE_LDAP
744
745 #include <ldap.h>
746
747 static int get_ldap_seq(const char *server, int port, uint32 *seq)
748 {
749         int ret = -1;
750         struct timeval to;
751         const char *attrs[] = {"highestCommittedUSN", NULL};
752         LDAPMessage *res = NULL;
753         char **values = NULL;
754         LDAP *ldp = NULL;
755
756         *seq = DOM_SEQUENCE_NONE;
757
758         /*
759          * Parameterised (5) second timeout on open. This is needed as the
760          * search timeout doesn't seem to apply to doing an open as well. JRA.
761          */
762
763         ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
764         if (ldp == NULL)
765                 return -1;
766
767         /* Timeout if no response within 20 seconds. */
768         to.tv_sec = 10;
769         to.tv_usec = 0;
770
771         if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
772                            CONST_DISCARD(char **, attrs), 0, &to, &res))
773                 goto done;
774
775         if (ldap_count_entries(ldp, res) != 1)
776                 goto done;
777
778         values = ldap_get_values(ldp, res, "highestCommittedUSN");
779         if (!values || !values[0])
780                 goto done;
781
782         *seq = atoi(values[0]);
783         ret = 0;
784
785   done:
786
787         if (values)
788                 ldap_value_free(values);
789         if (res)
790                 ldap_msgfree(res);
791         if (ldp)
792                 ldap_unbind(ldp);
793         return ret;
794 }
795
796 /**********************************************************************
797  Get the sequence number for a Windows AD native mode domain using
798  LDAP queries.
799 **********************************************************************/
800
801 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
802 {
803         int ret = -1;
804         char addr[INET6_ADDRSTRLEN];
805
806         print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
807         if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
808                 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
809                           "number for Domain (%s) from DC (%s)\n",
810                         domain->name, addr));
811         }
812         return ret;
813 }
814
815 #endif /* HAVE_LDAP */
816
817 /* find the sequence number for a domain */
818 static NTSTATUS msrpc_sequence_number(struct winbindd_domain *domain,
819                                       uint32_t *pseq)
820 {
821         struct rpc_pipe_client *samr_pipe;
822         struct policy_handle dom_pol;
823         uint32_t seq;
824         TALLOC_CTX *tmp_ctx;
825         NTSTATUS status;
826
827         DEBUG(3, ("msrpc_sequence_number: fetch sequence_number for %s\n", domain->name));
828
829         if (pseq) {
830                 *pseq = DOM_SEQUENCE_NONE;
831         }
832
833         tmp_ctx = talloc_stackframe();
834         if (tmp_ctx == NULL) {
835                 return NT_STATUS_NO_MEMORY;
836         }
837
838         if ( !winbindd_can_contact_domain( domain ) ) {
839                 DEBUG(10,("sequence_number: No incoming trust for domain %s\n",
840                           domain->name));
841                 if (pseq) {
842                         *pseq = time(NULL);
843                 }
844                 status = NT_STATUS_OK;
845                 goto done;
846         }
847
848 #ifdef HAVE_LDAP
849         if (domain->active_directory) {
850                 int rc;
851
852                 DEBUG(8,("using get_ldap_seq() to retrieve the "
853                          "sequence number\n"));
854
855                 rc =  get_ldap_sequence_number(domain, &seq);
856                 if (rc == 0) {
857                         DEBUG(10,("domain_sequence_number: LDAP for "
858                                   "domain %s is %u\n",
859                                   domain->name, seq));
860
861                         if (pseq) {
862                                 *pseq = seq;
863                         }
864
865                         status = NT_STATUS_OK;
866                         goto done;
867                 }
868
869                 DEBUG(10,("domain_sequence_number: failed to get LDAP "
870                           "sequence number for domain %s\n",
871                           domain->name ));
872         }
873 #endif /* HAVE_LDAP */
874
875         status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);
876         if (!NT_STATUS_IS_OK(status)) {
877                 goto done;
878         }
879
880         status = rpc_sequence_number(tmp_ctx,
881                                      samr_pipe,
882                                      &dom_pol,
883                                      domain->name,
884                                      &seq);
885         if (!NT_STATUS_IS_OK(status)) {
886                 goto done;
887         }
888
889         if (pseq) {
890                 *pseq = seq;
891         }
892
893 done:
894         TALLOC_FREE(tmp_ctx);
895         return status;
896 }
897
898 /* get a list of trusted domains */
899 static NTSTATUS msrpc_trusted_domains(struct winbindd_domain *domain,
900                                       TALLOC_CTX *mem_ctx,
901                                       struct netr_DomainTrustList *ptrust_list)
902 {
903         struct rpc_pipe_client *lsa_pipe;
904         struct policy_handle lsa_policy;
905         struct netr_DomainTrust *trusts = NULL;
906         uint32_t num_trusts = 0;
907         TALLOC_CTX *tmp_ctx;
908         NTSTATUS status;
909
910         DEBUG(3,("msrpc_trusted_domains\n"));
911
912         if (ptrust_list) {
913                 ZERO_STRUCTP(ptrust_list);
914         }
915
916         tmp_ctx = talloc_stackframe();
917         if (tmp_ctx == NULL) {
918                 return NT_STATUS_NO_MEMORY;
919         }
920
921         status = cm_connect_lsa(domain, tmp_ctx, &lsa_pipe, &lsa_policy);
922         if (!NT_STATUS_IS_OK(status))
923                 return status;
924
925         status = rpc_trusted_domains(tmp_ctx,
926                                      lsa_pipe,
927                                      &lsa_policy,
928                                      &num_trusts,
929                                      &trusts);
930         if (!NT_STATUS_IS_OK(status)) {
931                 goto done;
932         }
933
934         if (ptrust_list) {
935                 ptrust_list->count = num_trusts;
936                 ptrust_list->array = talloc_move(mem_ctx, &trusts);
937         }
938
939 done:
940         TALLOC_FREE(tmp_ctx);
941         return status;
942 }
943
944 /* find the lockout policy for a domain */
945 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
946                                      TALLOC_CTX *mem_ctx,
947                                      struct samr_DomInfo12 *lockout_policy)
948 {
949         NTSTATUS result;
950         struct rpc_pipe_client *cli;
951         struct policy_handle dom_pol;
952         union samr_DomainInfo *info = NULL;
953
954         DEBUG(3, ("msrpc_lockout_policy: fetch lockout policy for %s\n", domain->name));
955
956         if ( !winbindd_can_contact_domain( domain ) ) {
957                 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n",
958                           domain->name));
959                 return NT_STATUS_NOT_SUPPORTED;
960         }
961
962         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
963         if (!NT_STATUS_IS_OK(result)) {
964                 goto done;
965         }
966
967         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
968                                              &dom_pol,
969                                              12,
970                                              &info);
971         if (!NT_STATUS_IS_OK(result)) {
972                 goto done;
973         }
974
975         *lockout_policy = info->info12;
976
977         DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
978                 info->info12.lockout_threshold));
979
980   done:
981
982         return result;
983 }
984
985 /* find the password policy for a domain */
986 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
987                                       TALLOC_CTX *mem_ctx,
988                                       struct samr_DomInfo1 *password_policy)
989 {
990         NTSTATUS result;
991         struct rpc_pipe_client *cli;
992         struct policy_handle dom_pol;
993         union samr_DomainInfo *info = NULL;
994
995         DEBUG(3, ("msrpc_password_policy: fetch password policy for %s\n",
996                   domain->name));
997
998         if ( !winbindd_can_contact_domain( domain ) ) {
999                 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n",
1000                           domain->name));
1001                 return NT_STATUS_NOT_SUPPORTED;
1002         }
1003
1004         result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
1005         if (!NT_STATUS_IS_OK(result)) {
1006                 goto done;
1007         }
1008
1009         result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
1010                                              &dom_pol,
1011                                              1,
1012                                              &info);
1013         if (!NT_STATUS_IS_OK(result)) {
1014                 goto done;
1015         }
1016
1017         *password_policy = info->info1;
1018
1019         DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
1020                 info->info1.min_password_length));
1021
1022   done:
1023
1024         return result;
1025 }
1026
1027 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli,
1028                                      TALLOC_CTX *mem_ctx,
1029                                      struct policy_handle *pol,
1030                                      int num_sids,
1031                                      const struct dom_sid *sids,
1032                                      char ***pdomains,
1033                                      char ***pnames,
1034                                      enum lsa_SidType **ptypes);
1035
1036 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx,
1037                               struct winbindd_domain *domain,
1038                               uint32_t num_sids,
1039                               const struct dom_sid *sids,
1040                               char ***domains,
1041                               char ***names,
1042                               enum lsa_SidType **types)
1043 {
1044         NTSTATUS status;
1045         struct rpc_pipe_client *cli = NULL;
1046         struct policy_handle lsa_policy;
1047         unsigned int orig_timeout;
1048         lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;
1049
1050         if (domain->can_do_ncacn_ip_tcp) {
1051                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1052                 if (NT_STATUS_IS_OK(status)) {
1053                         lookup_sids_fn = rpccli_lsa_lookup_sids3;
1054                         goto lookup;
1055                 }
1056                 domain->can_do_ncacn_ip_tcp = false;
1057         }
1058         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1059
1060         if (!NT_STATUS_IS_OK(status)) {
1061                 return status;
1062         }
1063
1064  lookup:
1065         /*
1066          * This call can take a long time
1067          * allow the server to time out.
1068          * 35 seconds should do it.
1069          */
1070         orig_timeout = rpccli_set_timeout(cli, 35000);
1071
1072         status = lookup_sids_fn(cli,
1073                                 mem_ctx,
1074                                 &lsa_policy,
1075                                 num_sids,
1076                                 sids,
1077                                 domains,
1078                                 names,
1079                                 types);
1080
1081         /* And restore our original timeout. */
1082         rpccli_set_timeout(cli, orig_timeout);
1083
1084         return status;
1085 }
1086
1087 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli,
1088                                       TALLOC_CTX *mem_ctx,
1089                                       struct policy_handle *pol,
1090                                       int num_names,
1091                                       const char **names,
1092                                       const char ***dom_names,
1093                                       int level,
1094                                       struct dom_sid **sids,
1095                                       enum lsa_SidType **types);
1096
1097 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
1098                                struct winbindd_domain *domain,
1099                                uint32_t num_names,
1100                                const char **names,
1101                                const char ***domains,
1102                                struct dom_sid **sids,
1103                                enum lsa_SidType **types)
1104 {
1105         NTSTATUS status;
1106         struct rpc_pipe_client *cli = NULL;
1107         struct policy_handle lsa_policy;
1108         unsigned int orig_timeout = 0;
1109         lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names;
1110
1111         if (domain->can_do_ncacn_ip_tcp) {
1112                 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);
1113                 if (NT_STATUS_IS_OK(status)) {
1114                         lookup_names_fn = rpccli_lsa_lookup_names4;
1115                         goto lookup;
1116                 }
1117                 domain->can_do_ncacn_ip_tcp = false;
1118         }
1119         status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
1120
1121         if (!NT_STATUS_IS_OK(status)) {
1122                 return status;
1123         }
1124
1125  lookup:
1126
1127         /*
1128          * This call can take a long time
1129          * allow the server to time out.
1130          * 35 seconds should do it.
1131          */
1132         orig_timeout = rpccli_set_timeout(cli, 35000);
1133
1134         status = lookup_names_fn(cli,
1135                                  mem_ctx,
1136                                  &lsa_policy,
1137                                  num_names,
1138                                  (const char **) names,
1139                                  domains,
1140                                  1,
1141                                  sids,
1142                                  types);
1143
1144         /* And restore our original timeout. */
1145         rpccli_set_timeout(cli, orig_timeout);
1146
1147         if (!NT_STATUS_IS_OK(status)) {
1148                 return status;
1149         }
1150
1151         return status;
1152 }
1153
1154 /* the rpc backend methods are exposed via this structure */
1155 struct winbindd_methods msrpc_methods = {
1156         False,
1157         msrpc_query_user_list,
1158         msrpc_enum_dom_groups,
1159         msrpc_enum_local_groups,
1160         msrpc_name_to_sid,
1161         msrpc_sid_to_name,
1162         msrpc_rids_to_names,
1163         msrpc_query_user,
1164         msrpc_lookup_usergroups,
1165         msrpc_lookup_useraliases,
1166         msrpc_lookup_groupmem,
1167         msrpc_sequence_number,
1168         msrpc_lockout_policy,
1169         msrpc_password_policy,
1170         msrpc_trusted_domains,
1171 };