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