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