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