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