winbindd: Use dom_sid_str_buf
[nivanova/samba-autobuild/.git] / source3 / winbindd / winbindd_samr.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * Winbind rpc backend functions
5  *
6  * Copyright (c) 2000-2003 Tim Potter
7  * Copyright (c) 2001      Andrew Tridgell
8  * Copyright (c) 2005      Volker Lendecke
9  * Copyright (c) 2008      Guenther Deschner (pidl conversion)
10  * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
29 #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         enum lsa_SidType type;
591         TALLOC_CTX *tmp_ctx;
592         NTSTATUS status;
593         bool retry = false;
594
595         DEBUG(3,("sam_name_to_sid\n"));
596
597         tmp_ctx = talloc_stackframe();
598         if (tmp_ctx == NULL) {
599                 return NT_STATUS_NO_MEMORY;
600         }
601
602 again:
603         status = open_cached_internal_pipe_conn(domain,
604                                                 NULL,
605                                                 NULL,
606                                                 &lsa_pipe,
607                                                 &lsa_policy);
608         if (!NT_STATUS_IS_OK(status)) {
609                 goto done;
610         }
611
612         status = rpc_name_to_sid(tmp_ctx,
613                                  lsa_pipe,
614                                  &lsa_policy,
615                                  domain_name,
616                                  name,
617                                  flags,
618                                  &sid,
619                                  &type);
620
621         if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
622                 retry = true;
623                 goto again;
624         }
625
626         if (!NT_STATUS_IS_OK(status)) {
627                 goto done;
628         }
629
630         if (psid) {
631                 sid_copy(psid, &sid);
632         }
633         if (ptype) {
634                 *ptype = type;
635         }
636
637 done:
638         TALLOC_FREE(tmp_ctx);
639         return status;
640 }
641
642 /* convert a domain SID to a user or group name */
643 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
644                                 TALLOC_CTX *mem_ctx,
645                                 const struct dom_sid *sid,
646                                 char **pdomain_name,
647                                 char **pname,
648                                 enum lsa_SidType *ptype)
649 {
650         struct rpc_pipe_client *lsa_pipe;
651         struct policy_handle lsa_policy = { 0 };
652         char *domain_name = NULL;
653         char *name = NULL;
654         enum lsa_SidType type;
655         TALLOC_CTX *tmp_ctx;
656         NTSTATUS status;
657         bool retry = false;
658
659         DEBUG(3,("sam_sid_to_name\n"));
660
661         /* Paranoia check */
662         if (!sid_check_is_in_builtin(sid) &&
663             !sid_check_is_builtin(sid) &&
664             !sid_check_is_in_our_sam(sid) &&
665             !sid_check_is_our_sam(sid) &&
666             !sid_check_is_in_unix_users(sid) &&
667             !sid_check_is_unix_users(sid) &&
668             !sid_check_is_in_unix_groups(sid) &&
669             !sid_check_is_unix_groups(sid) &&
670             !sid_check_is_in_wellknown_domain(sid)) {
671                 struct dom_sid_buf buf;
672                 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
673                           "lookup SID %s\n",
674                           dom_sid_str_buf(sid, &buf)));
675                 return NT_STATUS_NONE_MAPPED;
676         }
677
678         tmp_ctx = talloc_stackframe();
679         if (tmp_ctx == NULL) {
680                 return NT_STATUS_NO_MEMORY;
681         }
682
683 again:
684         status = open_cached_internal_pipe_conn(domain,
685                                                 NULL,
686                                                 NULL,
687                                                 &lsa_pipe,
688                                                 &lsa_policy);
689         if (!NT_STATUS_IS_OK(status)) {
690                 goto done;
691         }
692
693         status = rpc_sid_to_name(tmp_ctx,
694                                  lsa_pipe,
695                                  &lsa_policy,
696                                  domain,
697                                  sid,
698                                  &domain_name,
699                                  &name,
700                                  &type);
701
702         if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
703                 retry = true;
704                 goto again;
705         }
706
707         if (ptype) {
708                 *ptype = type;
709         }
710
711         if (pname) {
712                 *pname = talloc_move(mem_ctx, &name);
713         }
714
715         if (pdomain_name) {
716                 *pdomain_name = talloc_move(mem_ctx, &domain_name);
717         }
718
719 done:
720
721         TALLOC_FREE(tmp_ctx);
722         return status;
723 }
724
725 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
726                                   TALLOC_CTX *mem_ctx,
727                                   const struct dom_sid *domain_sid,
728                                   uint32_t *rids,
729                                   size_t num_rids,
730                                   char **pdomain_name,
731                                   char ***pnames,
732                                   enum lsa_SidType **ptypes)
733 {
734         struct rpc_pipe_client *lsa_pipe;
735         struct policy_handle lsa_policy = { 0 };
736         enum lsa_SidType *types = NULL;
737         char *domain_name = NULL;
738         char **names = NULL;
739         TALLOC_CTX *tmp_ctx;
740         NTSTATUS status;
741         bool retry = false;
742
743         DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
744
745         /* Paranoia check */
746         if (!sid_check_is_builtin(domain_sid) &&
747             !sid_check_is_our_sam(domain_sid) &&
748             !sid_check_is_unix_users(domain_sid) &&
749             !sid_check_is_unix_groups(domain_sid) &&
750             !sid_check_is_in_wellknown_domain(domain_sid)) {
751                 struct dom_sid_buf buf;
752                 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
753                           "lookup SID %s\n",
754                           dom_sid_str_buf(domain_sid, &buf)));
755                 return NT_STATUS_NONE_MAPPED;
756         }
757
758         tmp_ctx = talloc_stackframe();
759         if (tmp_ctx == NULL) {
760                 return NT_STATUS_NO_MEMORY;
761         }
762
763 again:
764         status = open_cached_internal_pipe_conn(domain,
765                                                 NULL,
766                                                 NULL,
767                                                 &lsa_pipe,
768                                                 &lsa_policy);
769         if (!NT_STATUS_IS_OK(status)) {
770                 goto done;
771         }
772
773         status = rpc_rids_to_names(tmp_ctx,
774                                    lsa_pipe,
775                                    &lsa_policy,
776                                    domain,
777                                    domain_sid,
778                                    rids,
779                                    num_rids,
780                                    &domain_name,
781                                    &names,
782                                    &types);
783
784         if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
785                 retry = true;
786                 goto again;
787         }
788
789         if (!NT_STATUS_IS_OK(status)) {
790                 goto done;
791         }
792
793         if (pdomain_name) {
794                 *pdomain_name = talloc_move(mem_ctx, &domain_name);
795         }
796
797         if (ptypes) {
798                 *ptypes = talloc_move(mem_ctx, &types);
799         }
800
801         if (pnames) {
802                 *pnames = talloc_move(mem_ctx, &names);
803         }
804
805 done:
806         TALLOC_FREE(tmp_ctx);
807         return status;
808 }
809
810 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
811                                    TALLOC_CTX *mem_ctx,
812                                    struct samr_DomInfo12 *lockout_policy)
813 {
814         struct rpc_pipe_client *samr_pipe;
815         struct policy_handle dom_pol = { 0 };
816         union samr_DomainInfo *info = NULL;
817         TALLOC_CTX *tmp_ctx;
818         NTSTATUS status, result;
819         struct dcerpc_binding_handle *b = NULL;
820         bool retry = false;
821
822         DEBUG(3,("sam_lockout_policy\n"));
823
824         tmp_ctx = talloc_stackframe();
825         if (tmp_ctx == NULL) {
826                 return NT_STATUS_NO_MEMORY;
827         }
828
829 again:
830         status = open_cached_internal_pipe_conn(domain,
831                                                 &samr_pipe,
832                                                 &dom_pol,
833                                                 NULL,
834                                                 NULL);
835         if (!NT_STATUS_IS_OK(status)) {
836                 goto error;
837         }
838
839         b = samr_pipe->binding_handle;
840
841         status = dcerpc_samr_QueryDomainInfo(b,
842                                              mem_ctx,
843                                              &dom_pol,
844                                              DomainLockoutInformation,
845                                              &info,
846                                              &result);
847
848         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
849                 retry = true;
850                 goto again;
851         }
852
853         if (!NT_STATUS_IS_OK(status)) {
854                 goto error;
855         }
856         if (!NT_STATUS_IS_OK(result)) {
857                 status = result;
858                 goto error;
859         }
860
861         *lockout_policy = info->info12;
862
863 error:
864         TALLOC_FREE(tmp_ctx);
865         return status;
866 }
867
868 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
869                                     TALLOC_CTX *mem_ctx,
870                                     struct samr_DomInfo1 *passwd_policy)
871 {
872         struct rpc_pipe_client *samr_pipe;
873         struct policy_handle dom_pol = { 0 };
874         union samr_DomainInfo *info = NULL;
875         TALLOC_CTX *tmp_ctx;
876         NTSTATUS status, result;
877         struct dcerpc_binding_handle *b = NULL;
878         bool retry = false;
879
880         DEBUG(3,("sam_password_policy\n"));
881
882         tmp_ctx = talloc_stackframe();
883         if (tmp_ctx == NULL) {
884                 return NT_STATUS_NO_MEMORY;
885         }
886
887 again:
888         status = open_cached_internal_pipe_conn(domain,
889                                                 &samr_pipe,
890                                                 &dom_pol,
891                                                 NULL,
892                                                 NULL);
893         if (!NT_STATUS_IS_OK(status)) {
894                 goto error;
895         }
896
897         b = samr_pipe->binding_handle;
898
899         status = dcerpc_samr_QueryDomainInfo(b,
900                                              mem_ctx,
901                                              &dom_pol,
902                                              DomainPasswordInformation,
903                                              &info,
904                                              &result);
905
906         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
907                 retry = true;
908                 goto again;
909         }
910
911         if (!NT_STATUS_IS_OK(status)) {
912                 goto error;
913         }
914         if (!NT_STATUS_IS_OK(result)) {
915                 status = result;
916                 goto error;
917         }
918
919         *passwd_policy = info->info1;
920
921 error:
922         TALLOC_FREE(tmp_ctx);
923         return status;
924 }
925
926 /* Lookup groups a user is a member of. */
927 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
928                                       TALLOC_CTX *mem_ctx,
929                                       const struct dom_sid *user_sid,
930                                       uint32_t *pnum_groups,
931                                       struct dom_sid **puser_grpsids)
932 {
933         struct rpc_pipe_client *samr_pipe;
934         struct policy_handle dom_pol;
935         struct dom_sid *user_grpsids = NULL;
936         uint32_t num_groups = 0;
937         TALLOC_CTX *tmp_ctx;
938         NTSTATUS status;
939         bool retry = false;
940
941         DEBUG(3,("sam_lookup_usergroups\n"));
942
943         ZERO_STRUCT(dom_pol);
944
945         if (pnum_groups) {
946                 *pnum_groups = 0;
947         }
948
949         tmp_ctx = talloc_stackframe();
950         if (tmp_ctx == NULL) {
951                 return NT_STATUS_NO_MEMORY;
952         }
953
954 again:
955         status = open_cached_internal_pipe_conn(domain,
956                                                 &samr_pipe,
957                                                 &dom_pol,
958                                                 NULL,
959                                                 NULL);
960         if (!NT_STATUS_IS_OK(status)) {
961                 goto done;
962         }
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
972         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
973                 retry = true;
974                 goto again;
975         }
976
977         if (!NT_STATUS_IS_OK(status)) {
978                 goto done;
979         }
980
981         if (pnum_groups) {
982                 *pnum_groups = num_groups;
983         }
984
985         if (puser_grpsids) {
986                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
987         }
988
989 done:
990
991         TALLOC_FREE(tmp_ctx);
992         return status;
993 }
994
995 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
996                                        TALLOC_CTX *mem_ctx,
997                                        uint32_t num_sids,
998                                        const struct dom_sid *sids,
999                                        uint32_t *pnum_aliases,
1000                                        uint32_t **palias_rids)
1001 {
1002         struct rpc_pipe_client *samr_pipe;
1003         struct policy_handle dom_pol = { 0 };
1004         uint32_t num_aliases = 0;
1005         uint32_t *alias_rids = NULL;
1006         TALLOC_CTX *tmp_ctx;
1007         NTSTATUS status;
1008         bool retry = false;
1009
1010         DEBUG(3,("sam_lookup_useraliases\n"));
1011
1012         if (pnum_aliases) {
1013                 *pnum_aliases = 0;
1014         }
1015
1016         tmp_ctx = talloc_stackframe();
1017         if (tmp_ctx == NULL) {
1018                 return NT_STATUS_NO_MEMORY;
1019         }
1020
1021 again:
1022         status = open_cached_internal_pipe_conn(domain,
1023                                                 &samr_pipe,
1024                                                 &dom_pol,
1025                                                 NULL,
1026                                                 NULL);
1027         if (!NT_STATUS_IS_OK(status)) {
1028                 goto done;
1029         }
1030
1031         status = rpc_lookup_useraliases(tmp_ctx,
1032                                         samr_pipe,
1033                                         &dom_pol,
1034                                         num_sids,
1035                                         sids,
1036                                         &num_aliases,
1037                                         &alias_rids);
1038
1039         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
1040                 retry = true;
1041                 goto again;
1042         }
1043
1044         if (!NT_STATUS_IS_OK(status)) {
1045                 goto done;
1046         }
1047
1048         if (pnum_aliases) {
1049                 *pnum_aliases = num_aliases;
1050         }
1051
1052         if (palias_rids) {
1053                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1054         }
1055
1056 done:
1057
1058         TALLOC_FREE(tmp_ctx);
1059         return status;
1060 }
1061
1062 /* find the sequence number for a domain */
1063 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1064                                     uint32_t *pseq)
1065 {
1066         struct rpc_pipe_client *samr_pipe;
1067         struct policy_handle dom_pol = { 0 };
1068         uint32_t seq = DOM_SEQUENCE_NONE;
1069         TALLOC_CTX *tmp_ctx;
1070         NTSTATUS status;
1071         bool retry = false;
1072
1073         DEBUG(3,("samr: sequence number\n"));
1074
1075         if (pseq) {
1076                 *pseq = DOM_SEQUENCE_NONE;
1077         }
1078
1079         tmp_ctx = talloc_stackframe();
1080         if (tmp_ctx == NULL) {
1081                 return NT_STATUS_NO_MEMORY;
1082         }
1083
1084 again:
1085         status = open_cached_internal_pipe_conn(domain,
1086                                                 &samr_pipe,
1087                                                 &dom_pol,
1088                                                 NULL,
1089                                                 NULL);
1090         if (!NT_STATUS_IS_OK(status)) {
1091                 goto done;
1092         }
1093
1094         status = rpc_sequence_number(tmp_ctx,
1095                                      samr_pipe,
1096                                      &dom_pol,
1097                                      domain->name,
1098                                      &seq);
1099
1100         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
1101                 retry = true;
1102                 goto again;
1103         }
1104
1105         if (!NT_STATUS_IS_OK(status)) {
1106                 goto done;
1107         }
1108
1109         if (pseq) {
1110                 *pseq = seq;
1111         }
1112
1113 done:
1114         TALLOC_FREE(tmp_ctx);
1115         return status;
1116 }
1117
1118 /* the rpc backend methods are exposed via this structure */
1119 struct winbindd_methods builtin_passdb_methods = {
1120         .consistent            = false,
1121
1122         .query_user_list       = builtin_query_user_list,
1123         .enum_dom_groups       = builtin_enum_dom_groups,
1124         .enum_local_groups     = sam_enum_local_groups,
1125         .name_to_sid           = sam_name_to_sid,
1126         .sid_to_name           = sam_sid_to_name,
1127         .rids_to_names         = sam_rids_to_names,
1128         .lookup_usergroups     = sam_lookup_usergroups,
1129         .lookup_useraliases    = sam_lookup_useraliases,
1130         .lookup_groupmem       = sam_lookup_groupmem,
1131         .sequence_number       = sam_sequence_number,
1132         .lockout_policy        = sam_lockout_policy,
1133         .password_policy       = sam_password_policy,
1134         .trusted_domains       = builtin_trusted_domains
1135 };
1136
1137 /* the rpc backend methods are exposed via this structure */
1138 struct winbindd_methods sam_passdb_methods = {
1139         .consistent            = false,
1140
1141         .query_user_list       = sam_query_user_list,
1142         .enum_dom_groups       = sam_enum_dom_groups,
1143         .enum_local_groups     = sam_enum_local_groups,
1144         .name_to_sid           = sam_name_to_sid,
1145         .sid_to_name           = sam_sid_to_name,
1146         .rids_to_names         = sam_rids_to_names,
1147         .lookup_usergroups     = sam_lookup_usergroups,
1148         .lookup_useraliases    = sam_lookup_useraliases,
1149         .lookup_groupmem       = sam_lookup_groupmem,
1150         .sequence_number       = sam_sequence_number,
1151         .lockout_policy        = sam_lockout_policy,
1152         .password_policy       = sam_password_policy,
1153         .trusted_domains       = sam_trusted_domains
1154 };