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