s3-winbind: We need to use internal rpc connections in winbind.
[idra/samba.git] / source3 / winbindd / winbindd_samr.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * Winbind rpc backend functions
5  *
6  * Copyright (c) 2000-2003 Tim Potter
7  * Copyright (c) 2001      Andrew Tridgell
8  * Copyright (c) 2005      Volker Lendecke
9  * Copyright (c) 2008      Guenther Deschner (pidl conversion)
10  * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
29 #include "rpc_client/rpc_client.h"
30 #include "../librpc/gen_ndr/ndr_samr_c.h"
31 #include "rpc_client/cli_samr.h"
32 #include "../librpc/gen_ndr/ndr_lsa_c.h"
33 #include "rpc_client/cli_lsarpc.h"
34 #include "rpc_server/rpc_ncacn_np.h"
35 #include "../libcli/security/security.h"
36 #include "passdb/machine_sid.h"
37 #include "auth.h"
38
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_WINBIND
41
42 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
43                                         struct rpc_pipe_client **samr_pipe)
44 {
45         struct rpc_pipe_client *cli = NULL;
46         struct auth_session_info *session_info = NULL;
47         NTSTATUS status;
48
49         if (session_info == NULL) {
50                 status = make_session_info_system(mem_ctx, &session_info);
51                 if (!NT_STATUS_IS_OK(status)) {
52                         DEBUG(0, ("open_samr_pipe: Could not create auth_session_info: %s\n",
53                                   nt_errstr(status)));
54                         return status;
55                 }
56         }
57
58         /* create a samr connection */
59         status = rpc_pipe_open_internal(mem_ctx,
60                                         &ndr_table_samr.syntax_id,
61                                         session_info,
62                                         NULL,
63                                         winbind_messaging_context(),
64                                         &cli);
65         if (!NT_STATUS_IS_OK(status)) {
66                 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
67                           nt_errstr(status)));
68                 return status;
69         }
70
71         if (samr_pipe) {
72                 *samr_pipe = cli;
73         }
74
75         return NT_STATUS_OK;
76 }
77
78 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
79                                  struct winbindd_domain *domain,
80                                  struct rpc_pipe_client **samr_pipe,
81                                  struct policy_handle *samr_domain_hnd)
82 {
83         NTSTATUS status, result;
84         struct policy_handle samr_connect_hnd;
85         struct dcerpc_binding_handle *b;
86
87         status = open_internal_samr_pipe(mem_ctx, samr_pipe);
88         if (!NT_STATUS_IS_OK(status)) {
89                 return status;
90         }
91
92         b = (*samr_pipe)->binding_handle;
93
94         status = dcerpc_samr_Connect2(b, mem_ctx,
95                                       (*samr_pipe)->desthost,
96                                       SEC_FLAG_MAXIMUM_ALLOWED,
97                                       &samr_connect_hnd,
98                                       &result);
99         if (!NT_STATUS_IS_OK(status)) {
100                 return status;
101         }
102         if (!NT_STATUS_IS_OK(result)) {
103                 return result;
104         }
105
106         status = dcerpc_samr_OpenDomain(b, mem_ctx,
107                                         &samr_connect_hnd,
108                                         SEC_FLAG_MAXIMUM_ALLOWED,
109                                         &domain->sid,
110                                         samr_domain_hnd,
111                                         &result);
112         if (!NT_STATUS_IS_OK(status)) {
113                 return status;
114         }
115
116         return result;
117 }
118
119 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
120                                        struct rpc_pipe_client **lsa_pipe)
121 {
122         struct rpc_pipe_client *cli = NULL;
123         struct auth_session_info *session_info = NULL;
124         NTSTATUS status;
125
126         if (session_info == NULL) {
127                 status = make_session_info_system(mem_ctx, &session_info);
128                 if (!NT_STATUS_IS_OK(status)) {
129                         DEBUG(0, ("open_lsa_pipe: Could not create auth_session_info: %s\n",
130                                   nt_errstr(status)));
131                         return status;
132                 }
133         }
134
135         /* create a lsa connection */
136         status = rpc_pipe_open_internal(mem_ctx,
137                                         &ndr_table_lsarpc.syntax_id,
138                                         session_info,
139                                         NULL,
140                                         winbind_messaging_context(),
141                                         &cli);
142         if (!NT_STATUS_IS_OK(status)) {
143                 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
144                           nt_errstr(status)));
145                 return status;
146         }
147
148         if (lsa_pipe) {
149                 *lsa_pipe = cli;
150         }
151
152         return NT_STATUS_OK;
153 }
154
155 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
156                                        struct rpc_pipe_client **lsa_pipe,
157                                        struct policy_handle *lsa_hnd)
158 {
159         NTSTATUS status;
160
161         status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
162         if (!NT_STATUS_IS_OK(status)) {
163                 return status;
164         }
165
166         status = rpccli_lsa_open_policy((*lsa_pipe),
167                                         mem_ctx,
168                                         true,
169                                         SEC_FLAG_MAXIMUM_ALLOWED,
170                                         lsa_hnd);
171
172         return status;
173 }
174
175 /*********************************************************************
176  SAM specific functions.
177 *********************************************************************/
178
179 /* List all domain groups */
180 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
181                                     TALLOC_CTX *mem_ctx,
182                                     uint32_t *pnum_info,
183                                     struct wb_acct_info **pinfo)
184 {
185         struct rpc_pipe_client *samr_pipe;
186         struct policy_handle dom_pol;
187         struct wb_acct_info *info = NULL;
188         uint32_t num_info = 0;
189         TALLOC_CTX *tmp_ctx;
190         NTSTATUS status, result;
191         struct dcerpc_binding_handle *b = NULL;
192
193         DEBUG(3,("sam_enum_dom_groups\n"));
194
195         ZERO_STRUCT(dom_pol);
196
197         if (pnum_info) {
198                 *pnum_info = 0;
199         }
200
201         tmp_ctx = talloc_stackframe();
202         if (tmp_ctx == NULL) {
203                 return NT_STATUS_NO_MEMORY;
204         }
205
206         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
207         if (!NT_STATUS_IS_OK(status)) {
208                 goto error;
209         }
210
211         b = samr_pipe->binding_handle;
212
213         status = rpc_enum_dom_groups(tmp_ctx,
214                                      samr_pipe,
215                                      &dom_pol,
216                                      &num_info,
217                                      &info);
218         if (!NT_STATUS_IS_OK(status)) {
219                 goto error;
220         }
221
222         if (pnum_info) {
223                 *pnum_info = num_info;
224         }
225
226         if (pinfo) {
227                 *pinfo = talloc_move(mem_ctx, &info);
228         }
229
230 error:
231         if (b && is_valid_policy_hnd(&dom_pol)) {
232                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
233         }
234         TALLOC_FREE(tmp_ctx);
235         return status;
236 }
237
238 /* Query display info for a domain */
239 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
240                                     TALLOC_CTX *mem_ctx,
241                                     uint32_t *pnum_info,
242                                     struct wbint_userinfo **pinfo)
243 {
244         struct rpc_pipe_client *samr_pipe = NULL;
245         struct policy_handle dom_pol;
246         struct wbint_userinfo *info = NULL;
247         uint32_t num_info = 0;
248         TALLOC_CTX *tmp_ctx;
249         NTSTATUS status, result;
250         struct dcerpc_binding_handle *b = NULL;
251
252         DEBUG(3,("samr_query_user_list\n"));
253
254         ZERO_STRUCT(dom_pol);
255
256         if (pnum_info) {
257                 *pnum_info = 0;
258         }
259
260         tmp_ctx = talloc_stackframe();
261         if (tmp_ctx == NULL) {
262                 return NT_STATUS_NO_MEMORY;
263         }
264
265         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
266         if (!NT_STATUS_IS_OK(status)) {
267                 goto done;
268         }
269
270         b = samr_pipe->binding_handle;
271
272         status = rpc_query_user_list(tmp_ctx,
273                                      samr_pipe,
274                                      &dom_pol,
275                                      &domain->sid,
276                                      &num_info,
277                                      &info);
278         if (!NT_STATUS_IS_OK(status)) {
279                 goto done;
280         }
281
282         if (pnum_info) {
283                 *pnum_info = num_info;
284         }
285
286         if (pinfo) {
287                 *pinfo = talloc_move(mem_ctx, &info);
288         }
289
290 done:
291         if (b && is_valid_policy_hnd(&dom_pol)) {
292                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
293         }
294
295         TALLOC_FREE(tmp_ctx);
296         return status;
297 }
298
299 /* Lookup user information from a rid or username. */
300 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
301                                TALLOC_CTX *mem_ctx,
302                                const struct dom_sid *user_sid,
303                                struct wbint_userinfo *user_info)
304 {
305         struct rpc_pipe_client *samr_pipe;
306         struct policy_handle dom_pol;
307         TALLOC_CTX *tmp_ctx;
308         NTSTATUS status, result;
309         struct dcerpc_binding_handle *b = NULL;
310
311         DEBUG(3,("sam_query_user\n"));
312
313         ZERO_STRUCT(dom_pol);
314
315         /* Paranoia check */
316         if (!sid_check_is_in_our_domain(user_sid)) {
317                 return NT_STATUS_NO_SUCH_USER;
318         }
319
320         if (user_info) {
321                 user_info->homedir = NULL;
322                 user_info->shell = NULL;
323                 user_info->primary_gid = (gid_t) -1;
324         }
325
326         tmp_ctx = talloc_stackframe();
327         if (tmp_ctx == NULL) {
328                 return NT_STATUS_NO_MEMORY;
329         }
330
331         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
332         if (!NT_STATUS_IS_OK(status)) {
333                 goto done;
334         }
335
336         b = samr_pipe->binding_handle;
337
338         status = rpc_query_user(tmp_ctx,
339                                 samr_pipe,
340                                 &dom_pol,
341                                 &domain->sid,
342                                 user_sid,
343                                 user_info);
344
345 done:
346         if (b && is_valid_policy_hnd(&dom_pol)) {
347                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
348         }
349
350         TALLOC_FREE(tmp_ctx);
351         return status;
352 }
353
354 /* get a list of trusted domains - builtin domain */
355 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
356                                     TALLOC_CTX *mem_ctx,
357                                     struct netr_DomainTrustList *ptrust_list)
358 {
359         struct rpc_pipe_client *lsa_pipe;
360         struct policy_handle lsa_policy;
361         struct netr_DomainTrust *trusts = NULL;
362         uint32_t num_trusts = 0;
363         TALLOC_CTX *tmp_ctx;
364         NTSTATUS status, result;
365         struct dcerpc_binding_handle *b = NULL;
366
367         DEBUG(3,("samr: trusted domains\n"));
368
369         ZERO_STRUCT(lsa_policy);
370
371         if (ptrust_list) {
372                 ZERO_STRUCTP(ptrust_list);
373         }
374
375         tmp_ctx = talloc_stackframe();
376         if (tmp_ctx == NULL) {
377                 return NT_STATUS_NO_MEMORY;
378         }
379
380         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
381         if (!NT_STATUS_IS_OK(status)) {
382                 goto done;
383         }
384
385         b = lsa_pipe->binding_handle;
386
387         status = rpc_trusted_domains(tmp_ctx,
388                                      lsa_pipe,
389                                      &lsa_policy,
390                                      &num_trusts,
391                                      &trusts);
392         if (!NT_STATUS_IS_OK(status)) {
393                 goto done;
394         }
395
396         if (ptrust_list) {
397                 ptrust_list->count = num_trusts;
398                 ptrust_list->array = talloc_move(mem_ctx, &trusts);
399         }
400
401 done:
402         if (b && is_valid_policy_hnd(&lsa_policy)) {
403                 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
404         }
405
406         TALLOC_FREE(tmp_ctx);
407         return status;
408 }
409
410 /* Lookup group membership given a rid.   */
411 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
412                                     TALLOC_CTX *mem_ctx,
413                                     const struct dom_sid *group_sid,
414                                     enum lsa_SidType type,
415                                     uint32_t *pnum_names,
416                                     struct dom_sid **psid_mem,
417                                     char ***pnames,
418                                     uint32_t **pname_types)
419 {
420         struct rpc_pipe_client *samr_pipe;
421         struct policy_handle dom_pol;
422
423         uint32_t num_names = 0;
424         struct dom_sid *sid_mem = NULL;
425         char **names = NULL;
426         uint32_t *name_types = NULL;
427
428         TALLOC_CTX *tmp_ctx;
429         NTSTATUS status, result;
430         struct dcerpc_binding_handle *b = NULL;
431
432         DEBUG(3,("sam_lookup_groupmem\n"));
433
434         ZERO_STRUCT(dom_pol);
435
436         /* Paranoia check */
437         if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
438                 /* There's no groups, only aliases in BUILTIN */
439                 return NT_STATUS_NO_SUCH_GROUP;
440         }
441
442         if (pnum_names) {
443                 *pnum_names = 0;
444         }
445
446         tmp_ctx = talloc_stackframe();
447         if (tmp_ctx == NULL) {
448                 return NT_STATUS_NO_MEMORY;
449         }
450
451         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
452         if (!NT_STATUS_IS_OK(status)) {
453                 goto done;
454         }
455
456         b = samr_pipe->binding_handle;
457
458         status = rpc_lookup_groupmem(tmp_ctx,
459                                      samr_pipe,
460                                      &dom_pol,
461                                      domain->name,
462                                      &domain->sid,
463                                      group_sid,
464                                      type,
465                                      &num_names,
466                                      &sid_mem,
467                                      &names,
468                                      &name_types);
469
470         if (pnum_names) {
471                 *pnum_names = num_names;
472         }
473
474         if (pnames) {
475                 *pnames = talloc_move(mem_ctx, &names);
476         }
477
478         if (pname_types) {
479                 *pname_types = talloc_move(mem_ctx, &name_types);
480         }
481
482         if (psid_mem) {
483                 *psid_mem = talloc_move(mem_ctx, &sid_mem);
484         }
485
486 done:
487         if (b && is_valid_policy_hnd(&dom_pol)) {
488                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
489         }
490
491         TALLOC_FREE(tmp_ctx);
492         return status;
493 }
494
495 /*********************************************************************
496  BUILTIN specific functions.
497 *********************************************************************/
498
499 /* List all domain groups */
500 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
501                                 TALLOC_CTX *mem_ctx,
502                                 uint32 *num_entries,
503                                 struct wb_acct_info **info)
504 {
505         /* BUILTIN doesn't have domain groups */
506         *num_entries = 0;
507         *info = NULL;
508         return NT_STATUS_OK;
509 }
510
511 /* Query display info for a domain */
512 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
513                                 TALLOC_CTX *mem_ctx,
514                                 uint32 *num_entries,
515                                 struct wbint_userinfo **info)
516 {
517         /* We don't have users */
518         *num_entries = 0;
519         *info = NULL;
520         return NT_STATUS_OK;
521 }
522
523 /* Lookup user information from a rid or username. */
524 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
525                                 TALLOC_CTX *mem_ctx,
526                                 const struct dom_sid *user_sid,
527                                 struct wbint_userinfo *user_info)
528 {
529         return NT_STATUS_NO_SUCH_USER;
530 }
531
532 /* get a list of trusted domains - builtin domain */
533 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
534                                         TALLOC_CTX *mem_ctx,
535                                         struct netr_DomainTrustList *trusts)
536 {
537         ZERO_STRUCTP(trusts);
538         return NT_STATUS_OK;
539 }
540
541 /*********************************************************************
542  COMMON functions.
543 *********************************************************************/
544
545 /* List all local groups (aliases) */
546 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
547                                       TALLOC_CTX *mem_ctx,
548                                       uint32_t *pnum_info,
549                                       struct wb_acct_info **pinfo)
550 {
551         struct rpc_pipe_client *samr_pipe;
552         struct policy_handle dom_pol;
553         struct wb_acct_info *info = NULL;
554         uint32_t num_info = 0;
555         TALLOC_CTX *tmp_ctx;
556         NTSTATUS status, result;
557         struct dcerpc_binding_handle *b = NULL;
558
559         DEBUG(3,("samr: enum local groups\n"));
560
561         ZERO_STRUCT(dom_pol);
562
563         if (pnum_info) {
564                 *pnum_info = 0;
565         }
566
567         tmp_ctx = talloc_stackframe();
568         if (tmp_ctx == NULL) {
569                 return NT_STATUS_NO_MEMORY;
570         }
571
572         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
573         if (!NT_STATUS_IS_OK(status)) {
574                 goto done;
575         }
576
577         b = samr_pipe->binding_handle;
578
579         status = rpc_enum_local_groups(mem_ctx,
580                                        samr_pipe,
581                                        &dom_pol,
582                                        &num_info,
583                                        &info);
584         if (!NT_STATUS_IS_OK(status)) {
585                 goto done;
586         }
587
588         if (pnum_info) {
589                 *pnum_info = num_info;
590         }
591
592         if (pinfo) {
593                 *pinfo = talloc_move(mem_ctx, &info);
594         }
595
596 done:
597         if (b && is_valid_policy_hnd(&dom_pol)) {
598                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
599         }
600
601         TALLOC_FREE(tmp_ctx);
602         return status;
603 }
604
605 /* convert a single name to a sid in a domain */
606 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
607                                    TALLOC_CTX *mem_ctx,
608                                    const char *domain_name,
609                                    const char *name,
610                                    uint32_t flags,
611                                    struct dom_sid *psid,
612                                    enum lsa_SidType *ptype)
613 {
614         struct rpc_pipe_client *lsa_pipe;
615         struct policy_handle lsa_policy;
616         struct dom_sid sid;
617         enum lsa_SidType type;
618         TALLOC_CTX *tmp_ctx;
619         NTSTATUS status, result;
620         struct dcerpc_binding_handle *b = NULL;
621
622         DEBUG(3,("sam_name_to_sid\n"));
623
624         ZERO_STRUCT(lsa_policy);
625
626         tmp_ctx = talloc_stackframe();
627         if (tmp_ctx == NULL) {
628                 return NT_STATUS_NO_MEMORY;
629         }
630
631         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
632         if (!NT_STATUS_IS_OK(status)) {
633                 goto done;
634         }
635
636         b = lsa_pipe->binding_handle;
637
638         status = rpc_name_to_sid(tmp_ctx,
639                                  lsa_pipe,
640                                  &lsa_policy,
641                                  domain_name,
642                                  name,
643                                  flags,
644                                  &sid,
645                                  &type);
646         if (!NT_STATUS_IS_OK(status)) {
647                 goto done;
648         }
649
650         if (psid) {
651                 sid_copy(psid, &sid);
652         }
653         if (ptype) {
654                 *ptype = type;
655         }
656
657 done:
658         if (b && is_valid_policy_hnd(&lsa_policy)) {
659                 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
660         }
661
662         TALLOC_FREE(tmp_ctx);
663         return status;
664 }
665
666 /* convert a domain SID to a user or group name */
667 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
668                                 TALLOC_CTX *mem_ctx,
669                                 const struct dom_sid *sid,
670                                 char **pdomain_name,
671                                 char **pname,
672                                 enum lsa_SidType *ptype)
673 {
674         struct rpc_pipe_client *lsa_pipe;
675         struct policy_handle lsa_policy;
676         char *domain_name = NULL;
677         char *name = NULL;
678         enum lsa_SidType type;
679         TALLOC_CTX *tmp_ctx;
680         NTSTATUS status, result;
681         struct dcerpc_binding_handle *b = NULL;
682
683         DEBUG(3,("sam_sid_to_name\n"));
684
685         ZERO_STRUCT(lsa_policy);
686
687         /* Paranoia check */
688         if (!sid_check_is_in_builtin(sid) &&
689             !sid_check_is_in_our_domain(sid) &&
690             !sid_check_is_in_unix_users(sid) &&
691             !sid_check_is_unix_users(sid) &&
692             !sid_check_is_in_unix_groups(sid) &&
693             !sid_check_is_unix_groups(sid) &&
694             !sid_check_is_in_wellknown_domain(sid)) {
695                 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
696                           "lookup SID %s\n", sid_string_dbg(sid)));
697                 return NT_STATUS_NONE_MAPPED;
698         }
699
700         tmp_ctx = talloc_stackframe();
701         if (tmp_ctx == NULL) {
702                 return NT_STATUS_NO_MEMORY;
703         }
704
705         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
706         if (!NT_STATUS_IS_OK(status)) {
707                 goto done;
708         }
709
710         b = lsa_pipe->binding_handle;
711
712         status = rpc_sid_to_name(tmp_ctx,
713                                  lsa_pipe,
714                                  &lsa_policy,
715                                  domain,
716                                  sid,
717                                  &domain_name,
718                                  &name,
719                                  &type);
720
721         if (ptype) {
722                 *ptype = type;
723         }
724
725         if (pname) {
726                 *pname = talloc_move(mem_ctx, &name);
727         }
728
729         if (pdomain_name) {
730                 *pdomain_name = talloc_move(mem_ctx, &domain_name);
731         }
732
733 done:
734         if (b && is_valid_policy_hnd(&lsa_policy)) {
735                 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
736         }
737
738         TALLOC_FREE(tmp_ctx);
739         return status;
740 }
741
742 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
743                                   TALLOC_CTX *mem_ctx,
744                                   const struct dom_sid *domain_sid,
745                                   uint32 *rids,
746                                   size_t num_rids,
747                                   char **pdomain_name,
748                                   char ***pnames,
749                                   enum lsa_SidType **ptypes)
750 {
751         struct rpc_pipe_client *lsa_pipe;
752         struct policy_handle lsa_policy;
753         enum lsa_SidType *types = NULL;
754         char *domain_name = NULL;
755         char **names = NULL;
756         TALLOC_CTX *tmp_ctx;
757         NTSTATUS status, result;
758         struct dcerpc_binding_handle *b = NULL;
759
760         DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
761
762         ZERO_STRUCT(lsa_policy);
763
764         /* Paranoia check */
765         if (!sid_check_is_builtin(domain_sid) &&
766             !sid_check_is_domain(domain_sid) &&
767             !sid_check_is_unix_users(domain_sid) &&
768             !sid_check_is_unix_groups(domain_sid) &&
769             !sid_check_is_in_wellknown_domain(domain_sid)) {
770                 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
771                           "lookup SID %s\n", sid_string_dbg(domain_sid)));
772                 return NT_STATUS_NONE_MAPPED;
773         }
774
775         tmp_ctx = talloc_stackframe();
776         if (tmp_ctx == NULL) {
777                 return NT_STATUS_NO_MEMORY;
778         }
779
780         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
781         if (!NT_STATUS_IS_OK(status)) {
782                 goto done;
783         }
784
785         b = lsa_pipe->binding_handle;
786
787         status = rpc_rids_to_names(tmp_ctx,
788                                    lsa_pipe,
789                                    &lsa_policy,
790                                    domain,
791                                    domain_sid,
792                                    rids,
793                                    num_rids,
794                                    &domain_name,
795                                    &names,
796                                    &types);
797         if (!NT_STATUS_IS_OK(status)) {
798                 goto done;
799         }
800
801         if (pdomain_name) {
802                 *pdomain_name = talloc_move(mem_ctx, &domain_name);
803         }
804
805         if (ptypes) {
806                 *ptypes = talloc_move(mem_ctx, &types);
807         }
808
809         if (pnames) {
810                 *pnames = talloc_move(mem_ctx, &names);
811         }
812
813 done:
814         if (b && is_valid_policy_hnd(&lsa_policy)) {
815                 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
816         }
817
818         TALLOC_FREE(tmp_ctx);
819         return status;
820 }
821
822 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
823                                    TALLOC_CTX *mem_ctx,
824                                    struct samr_DomInfo12 *lockout_policy)
825 {
826         struct rpc_pipe_client *samr_pipe;
827         struct policy_handle dom_pol;
828         union samr_DomainInfo *info = NULL;
829         TALLOC_CTX *tmp_ctx;
830         NTSTATUS status, result;
831         struct dcerpc_binding_handle *b = NULL;
832
833         DEBUG(3,("sam_lockout_policy\n"));
834
835         ZERO_STRUCT(dom_pol);
836
837         tmp_ctx = talloc_stackframe();
838         if (tmp_ctx == NULL) {
839                 return NT_STATUS_NO_MEMORY;
840         }
841
842         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
843         if (!NT_STATUS_IS_OK(status)) {
844                 goto error;
845         }
846
847         b = samr_pipe->binding_handle;
848
849         status = dcerpc_samr_QueryDomainInfo(b,
850                                              mem_ctx,
851                                              &dom_pol,
852                                              12,
853                                              &info,
854                                              &result);
855         if (!NT_STATUS_IS_OK(status)) {
856                 goto error;
857         }
858         if (!NT_STATUS_IS_OK(result)) {
859                 status = result;
860                 goto error;
861         }
862
863         *lockout_policy = info->info12;
864
865 error:
866         if (b && is_valid_policy_hnd(&dom_pol)) {
867                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
868         }
869
870         TALLOC_FREE(tmp_ctx);
871         return status;
872 }
873
874 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
875                                     TALLOC_CTX *mem_ctx,
876                                     struct samr_DomInfo1 *passwd_policy)
877 {
878         struct rpc_pipe_client *samr_pipe;
879         struct policy_handle dom_pol;
880         union samr_DomainInfo *info = NULL;
881         TALLOC_CTX *tmp_ctx;
882         NTSTATUS status, result;
883         struct dcerpc_binding_handle *b = NULL;
884
885         DEBUG(3,("sam_password_policy\n"));
886
887         ZERO_STRUCT(dom_pol);
888
889         tmp_ctx = talloc_stackframe();
890         if (tmp_ctx == NULL) {
891                 return NT_STATUS_NO_MEMORY;
892         }
893
894         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
895         if (!NT_STATUS_IS_OK(status)) {
896                 goto error;
897         }
898
899         b = samr_pipe->binding_handle;
900
901         status = dcerpc_samr_QueryDomainInfo(b,
902                                              mem_ctx,
903                                              &dom_pol,
904                                              1,
905                                              &info,
906                                              &result);
907         if (!NT_STATUS_IS_OK(status)) {
908                 goto error;
909         }
910         if (!NT_STATUS_IS_OK(result)) {
911                 status = result;
912                 goto error;
913         }
914
915         *passwd_policy = info->info1;
916
917 error:
918         if (b && is_valid_policy_hnd(&dom_pol)) {
919                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
920         }
921
922         TALLOC_FREE(tmp_ctx);
923         return status;
924 }
925
926 /* Lookup groups a user is a member of. */
927 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
928                                       TALLOC_CTX *mem_ctx,
929                                       const struct dom_sid *user_sid,
930                                       uint32_t *pnum_groups,
931                                       struct dom_sid **puser_grpsids)
932 {
933         struct rpc_pipe_client *samr_pipe;
934         struct policy_handle dom_pol;
935         struct dom_sid *user_grpsids = NULL;
936         uint32_t num_groups = 0;
937         TALLOC_CTX *tmp_ctx;
938         NTSTATUS status, result;
939         struct dcerpc_binding_handle *b = NULL;
940
941         DEBUG(3,("sam_lookup_usergroups\n"));
942
943         ZERO_STRUCT(dom_pol);
944
945         if (pnum_groups) {
946                 *pnum_groups = 0;
947         }
948
949         tmp_ctx = talloc_stackframe();
950         if (tmp_ctx == NULL) {
951                 return NT_STATUS_NO_MEMORY;
952         }
953
954         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
955         if (!NT_STATUS_IS_OK(status)) {
956                 goto done;
957         }
958
959         b = samr_pipe->binding_handle;
960
961         status = rpc_lookup_usergroups(tmp_ctx,
962                                        samr_pipe,
963                                        &dom_pol,
964                                        &domain->sid,
965                                        user_sid,
966                                        &num_groups,
967                                        &user_grpsids);
968         if (!NT_STATUS_IS_OK(status)) {
969                 goto done;
970         }
971
972         if (pnum_groups) {
973                 *pnum_groups = num_groups;
974         }
975
976         if (puser_grpsids) {
977                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
978         }
979
980 done:
981         if (b && is_valid_policy_hnd(&dom_pol)) {
982                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
983         }
984
985         TALLOC_FREE(tmp_ctx);
986         return status;
987 }
988
989 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
990                                        TALLOC_CTX *mem_ctx,
991                                        uint32_t num_sids,
992                                        const struct dom_sid *sids,
993                                        uint32_t *pnum_aliases,
994                                        uint32_t **palias_rids)
995 {
996         struct rpc_pipe_client *samr_pipe;
997         struct policy_handle dom_pol;
998         uint32_t num_aliases = 0;
999         uint32_t *alias_rids = NULL;
1000         TALLOC_CTX *tmp_ctx;
1001         NTSTATUS status, result;
1002         struct dcerpc_binding_handle *b = NULL;
1003
1004         DEBUG(3,("sam_lookup_useraliases\n"));
1005
1006         ZERO_STRUCT(dom_pol);
1007
1008         if (pnum_aliases) {
1009                 *pnum_aliases = 0;
1010         }
1011
1012         tmp_ctx = talloc_stackframe();
1013         if (tmp_ctx == NULL) {
1014                 return NT_STATUS_NO_MEMORY;
1015         }
1016
1017         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1018         if (!NT_STATUS_IS_OK(status)) {
1019                 goto done;
1020         }
1021
1022         b = samr_pipe->binding_handle;
1023
1024         status = rpc_lookup_useraliases(tmp_ctx,
1025                                         samr_pipe,
1026                                         &dom_pol,
1027                                         num_sids,
1028                                         sids,
1029                                         &num_aliases,
1030                                         &alias_rids);
1031         if (!NT_STATUS_IS_OK(status)) {
1032                 goto done;
1033         }
1034
1035         if (pnum_aliases) {
1036                 *pnum_aliases = num_aliases;
1037         }
1038
1039         if (palias_rids) {
1040                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1041         }
1042
1043 done:
1044         if (b && is_valid_policy_hnd(&dom_pol)) {
1045                 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1046         }
1047
1048         TALLOC_FREE(tmp_ctx);
1049         return status;
1050 }
1051
1052 /* find the sequence number for a domain */
1053 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1054                                     uint32_t *pseq)
1055 {
1056         struct rpc_pipe_client *samr_pipe;
1057         struct policy_handle dom_pol;
1058         uint32_t seq;
1059         TALLOC_CTX *tmp_ctx;
1060         NTSTATUS status, result;
1061         struct dcerpc_binding_handle *b = NULL;
1062
1063         DEBUG(3,("samr: sequence number\n"));
1064
1065         ZERO_STRUCT(dom_pol);
1066
1067         if (pseq) {
1068                 *pseq = DOM_SEQUENCE_NONE;
1069         }
1070
1071         tmp_ctx = talloc_stackframe();
1072         if (tmp_ctx == NULL) {
1073                 return NT_STATUS_NO_MEMORY;
1074         }
1075
1076         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1077         if (!NT_STATUS_IS_OK(status)) {
1078                 goto done;
1079         }
1080
1081         b = samr_pipe->binding_handle;
1082
1083         status = rpc_sequence_number(tmp_ctx,
1084                                      samr_pipe,
1085                                      &dom_pol,
1086                                      domain->name,
1087                                      &seq);
1088         if (!NT_STATUS_IS_OK(status)) {
1089                 goto done;
1090         }
1091
1092         if (pseq) {
1093                 *pseq = seq;
1094         }
1095 done:
1096         if (b && is_valid_policy_hnd(&dom_pol)) {
1097                 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
1098         }
1099
1100         TALLOC_FREE(tmp_ctx);
1101         return status;
1102 }
1103
1104 /* the rpc backend methods are exposed via this structure */
1105 struct winbindd_methods builtin_passdb_methods = {
1106         .consistent            = false,
1107
1108         .query_user_list       = builtin_query_user_list,
1109         .enum_dom_groups       = builtin_enum_dom_groups,
1110         .enum_local_groups     = sam_enum_local_groups,
1111         .name_to_sid           = sam_name_to_sid,
1112         .sid_to_name           = sam_sid_to_name,
1113         .rids_to_names         = sam_rids_to_names,
1114         .query_user            = builtin_query_user,
1115         .lookup_usergroups     = sam_lookup_usergroups,
1116         .lookup_useraliases    = sam_lookup_useraliases,
1117         .lookup_groupmem       = sam_lookup_groupmem,
1118         .sequence_number       = sam_sequence_number,
1119         .lockout_policy        = sam_lockout_policy,
1120         .password_policy       = sam_password_policy,
1121         .trusted_domains       = builtin_trusted_domains
1122 };
1123
1124 /* the rpc backend methods are exposed via this structure */
1125 struct winbindd_methods sam_passdb_methods = {
1126         .consistent            = false,
1127
1128         .query_user_list       = sam_query_user_list,
1129         .enum_dom_groups       = sam_enum_dom_groups,
1130         .enum_local_groups     = sam_enum_local_groups,
1131         .name_to_sid           = sam_name_to_sid,
1132         .sid_to_name           = sam_sid_to_name,
1133         .rids_to_names         = sam_rids_to_names,
1134         .query_user            = sam_query_user,
1135         .lookup_usergroups     = sam_lookup_usergroups,
1136         .lookup_useraliases    = sam_lookup_useraliases,
1137         .lookup_groupmem       = sam_lookup_groupmem,
1138         .sequence_number       = sam_sequence_number,
1139         .lockout_policy        = sam_lockout_policy,
1140         .password_policy       = sam_password_policy,
1141         .trusted_domains       = sam_trusted_domains
1142 };