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