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