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