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