s3-winbind: Rename common_lockout_policy to sam_lockout_policy.
[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
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 static 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_samr_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_samr_pipe: Could not connect to samr_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         if (pnum_info) {
192                 *pnum_info = 0;
193         }
194
195         tmp_ctx = talloc_stackframe();
196         if (tmp_ctx == NULL) {
197                 return NT_STATUS_NO_MEMORY;
198         }
199
200         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
201         if (!NT_STATUS_IS_OK(status)) {
202                 goto error;
203         }
204
205         status = rpc_enum_dom_groups(tmp_ctx,
206                                      samr_pipe,
207                                      &dom_pol,
208                                      &num_info,
209                                      &info);
210         if (!NT_STATUS_IS_OK(status)) {
211                 goto error;
212         }
213
214         if (pnum_info) {
215                 *pnum_info = num_info;
216         }
217
218         if (pinfo) {
219                 *pinfo = talloc_move(mem_ctx, &info);
220         }
221
222 error:
223         TALLOC_FREE(tmp_ctx);
224         return status;
225 }
226
227 /* Query display info for a domain */
228 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
229                                     TALLOC_CTX *mem_ctx,
230                                     uint32_t *pnum_info,
231                                     struct wbint_userinfo **pinfo)
232 {
233         struct rpc_pipe_client *samr_pipe = NULL;
234         struct policy_handle dom_pol;
235         struct wbint_userinfo *info = NULL;
236         uint32_t num_info = 0;
237         TALLOC_CTX *tmp_ctx;
238         NTSTATUS status;
239
240         DEBUG(3,("samr_query_user_list\n"));
241
242         if (pnum_info) {
243                 *pnum_info = 0;
244         }
245
246         tmp_ctx = talloc_stackframe();
247         if (tmp_ctx == NULL) {
248                 return NT_STATUS_NO_MEMORY;
249         }
250
251         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
252         if (!NT_STATUS_IS_OK(status)) {
253                 goto done;
254         }
255
256         status = rpc_query_user_list(tmp_ctx,
257                                      samr_pipe,
258                                      &dom_pol,
259                                      &domain->sid,
260                                      &num_info,
261                                      &info);
262         if (!NT_STATUS_IS_OK(status)) {
263                 goto done;
264         }
265
266         if (pnum_info) {
267                 *pnum_info = num_info;
268         }
269
270         if (pinfo) {
271                 *pinfo = talloc_move(mem_ctx, &info);
272         }
273
274 done:
275         TALLOC_FREE(tmp_ctx);
276         return status;
277 }
278
279 /* Lookup user information from a rid or username. */
280 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
281                                TALLOC_CTX *mem_ctx,
282                                const struct dom_sid *user_sid,
283                                struct wbint_userinfo *user_info)
284 {
285         struct rpc_pipe_client *samr_pipe;
286         struct policy_handle dom_pol;
287         TALLOC_CTX *tmp_ctx;
288         NTSTATUS status;
289
290         DEBUG(3,("sam_query_user\n"));
291
292         /* Paranoia check */
293         if (!sid_check_is_in_our_domain(user_sid)) {
294                 return NT_STATUS_NO_SUCH_USER;
295         }
296
297         if (user_info) {
298                 user_info->homedir = NULL;
299                 user_info->shell = NULL;
300                 user_info->primary_gid = (gid_t) -1;
301         }
302
303         tmp_ctx = talloc_stackframe();
304         if (tmp_ctx == NULL) {
305                 return NT_STATUS_NO_MEMORY;
306         }
307
308         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
309         if (!NT_STATUS_IS_OK(status)) {
310                 goto done;
311         }
312
313         status = rpc_query_user(tmp_ctx,
314                                 samr_pipe,
315                                 &dom_pol,
316                                 &domain->sid,
317                                 user_sid,
318                                 user_info);
319
320 done:
321         TALLOC_FREE(tmp_ctx);
322         return status;
323 }
324
325 /* get a list of trusted domains - builtin domain */
326 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
327                                     TALLOC_CTX *mem_ctx,
328                                     struct netr_DomainTrustList *trusts)
329 {
330         struct rpc_pipe_client *lsa_pipe;
331         struct netr_DomainTrust *array = NULL;
332         struct policy_handle lsa_policy;
333         uint32_t enum_ctx = 0;
334         uint32_t count = 0;
335         TALLOC_CTX *tmp_ctx;
336         NTSTATUS status;
337
338         DEBUG(3,("samr: trusted domains\n"));
339
340         tmp_ctx = talloc_stackframe();
341         if (tmp_ctx == NULL) {
342                 return NT_STATUS_NO_MEMORY;
343         }
344
345         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
346         if (!NT_STATUS_IS_OK(status)) {
347                 goto error;
348         }
349
350         do {
351                 struct lsa_DomainList dom_list;
352                 uint32_t start_idx;
353                 uint32_t i;
354
355                 /*
356                  * We don't run into deadlocks here, cause winbind_off() is
357                  * called in the main function.
358                  */
359                 status = rpccli_lsa_EnumTrustDom(lsa_pipe,
360                                                  tmp_ctx,
361                                                  &lsa_policy,
362                                                  &enum_ctx,
363                                                  &dom_list,
364                                                  (uint32_t) -1);
365                 if (!NT_STATUS_IS_OK(status)) {
366                         if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
367                                 goto error;
368                         }
369                 }
370
371                 start_idx = trusts->count;
372                 count += dom_list.count;
373
374                 array = talloc_realloc(tmp_ctx,
375                                        array,
376                                        struct netr_DomainTrust,
377                                        count);
378                 if (array == NULL) {
379                         status = NT_STATUS_NO_MEMORY;
380                         goto error;
381                 }
382
383                 for (i = 0; i < dom_list.count; i++) {
384                         struct netr_DomainTrust *trust = &array[i];
385                         struct dom_sid *sid;
386
387                         ZERO_STRUCTP(trust);
388
389                         trust->netbios_name = talloc_move(array,
390                                                           &dom_list.domains[i].name.string);
391                         trust->dns_name = NULL;
392
393                         sid = talloc(array, struct dom_sid);
394                         if (sid == NULL) {
395                                 status = NT_STATUS_NO_MEMORY;
396                                 goto error;
397                         }
398                         sid_copy(sid, dom_list.domains[i].sid);
399                         trust->sid = sid;
400                 }
401         } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
402
403         if (trusts) {
404                 trusts->count = count;
405                 trusts->array = talloc_move(mem_ctx, &array);
406         }
407
408 error:
409         TALLOC_FREE(tmp_ctx);
410         return status;
411 }
412
413 /* Lookup group membership given a rid.   */
414 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
415                                     TALLOC_CTX *mem_ctx,
416                                     const struct dom_sid *group_sid,
417                                     enum lsa_SidType type,
418                                     uint32_t *pnum_names,
419                                     struct dom_sid **psid_mem,
420                                     char ***pnames,
421                                     uint32_t **pname_types)
422 {
423         struct rpc_pipe_client *samr_pipe;
424         struct policy_handle dom_pol;
425
426         uint32_t num_names = 0;
427         struct dom_sid *sid_mem = NULL;
428         char **names = NULL;
429         uint32_t *name_types = NULL;
430
431         TALLOC_CTX *tmp_ctx;
432         NTSTATUS status;
433
434         DEBUG(3,("sam_lookup_groupmem\n"));
435
436         /* Paranoia check */
437         if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
438                 /* There's no groups, only aliases in BUILTIN */
439                 return NT_STATUS_NO_SUCH_GROUP;
440         }
441
442         if (pnum_names) {
443                 pnum_names = 0;
444         }
445
446         tmp_ctx = talloc_stackframe();
447         if (tmp_ctx == NULL) {
448                 return NT_STATUS_NO_MEMORY;
449         }
450
451         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
452         if (!NT_STATUS_IS_OK(status)) {
453                 goto done;
454         }
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         TALLOC_FREE(tmp_ctx);
486         return status;
487 }
488
489 /*********************************************************************
490  BUILTIN specific functions.
491 *********************************************************************/
492
493 /* List all domain groups */
494 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
495                                 TALLOC_CTX *mem_ctx,
496                                 uint32 *num_entries,
497                                 struct acct_info **info)
498 {
499         /* BUILTIN doesn't have domain groups */
500         *num_entries = 0;
501         *info = NULL;
502         return NT_STATUS_OK;
503 }
504
505 /* Query display info for a domain */
506 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
507                                 TALLOC_CTX *mem_ctx,
508                                 uint32 *num_entries,
509                                 struct wbint_userinfo **info)
510 {
511         /* We don't have users */
512         *num_entries = 0;
513         *info = NULL;
514         return NT_STATUS_OK;
515 }
516
517 /* Lookup user information from a rid or username. */
518 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
519                                 TALLOC_CTX *mem_ctx,
520                                 const struct dom_sid *user_sid,
521                                 struct wbint_userinfo *user_info)
522 {
523         return NT_STATUS_NO_SUCH_USER;
524 }
525
526 /* get a list of trusted domains - builtin domain */
527 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
528                                         TALLOC_CTX *mem_ctx,
529                                         struct netr_DomainTrustList *trusts)
530 {
531         ZERO_STRUCTP(trusts);
532         return NT_STATUS_OK;
533 }
534
535 /*********************************************************************
536  COMMON functions.
537 *********************************************************************/
538
539 /* List all local groups (aliases) */
540 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
541                                       TALLOC_CTX *mem_ctx,
542                                       uint32_t *pnum_info,
543                                       struct acct_info **pinfo)
544 {
545         struct rpc_pipe_client *samr_pipe;
546         struct policy_handle dom_pol;
547         struct acct_info *info = NULL;
548         uint32_t num_info = 0;
549         TALLOC_CTX *tmp_ctx;
550         NTSTATUS status;
551
552         DEBUG(3,("samr: enum local groups\n"));
553
554         if (pnum_info) {
555                 *pnum_info = 0;
556         }
557
558         tmp_ctx = talloc_stackframe();
559         if (tmp_ctx == NULL) {
560                 return NT_STATUS_NO_MEMORY;
561         }
562
563         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
564         if (!NT_STATUS_IS_OK(status)) {
565                 goto done;
566         }
567
568         status = rpc_enum_local_groups(mem_ctx,
569                                        samr_pipe,
570                                        &dom_pol,
571                                        &num_info,
572                                        &info);
573         if (!NT_STATUS_IS_OK(status)) {
574                 goto done;
575         }
576
577         if (pnum_info) {
578                 *pnum_info = num_info;
579         }
580
581         if (pinfo) {
582                 *pinfo = talloc_move(mem_ctx, &info);
583         }
584
585 done:
586         TALLOC_FREE(tmp_ctx);
587         return status;
588 }
589
590 /* convert a single name to a sid in a domain */
591 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
592                                    TALLOC_CTX *mem_ctx,
593                                    const char *domain_name,
594                                    const char *name,
595                                    uint32_t flags,
596                                    struct dom_sid *psid,
597                                    enum lsa_SidType *ptype)
598 {
599         struct rpc_pipe_client *lsa_pipe;
600         struct policy_handle lsa_policy;
601         struct dom_sid sid;
602         enum lsa_SidType type;
603         TALLOC_CTX *tmp_ctx;
604         NTSTATUS status;
605
606         DEBUG(3,("sam_name_to_sid\n"));
607
608         tmp_ctx = talloc_stackframe();
609         if (tmp_ctx == NULL) {
610                 return NT_STATUS_NO_MEMORY;
611         }
612
613         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
614         if (!NT_STATUS_IS_OK(status)) {
615                 goto done;
616         }
617
618         status = rpc_name_to_sid(tmp_ctx,
619                                  lsa_pipe,
620                                  &lsa_policy,
621                                  domain_name,
622                                  name,
623                                  flags,
624                                  &sid,
625                                  &type);
626         if (!NT_STATUS_IS_OK(status)) {
627                 goto done;
628         }
629
630         if (psid) {
631                 sid_copy(psid, &sid);
632         }
633         if (ptype) {
634                 *ptype = type;
635         }
636
637 done:
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         /* Paranoia check */
661         if (!sid_check_is_in_builtin(sid) &&
662             !sid_check_is_in_our_domain(sid) &&
663             !sid_check_is_in_unix_users(sid) &&
664             !sid_check_is_unix_users(sid) &&
665             !sid_check_is_in_unix_groups(sid) &&
666             !sid_check_is_unix_groups(sid) &&
667             !sid_check_is_in_wellknown_domain(sid)) {
668                 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
669                           "lookup SID %s\n", sid_string_dbg(sid)));
670                 return NT_STATUS_NONE_MAPPED;
671         }
672
673         tmp_ctx = talloc_stackframe();
674         if (tmp_ctx == NULL) {
675                 return NT_STATUS_NO_MEMORY;
676         }
677
678         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
679         if (!NT_STATUS_IS_OK(status)) {
680                 goto done;
681         }
682
683         status = rpc_sid_to_name(tmp_ctx,
684                                  lsa_pipe,
685                                  &lsa_policy,
686                                  domain,
687                                  sid,
688                                  &domain_name,
689                                  &name,
690                                  &type);
691
692         if (ptype) {
693                 *ptype = type;
694         }
695
696         if (pname) {
697                 *pname = talloc_move(mem_ctx, &name);
698         }
699
700         if (pdomain_name) {
701                 *pdomain_name = talloc_move(mem_ctx, &domain_name);
702         }
703
704 done:
705         TALLOC_FREE(tmp_ctx);
706         return status;
707 }
708
709 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
710                                   TALLOC_CTX *mem_ctx,
711                                   const struct dom_sid *sid,
712                                   uint32 *rids,
713                                   size_t num_rids,
714                                   char **pdomain_name,
715                                   char ***pnames,
716                                   enum lsa_SidType **ptypes)
717 {
718         struct rpc_pipe_client *lsa_pipe;
719         struct policy_handle lsa_policy;
720         enum lsa_SidType *types = NULL;
721         char *domain_name = NULL;
722         char **names = NULL;
723         TALLOC_CTX *tmp_ctx;
724         NTSTATUS status;
725
726         DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
727
728         /* Paranoia check */
729         if (!sid_check_is_in_builtin(sid) &&
730             !sid_check_is_in_our_domain(sid) &&
731             !sid_check_is_in_unix_users(sid) &&
732             !sid_check_is_unix_users(sid) &&
733             !sid_check_is_in_unix_groups(sid) &&
734             !sid_check_is_unix_groups(sid) &&
735             !sid_check_is_in_wellknown_domain(sid)) {
736                 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
737                           "lookup SID %s\n", sid_string_dbg(sid)));
738                 return NT_STATUS_NONE_MAPPED;
739         }
740
741         tmp_ctx = talloc_stackframe();
742         if (tmp_ctx == NULL) {
743                 return NT_STATUS_NO_MEMORY;
744         }
745
746         status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
747         if (!NT_STATUS_IS_OK(status)) {
748                 goto done;
749         }
750
751         status = rpc_rids_to_names(tmp_ctx,
752                                    lsa_pipe,
753                                    &lsa_policy,
754                                    domain,
755                                    sid,
756                                    rids,
757                                    num_rids,
758                                    &domain_name,
759                                    &names,
760                                    &types);
761         if (!NT_STATUS_IS_OK(status)) {
762                 goto done;
763         }
764
765         if (pdomain_name) {
766                 *pdomain_name = talloc_move(mem_ctx, &domain_name);
767         }
768
769         if (ptypes) {
770                 *ptypes = talloc_move(mem_ctx, &types);
771         }
772
773         if (pnames) {
774                 *pnames = talloc_move(mem_ctx, &names);
775         }
776
777 done:
778         TALLOC_FREE(tmp_ctx);
779         return status;
780 }
781
782 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
783                                    TALLOC_CTX *mem_ctx,
784                                    struct samr_DomInfo12 *lockout_policy)
785 {
786         struct rpc_pipe_client *samr_pipe;
787         struct policy_handle dom_pol;
788         union samr_DomainInfo *info = NULL;
789         TALLOC_CTX *tmp_ctx;
790         NTSTATUS status;
791
792         DEBUG(3,("sam_lockout_policy\n"));
793
794         tmp_ctx = talloc_stackframe();
795         if (tmp_ctx == NULL) {
796                 return NT_STATUS_NO_MEMORY;
797         }
798
799         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
800         if (!NT_STATUS_IS_OK(status)) {
801                 goto error;
802         }
803
804         status = rpccli_samr_QueryDomainInfo(samr_pipe,
805                                              mem_ctx,
806                                              &dom_pol,
807                                              12,
808                                              &info);
809         if (!NT_STATUS_IS_OK(status)) {
810                 goto error;
811         }
812
813         *lockout_policy = info->info12;
814
815 error:
816         TALLOC_FREE(tmp_ctx);
817         return status;
818 }
819
820 static NTSTATUS common_password_policy(struct winbindd_domain *domain,
821                                        TALLOC_CTX *mem_ctx,
822                                        struct samr_DomInfo1 *passwd_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;
829
830         DEBUG(3,("samr: password policy\n"));
831
832         tmp_ctx = talloc_stackframe();
833         if (tmp_ctx == NULL) {
834                 return NT_STATUS_NO_MEMORY;
835         }
836
837         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
838         if (!NT_STATUS_IS_OK(status)) {
839                 goto error;
840         }
841
842         status = rpccli_samr_QueryDomainInfo(samr_pipe,
843                                              mem_ctx,
844                                              &dom_pol,
845                                              1,
846                                              &info);
847         if (!NT_STATUS_IS_OK(status)) {
848                 goto error;
849         }
850
851         *passwd_policy = info->info1;
852
853 error:
854         TALLOC_FREE(tmp_ctx);
855         return status;
856 }
857
858 /* Lookup groups a user is a member of. */
859 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
860                                       TALLOC_CTX *mem_ctx,
861                                       const struct dom_sid *user_sid,
862                                       uint32_t *pnum_groups,
863                                       struct dom_sid **puser_grpsids)
864 {
865         struct rpc_pipe_client *samr_pipe;
866         struct policy_handle dom_pol;
867         struct dom_sid *user_grpsids = NULL;
868         uint32_t num_groups = 0;
869         TALLOC_CTX *tmp_ctx;
870         NTSTATUS status;
871
872         DEBUG(3,("sam_lookup_usergroups\n"));
873
874         if (pnum_groups) {
875                 *pnum_groups = 0;
876         }
877
878         tmp_ctx = talloc_stackframe();
879         if (tmp_ctx == NULL) {
880                 return NT_STATUS_NO_MEMORY;
881         }
882
883         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
884         if (!NT_STATUS_IS_OK(status)) {
885                 goto done;
886         }
887
888         status = rpc_lookup_usergroups(tmp_ctx,
889                                        samr_pipe,
890                                        &dom_pol,
891                                        &domain->sid,
892                                        user_sid,
893                                        &num_groups,
894                                        &user_grpsids);
895         if (!NT_STATUS_IS_OK(status)) {
896                 goto done;
897         }
898
899         if (pnum_groups) {
900                 *pnum_groups = num_groups;
901         }
902
903         if (puser_grpsids) {
904                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
905         }
906
907 done:
908         TALLOC_FREE(tmp_ctx);
909         return status;
910 }
911
912 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
913                                        TALLOC_CTX *mem_ctx,
914                                        uint32_t num_sids,
915                                        const struct dom_sid *sids,
916                                        uint32_t *pnum_aliases,
917                                        uint32_t **palias_rids)
918 {
919         struct rpc_pipe_client *samr_pipe;
920         struct policy_handle dom_pol;
921         uint32_t num_aliases = 0;
922         uint32_t *alias_rids = NULL;
923         TALLOC_CTX *tmp_ctx;
924         NTSTATUS status;
925
926         DEBUG(3,("sam_lookup_useraliases\n"));
927
928         if (pnum_aliases) {
929                 *pnum_aliases = 0;
930         }
931
932         tmp_ctx = talloc_stackframe();
933         if (tmp_ctx == NULL) {
934                 return NT_STATUS_NO_MEMORY;
935         }
936
937         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
938         if (!NT_STATUS_IS_OK(status)) {
939                 goto done;
940         }
941
942         status = rpc_lookup_useraliases(tmp_ctx,
943                                         samr_pipe,
944                                         &dom_pol,
945                                         num_sids,
946                                         sids,
947                                         &num_aliases,
948                                         &alias_rids);
949         if (!NT_STATUS_IS_OK(status)) {
950                 goto done;
951         }
952
953         if (pnum_aliases) {
954                 *pnum_aliases = num_aliases;
955         }
956
957         if (palias_rids) {
958                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
959         }
960
961 done:
962         TALLOC_FREE(tmp_ctx);
963         return status;
964 }
965
966 /* find the sequence number for a domain */
967 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
968                                     uint32_t *pseq)
969 {
970         struct rpc_pipe_client *samr_pipe;
971         struct policy_handle dom_pol;
972         uint32_t seq;
973         TALLOC_CTX *tmp_ctx;
974         NTSTATUS status;
975
976         DEBUG(3,("samr: sequence number\n"));
977
978         if (pseq) {
979                 *pseq = DOM_SEQUENCE_NONE;
980         }
981
982         tmp_ctx = talloc_stackframe();
983         if (tmp_ctx == NULL) {
984                 return NT_STATUS_NO_MEMORY;
985         }
986
987         status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
988         if (!NT_STATUS_IS_OK(status)) {
989                 goto done;
990         }
991
992         status = rpc_sequence_number(tmp_ctx,
993                                      samr_pipe,
994                                      &dom_pol,
995                                      domain->name,
996                                      &seq);
997         if (!NT_STATUS_IS_OK(status)) {
998                 goto done;
999         }
1000
1001         if (pseq) {
1002                 *pseq = seq;
1003         }
1004 done:
1005         TALLOC_FREE(tmp_ctx);
1006         return status;
1007 }
1008
1009 /* the rpc backend methods are exposed via this structure */
1010 struct winbindd_methods builtin_passdb_methods = {
1011         .consistent            = false,
1012
1013         .query_user_list       = builtin_query_user_list,
1014         .enum_dom_groups       = builtin_enum_dom_groups,
1015         .enum_local_groups     = sam_enum_local_groups,
1016         .name_to_sid           = sam_name_to_sid,
1017         .sid_to_name           = sam_sid_to_name,
1018         .rids_to_names         = sam_rids_to_names,
1019         .query_user            = builtin_query_user,
1020         .lookup_usergroups     = sam_lookup_usergroups,
1021         .lookup_useraliases    = sam_lookup_useraliases,
1022         .lookup_groupmem       = sam_lookup_groupmem,
1023         .sequence_number       = sam_sequence_number,
1024         .lockout_policy        = sam_lockout_policy,
1025         .password_policy       = common_password_policy,
1026         .trusted_domains       = builtin_trusted_domains
1027 };
1028
1029 /* the rpc backend methods are exposed via this structure */
1030 struct winbindd_methods sam_passdb_methods = {
1031         .consistent            = false,
1032
1033         .query_user_list       = sam_query_user_list,
1034         .enum_dom_groups       = sam_enum_dom_groups,
1035         .enum_local_groups     = sam_enum_local_groups,
1036         .name_to_sid           = sam_name_to_sid,
1037         .sid_to_name           = sam_sid_to_name,
1038         .rids_to_names         = sam_rids_to_names,
1039         .query_user            = sam_query_user,
1040         .lookup_usergroups     = sam_lookup_usergroups,
1041         .lookup_useraliases    = sam_lookup_useraliases,
1042         .lookup_groupmem       = sam_lookup_groupmem,
1043         .sequence_number       = sam_sequence_number,
1044         .lockout_policy        = sam_lockout_policy,
1045         .password_policy       = common_password_policy,
1046         .trusted_domains       = sam_trusted_domains
1047 };