winbindd: Use rpc_pipe_open_interface() so that winbindd uses the correct rpc servers
[Samba/wip.git] / source3 / winbindd / winbindd_samr.c
blob8a717008086574b5772834da60de4170ef1bb2f1
1 /*
2 * Unix SMB/CIFS implementation.
4 * Winbind rpc backend functions
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>
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.
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.
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/>.
26 #include "includes.h"
27 #include "winbindd.h"
28 #include "winbindd_rpc.h"
29 #include "rpc_client/rpc_client.h"
30 #include "../librpc/gen_ndr/ndr_samr_c.h"
31 #include "rpc_client/cli_samr.h"
32 #include "../librpc/gen_ndr/ndr_lsa_c.h"
33 #include "rpc_client/cli_lsarpc.h"
34 #include "rpc_server/rpc_ncacn_np.h"
35 #include "../libcli/security/security.h"
36 #include "passdb/machine_sid.h"
37 #include "auth.h"
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_WINBIND
42 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
43 struct rpc_pipe_client **samr_pipe)
45 struct rpc_pipe_client *cli = NULL;
46 struct auth_session_info *session_info = NULL;
47 NTSTATUS status;
49 status = make_session_info_system(mem_ctx, &session_info);
50 if (!NT_STATUS_IS_OK(status)) {
51 DEBUG(0, ("open_samr_pipe: Could not create auth_session_info: %s\n",
52 nt_errstr(status)));
53 return status;
56 /* create a samr connection */
57 if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
58 status = rpc_pipe_open_interface(mem_ctx,
59 &ndr_table_samr,
60 session_info,
61 NULL,
62 winbind_messaging_context(),
63 &cli);
64 } else {
65 status = rpc_pipe_open_internal(mem_ctx,
66 &ndr_table_samr.syntax_id,
67 session_info,
68 NULL,
69 winbind_messaging_context(),
70 &cli);
73 if (!NT_STATUS_IS_OK(status)) {
74 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",
75 nt_errstr(status)));
76 return status;
79 if (samr_pipe) {
80 *samr_pipe = cli;
83 return NT_STATUS_OK;
86 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
87 struct winbindd_domain *domain,
88 struct rpc_pipe_client **samr_pipe,
89 struct policy_handle *samr_domain_hnd)
91 NTSTATUS status, result;
92 struct policy_handle samr_connect_hnd;
93 struct dcerpc_binding_handle *b;
95 status = open_internal_samr_pipe(mem_ctx, samr_pipe);
96 if (!NT_STATUS_IS_OK(status)) {
97 return status;
100 b = (*samr_pipe)->binding_handle;
102 status = dcerpc_samr_Connect2(b, mem_ctx,
103 (*samr_pipe)->desthost,
104 SEC_FLAG_MAXIMUM_ALLOWED,
105 &samr_connect_hnd,
106 &result);
107 if (!NT_STATUS_IS_OK(status)) {
108 return status;
110 if (!NT_STATUS_IS_OK(result)) {
111 return result;
114 status = dcerpc_samr_OpenDomain(b, mem_ctx,
115 &samr_connect_hnd,
116 SEC_FLAG_MAXIMUM_ALLOWED,
117 &domain->sid,
118 samr_domain_hnd,
119 &result);
120 if (!NT_STATUS_IS_OK(status)) {
121 return status;
124 return result;
127 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
128 struct rpc_pipe_client **lsa_pipe)
130 struct rpc_pipe_client *cli = NULL;
131 struct auth_session_info *session_info = NULL;
132 NTSTATUS status;
134 status = make_session_info_system(mem_ctx, &session_info);
135 if (!NT_STATUS_IS_OK(status)) {
136 DEBUG(0, ("open_lsa_pipe: Could not create auth_session_info: %s\n",
137 nt_errstr(status)));
138 return status;
141 /* create a lsa connection */
142 if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
143 status = rpc_pipe_open_interface(mem_ctx,
144 &ndr_table_lsarpc,
145 session_info,
146 NULL,
147 winbind_messaging_context(),
148 &cli);
149 } else {
150 status = rpc_pipe_open_internal(mem_ctx,
151 &ndr_table_lsarpc.syntax_id,
152 session_info,
153 NULL,
154 winbind_messaging_context(),
155 &cli);
157 if (!NT_STATUS_IS_OK(status)) {
158 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n",
159 nt_errstr(status)));
160 return status;
163 if (lsa_pipe) {
164 *lsa_pipe = cli;
167 return NT_STATUS_OK;
170 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
171 struct rpc_pipe_client **lsa_pipe,
172 struct policy_handle *lsa_hnd)
174 NTSTATUS status;
176 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe);
177 if (!NT_STATUS_IS_OK(status)) {
178 return status;
181 status = rpccli_lsa_open_policy((*lsa_pipe),
182 mem_ctx,
183 true,
184 SEC_FLAG_MAXIMUM_ALLOWED,
185 lsa_hnd);
187 return status;
190 /*********************************************************************
191 SAM specific functions.
192 *********************************************************************/
194 /* List all domain groups */
195 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
196 TALLOC_CTX *mem_ctx,
197 uint32_t *pnum_info,
198 struct wb_acct_info **pinfo)
200 struct rpc_pipe_client *samr_pipe;
201 struct policy_handle dom_pol;
202 struct wb_acct_info *info = NULL;
203 uint32_t num_info = 0;
204 TALLOC_CTX *tmp_ctx;
205 NTSTATUS status, result;
206 struct dcerpc_binding_handle *b = NULL;
208 DEBUG(3,("sam_enum_dom_groups\n"));
210 ZERO_STRUCT(dom_pol);
212 if (pnum_info) {
213 *pnum_info = 0;
216 tmp_ctx = talloc_stackframe();
217 if (tmp_ctx == NULL) {
218 return NT_STATUS_NO_MEMORY;
221 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
222 if (!NT_STATUS_IS_OK(status)) {
223 goto error;
226 b = samr_pipe->binding_handle;
228 status = rpc_enum_dom_groups(tmp_ctx,
229 samr_pipe,
230 &dom_pol,
231 &num_info,
232 &info);
233 if (!NT_STATUS_IS_OK(status)) {
234 goto error;
237 if (pnum_info) {
238 *pnum_info = num_info;
241 if (pinfo) {
242 *pinfo = talloc_move(mem_ctx, &info);
245 error:
246 if (b && is_valid_policy_hnd(&dom_pol)) {
247 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
249 TALLOC_FREE(tmp_ctx);
250 return status;
253 /* Query display info for a domain */
254 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
255 TALLOC_CTX *mem_ctx,
256 uint32_t *pnum_info,
257 struct wbint_userinfo **pinfo)
259 struct rpc_pipe_client *samr_pipe = NULL;
260 struct policy_handle dom_pol;
261 struct wbint_userinfo *info = NULL;
262 uint32_t num_info = 0;
263 TALLOC_CTX *tmp_ctx;
264 NTSTATUS status, result;
265 struct dcerpc_binding_handle *b = NULL;
267 DEBUG(3,("samr_query_user_list\n"));
269 ZERO_STRUCT(dom_pol);
271 if (pnum_info) {
272 *pnum_info = 0;
275 tmp_ctx = talloc_stackframe();
276 if (tmp_ctx == NULL) {
277 return NT_STATUS_NO_MEMORY;
280 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
281 if (!NT_STATUS_IS_OK(status)) {
282 goto done;
285 b = samr_pipe->binding_handle;
287 status = rpc_query_user_list(tmp_ctx,
288 samr_pipe,
289 &dom_pol,
290 &domain->sid,
291 &num_info,
292 &info);
293 if (!NT_STATUS_IS_OK(status)) {
294 goto done;
297 if (pnum_info) {
298 *pnum_info = num_info;
301 if (pinfo) {
302 *pinfo = talloc_move(mem_ctx, &info);
305 done:
306 if (b && is_valid_policy_hnd(&dom_pol)) {
307 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
310 TALLOC_FREE(tmp_ctx);
311 return status;
314 /* Lookup user information from a rid or username. */
315 static NTSTATUS sam_query_user(struct winbindd_domain *domain,
316 TALLOC_CTX *mem_ctx,
317 const struct dom_sid *user_sid,
318 struct wbint_userinfo *user_info)
320 struct rpc_pipe_client *samr_pipe;
321 struct policy_handle dom_pol;
322 TALLOC_CTX *tmp_ctx;
323 NTSTATUS status, result;
324 struct dcerpc_binding_handle *b = NULL;
326 DEBUG(3,("sam_query_user\n"));
328 ZERO_STRUCT(dom_pol);
330 /* Paranoia check */
331 if (!sid_check_is_in_our_sam(user_sid)) {
332 return NT_STATUS_NO_SUCH_USER;
335 user_info->homedir = NULL;
336 user_info->shell = NULL;
337 user_info->primary_gid = (gid_t) -1;
339 tmp_ctx = talloc_stackframe();
340 if (tmp_ctx == NULL) {
341 return NT_STATUS_NO_MEMORY;
344 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
345 if (!NT_STATUS_IS_OK(status)) {
346 goto done;
349 b = samr_pipe->binding_handle;
351 status = rpc_query_user(tmp_ctx,
352 samr_pipe,
353 &dom_pol,
354 &domain->sid,
355 user_sid,
356 user_info);
358 done:
359 if (b && is_valid_policy_hnd(&dom_pol)) {
360 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
363 TALLOC_FREE(tmp_ctx);
364 return status;
367 /* get a list of trusted domains - builtin domain */
368 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
369 TALLOC_CTX *mem_ctx,
370 struct netr_DomainTrustList *ptrust_list)
372 struct rpc_pipe_client *lsa_pipe;
373 struct policy_handle lsa_policy;
374 struct netr_DomainTrust *trusts = NULL;
375 uint32_t num_trusts = 0;
376 TALLOC_CTX *tmp_ctx;
377 NTSTATUS status, result;
378 struct dcerpc_binding_handle *b = NULL;
380 DEBUG(3,("samr: trusted domains\n"));
382 ZERO_STRUCT(lsa_policy);
384 if (ptrust_list) {
385 ZERO_STRUCTP(ptrust_list);
388 tmp_ctx = talloc_stackframe();
389 if (tmp_ctx == NULL) {
390 return NT_STATUS_NO_MEMORY;
393 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
394 if (!NT_STATUS_IS_OK(status)) {
395 goto done;
398 b = lsa_pipe->binding_handle;
400 status = rpc_trusted_domains(tmp_ctx,
401 lsa_pipe,
402 &lsa_policy,
403 &num_trusts,
404 &trusts);
405 if (!NT_STATUS_IS_OK(status)) {
406 goto done;
409 if (ptrust_list) {
410 ptrust_list->count = num_trusts;
411 ptrust_list->array = talloc_move(mem_ctx, &trusts);
414 done:
415 if (b && is_valid_policy_hnd(&lsa_policy)) {
416 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
419 TALLOC_FREE(tmp_ctx);
420 return status;
423 /* Lookup group membership given a rid. */
424 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
425 TALLOC_CTX *mem_ctx,
426 const struct dom_sid *group_sid,
427 enum lsa_SidType type,
428 uint32_t *pnum_names,
429 struct dom_sid **psid_mem,
430 char ***pnames,
431 uint32_t **pname_types)
433 struct rpc_pipe_client *samr_pipe;
434 struct policy_handle dom_pol;
436 uint32_t num_names = 0;
437 struct dom_sid *sid_mem = NULL;
438 char **names = NULL;
439 uint32_t *name_types = NULL;
441 TALLOC_CTX *tmp_ctx;
442 NTSTATUS status, result;
443 struct dcerpc_binding_handle *b = NULL;
445 DEBUG(3,("sam_lookup_groupmem\n"));
447 ZERO_STRUCT(dom_pol);
449 /* Paranoia check */
450 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
451 /* There's no groups, only aliases in BUILTIN */
452 return NT_STATUS_NO_SUCH_GROUP;
455 if (pnum_names) {
456 *pnum_names = 0;
459 tmp_ctx = talloc_stackframe();
460 if (tmp_ctx == NULL) {
461 return NT_STATUS_NO_MEMORY;
464 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
465 if (!NT_STATUS_IS_OK(status)) {
466 goto done;
469 b = samr_pipe->binding_handle;
471 status = rpc_lookup_groupmem(tmp_ctx,
472 samr_pipe,
473 &dom_pol,
474 domain->name,
475 &domain->sid,
476 group_sid,
477 type,
478 &num_names,
479 &sid_mem,
480 &names,
481 &name_types);
483 if (pnum_names) {
484 *pnum_names = num_names;
487 if (pnames) {
488 *pnames = talloc_move(mem_ctx, &names);
491 if (pname_types) {
492 *pname_types = talloc_move(mem_ctx, &name_types);
495 if (psid_mem) {
496 *psid_mem = talloc_move(mem_ctx, &sid_mem);
499 done:
500 if (b && is_valid_policy_hnd(&dom_pol)) {
501 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
504 TALLOC_FREE(tmp_ctx);
505 return status;
508 /*********************************************************************
509 BUILTIN specific functions.
510 *********************************************************************/
512 /* List all domain groups */
513 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
514 TALLOC_CTX *mem_ctx,
515 uint32 *num_entries,
516 struct wb_acct_info **info)
518 /* BUILTIN doesn't have domain groups */
519 *num_entries = 0;
520 *info = NULL;
521 return NT_STATUS_OK;
524 /* Query display info for a domain */
525 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
526 TALLOC_CTX *mem_ctx,
527 uint32 *num_entries,
528 struct wbint_userinfo **info)
530 /* We don't have users */
531 *num_entries = 0;
532 *info = NULL;
533 return NT_STATUS_OK;
536 /* Lookup user information from a rid or username. */
537 static NTSTATUS builtin_query_user(struct winbindd_domain *domain,
538 TALLOC_CTX *mem_ctx,
539 const struct dom_sid *user_sid,
540 struct wbint_userinfo *user_info)
542 return NT_STATUS_NO_SUCH_USER;
545 /* get a list of trusted domains - builtin domain */
546 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
547 TALLOC_CTX *mem_ctx,
548 struct netr_DomainTrustList *trusts)
550 ZERO_STRUCTP(trusts);
551 return NT_STATUS_OK;
554 /*********************************************************************
555 COMMON functions.
556 *********************************************************************/
558 /* List all local groups (aliases) */
559 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
560 TALLOC_CTX *mem_ctx,
561 uint32_t *pnum_info,
562 struct wb_acct_info **pinfo)
564 struct rpc_pipe_client *samr_pipe;
565 struct policy_handle dom_pol;
566 struct wb_acct_info *info = NULL;
567 uint32_t num_info = 0;
568 TALLOC_CTX *tmp_ctx;
569 NTSTATUS status, result;
570 struct dcerpc_binding_handle *b = NULL;
572 DEBUG(3,("samr: enum local groups\n"));
574 ZERO_STRUCT(dom_pol);
576 if (pnum_info) {
577 *pnum_info = 0;
580 tmp_ctx = talloc_stackframe();
581 if (tmp_ctx == NULL) {
582 return NT_STATUS_NO_MEMORY;
585 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
586 if (!NT_STATUS_IS_OK(status)) {
587 goto done;
590 b = samr_pipe->binding_handle;
592 status = rpc_enum_local_groups(mem_ctx,
593 samr_pipe,
594 &dom_pol,
595 &num_info,
596 &info);
597 if (!NT_STATUS_IS_OK(status)) {
598 goto done;
601 if (pnum_info) {
602 *pnum_info = num_info;
605 if (pinfo) {
606 *pinfo = talloc_move(mem_ctx, &info);
609 done:
610 if (b && is_valid_policy_hnd(&dom_pol)) {
611 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
614 TALLOC_FREE(tmp_ctx);
615 return status;
618 /* convert a single name to a sid in a domain */
619 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
620 TALLOC_CTX *mem_ctx,
621 const char *domain_name,
622 const char *name,
623 uint32_t flags,
624 struct dom_sid *psid,
625 enum lsa_SidType *ptype)
627 struct rpc_pipe_client *lsa_pipe;
628 struct policy_handle lsa_policy;
629 struct dom_sid sid;
630 enum lsa_SidType type;
631 TALLOC_CTX *tmp_ctx;
632 NTSTATUS status, result;
633 struct dcerpc_binding_handle *b = NULL;
635 DEBUG(3,("sam_name_to_sid\n"));
637 ZERO_STRUCT(lsa_policy);
639 tmp_ctx = talloc_stackframe();
640 if (tmp_ctx == NULL) {
641 return NT_STATUS_NO_MEMORY;
644 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
645 if (!NT_STATUS_IS_OK(status)) {
646 goto done;
649 b = lsa_pipe->binding_handle;
651 status = rpc_name_to_sid(tmp_ctx,
652 lsa_pipe,
653 &lsa_policy,
654 domain_name,
655 name,
656 flags,
657 &sid,
658 &type);
659 if (!NT_STATUS_IS_OK(status)) {
660 goto done;
663 if (psid) {
664 sid_copy(psid, &sid);
666 if (ptype) {
667 *ptype = type;
670 done:
671 if (b && is_valid_policy_hnd(&lsa_policy)) {
672 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
675 TALLOC_FREE(tmp_ctx);
676 return status;
679 /* convert a domain SID to a user or group name */
680 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
681 TALLOC_CTX *mem_ctx,
682 const struct dom_sid *sid,
683 char **pdomain_name,
684 char **pname,
685 enum lsa_SidType *ptype)
687 struct rpc_pipe_client *lsa_pipe;
688 struct policy_handle lsa_policy;
689 char *domain_name = NULL;
690 char *name = NULL;
691 enum lsa_SidType type;
692 TALLOC_CTX *tmp_ctx;
693 NTSTATUS status, result;
694 struct dcerpc_binding_handle *b = NULL;
696 DEBUG(3,("sam_sid_to_name\n"));
698 ZERO_STRUCT(lsa_policy);
700 /* Paranoia check */
701 if (!sid_check_is_in_builtin(sid) &&
702 !sid_check_is_builtin(sid) &&
703 !sid_check_is_in_our_sam(sid) &&
704 !sid_check_is_our_sam(sid) &&
705 !sid_check_is_in_unix_users(sid) &&
706 !sid_check_is_unix_users(sid) &&
707 !sid_check_is_in_unix_groups(sid) &&
708 !sid_check_is_unix_groups(sid) &&
709 !sid_check_is_in_wellknown_domain(sid)) {
710 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
711 "lookup SID %s\n", sid_string_dbg(sid)));
712 return NT_STATUS_NONE_MAPPED;
715 tmp_ctx = talloc_stackframe();
716 if (tmp_ctx == NULL) {
717 return NT_STATUS_NO_MEMORY;
720 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
721 if (!NT_STATUS_IS_OK(status)) {
722 goto done;
725 b = lsa_pipe->binding_handle;
727 status = rpc_sid_to_name(tmp_ctx,
728 lsa_pipe,
729 &lsa_policy,
730 domain,
731 sid,
732 &domain_name,
733 &name,
734 &type);
736 if (ptype) {
737 *ptype = type;
740 if (pname) {
741 *pname = talloc_move(mem_ctx, &name);
744 if (pdomain_name) {
745 *pdomain_name = talloc_move(mem_ctx, &domain_name);
748 done:
749 if (b && is_valid_policy_hnd(&lsa_policy)) {
750 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
753 TALLOC_FREE(tmp_ctx);
754 return status;
757 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
758 TALLOC_CTX *mem_ctx,
759 const struct dom_sid *domain_sid,
760 uint32 *rids,
761 size_t num_rids,
762 char **pdomain_name,
763 char ***pnames,
764 enum lsa_SidType **ptypes)
766 struct rpc_pipe_client *lsa_pipe;
767 struct policy_handle lsa_policy;
768 enum lsa_SidType *types = NULL;
769 char *domain_name = NULL;
770 char **names = NULL;
771 TALLOC_CTX *tmp_ctx;
772 NTSTATUS status, result;
773 struct dcerpc_binding_handle *b = NULL;
775 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
777 ZERO_STRUCT(lsa_policy);
779 /* Paranoia check */
780 if (!sid_check_is_builtin(domain_sid) &&
781 !sid_check_is_our_sam(domain_sid) &&
782 !sid_check_is_unix_users(domain_sid) &&
783 !sid_check_is_unix_groups(domain_sid) &&
784 !sid_check_is_in_wellknown_domain(domain_sid)) {
785 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
786 "lookup SID %s\n", sid_string_dbg(domain_sid)));
787 return NT_STATUS_NONE_MAPPED;
790 tmp_ctx = talloc_stackframe();
791 if (tmp_ctx == NULL) {
792 return NT_STATUS_NO_MEMORY;
795 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
796 if (!NT_STATUS_IS_OK(status)) {
797 goto done;
800 b = lsa_pipe->binding_handle;
802 status = rpc_rids_to_names(tmp_ctx,
803 lsa_pipe,
804 &lsa_policy,
805 domain,
806 domain_sid,
807 rids,
808 num_rids,
809 &domain_name,
810 &names,
811 &types);
812 if (!NT_STATUS_IS_OK(status)) {
813 goto done;
816 if (pdomain_name) {
817 *pdomain_name = talloc_move(mem_ctx, &domain_name);
820 if (ptypes) {
821 *ptypes = talloc_move(mem_ctx, &types);
824 if (pnames) {
825 *pnames = talloc_move(mem_ctx, &names);
828 done:
829 if (b && is_valid_policy_hnd(&lsa_policy)) {
830 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
833 TALLOC_FREE(tmp_ctx);
834 return status;
837 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
838 TALLOC_CTX *mem_ctx,
839 struct samr_DomInfo12 *lockout_policy)
841 struct rpc_pipe_client *samr_pipe;
842 struct policy_handle dom_pol;
843 union samr_DomainInfo *info = NULL;
844 TALLOC_CTX *tmp_ctx;
845 NTSTATUS status, result;
846 struct dcerpc_binding_handle *b = NULL;
848 DEBUG(3,("sam_lockout_policy\n"));
850 ZERO_STRUCT(dom_pol);
852 tmp_ctx = talloc_stackframe();
853 if (tmp_ctx == NULL) {
854 return NT_STATUS_NO_MEMORY;
857 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
858 if (!NT_STATUS_IS_OK(status)) {
859 goto error;
862 b = samr_pipe->binding_handle;
864 status = dcerpc_samr_QueryDomainInfo(b,
865 mem_ctx,
866 &dom_pol,
867 DomainLockoutInformation,
868 &info,
869 &result);
870 if (!NT_STATUS_IS_OK(status)) {
871 goto error;
873 if (!NT_STATUS_IS_OK(result)) {
874 status = result;
875 goto error;
878 *lockout_policy = info->info12;
880 error:
881 if (b && is_valid_policy_hnd(&dom_pol)) {
882 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
885 TALLOC_FREE(tmp_ctx);
886 return status;
889 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
890 TALLOC_CTX *mem_ctx,
891 struct samr_DomInfo1 *passwd_policy)
893 struct rpc_pipe_client *samr_pipe;
894 struct policy_handle dom_pol;
895 union samr_DomainInfo *info = NULL;
896 TALLOC_CTX *tmp_ctx;
897 NTSTATUS status, result;
898 struct dcerpc_binding_handle *b = NULL;
900 DEBUG(3,("sam_password_policy\n"));
902 ZERO_STRUCT(dom_pol);
904 tmp_ctx = talloc_stackframe();
905 if (tmp_ctx == NULL) {
906 return NT_STATUS_NO_MEMORY;
909 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
910 if (!NT_STATUS_IS_OK(status)) {
911 goto error;
914 b = samr_pipe->binding_handle;
916 status = dcerpc_samr_QueryDomainInfo(b,
917 mem_ctx,
918 &dom_pol,
919 DomainPasswordInformation,
920 &info,
921 &result);
922 if (!NT_STATUS_IS_OK(status)) {
923 goto error;
925 if (!NT_STATUS_IS_OK(result)) {
926 status = result;
927 goto error;
930 *passwd_policy = info->info1;
932 error:
933 if (b && is_valid_policy_hnd(&dom_pol)) {
934 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
937 TALLOC_FREE(tmp_ctx);
938 return status;
941 /* Lookup groups a user is a member of. */
942 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
943 TALLOC_CTX *mem_ctx,
944 const struct dom_sid *user_sid,
945 uint32_t *pnum_groups,
946 struct dom_sid **puser_grpsids)
948 struct rpc_pipe_client *samr_pipe;
949 struct policy_handle dom_pol;
950 struct dom_sid *user_grpsids = NULL;
951 uint32_t num_groups = 0;
952 TALLOC_CTX *tmp_ctx;
953 NTSTATUS status, result;
954 struct dcerpc_binding_handle *b = NULL;
956 DEBUG(3,("sam_lookup_usergroups\n"));
958 ZERO_STRUCT(dom_pol);
960 if (pnum_groups) {
961 *pnum_groups = 0;
964 tmp_ctx = talloc_stackframe();
965 if (tmp_ctx == NULL) {
966 return NT_STATUS_NO_MEMORY;
969 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
970 if (!NT_STATUS_IS_OK(status)) {
971 goto done;
974 b = samr_pipe->binding_handle;
976 status = rpc_lookup_usergroups(tmp_ctx,
977 samr_pipe,
978 &dom_pol,
979 &domain->sid,
980 user_sid,
981 &num_groups,
982 &user_grpsids);
983 if (!NT_STATUS_IS_OK(status)) {
984 goto done;
987 if (pnum_groups) {
988 *pnum_groups = num_groups;
991 if (puser_grpsids) {
992 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
995 done:
996 if (b && is_valid_policy_hnd(&dom_pol)) {
997 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1000 TALLOC_FREE(tmp_ctx);
1001 return status;
1004 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
1005 TALLOC_CTX *mem_ctx,
1006 uint32_t num_sids,
1007 const struct dom_sid *sids,
1008 uint32_t *pnum_aliases,
1009 uint32_t **palias_rids)
1011 struct rpc_pipe_client *samr_pipe;
1012 struct policy_handle dom_pol;
1013 uint32_t num_aliases = 0;
1014 uint32_t *alias_rids = NULL;
1015 TALLOC_CTX *tmp_ctx;
1016 NTSTATUS status, result;
1017 struct dcerpc_binding_handle *b = NULL;
1019 DEBUG(3,("sam_lookup_useraliases\n"));
1021 ZERO_STRUCT(dom_pol);
1023 if (pnum_aliases) {
1024 *pnum_aliases = 0;
1027 tmp_ctx = talloc_stackframe();
1028 if (tmp_ctx == NULL) {
1029 return NT_STATUS_NO_MEMORY;
1032 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1033 if (!NT_STATUS_IS_OK(status)) {
1034 goto done;
1037 b = samr_pipe->binding_handle;
1039 status = rpc_lookup_useraliases(tmp_ctx,
1040 samr_pipe,
1041 &dom_pol,
1042 num_sids,
1043 sids,
1044 &num_aliases,
1045 &alias_rids);
1046 if (!NT_STATUS_IS_OK(status)) {
1047 goto done;
1050 if (pnum_aliases) {
1051 *pnum_aliases = num_aliases;
1054 if (palias_rids) {
1055 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1058 done:
1059 if (b && is_valid_policy_hnd(&dom_pol)) {
1060 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
1063 TALLOC_FREE(tmp_ctx);
1064 return status;
1067 /* find the sequence number for a domain */
1068 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1069 uint32_t *pseq)
1071 struct rpc_pipe_client *samr_pipe;
1072 struct policy_handle dom_pol;
1073 uint32_t seq;
1074 TALLOC_CTX *tmp_ctx;
1075 NTSTATUS status, result;
1076 struct dcerpc_binding_handle *b = NULL;
1078 DEBUG(3,("samr: sequence number\n"));
1080 ZERO_STRUCT(dom_pol);
1082 if (pseq) {
1083 *pseq = DOM_SEQUENCE_NONE;
1086 tmp_ctx = talloc_stackframe();
1087 if (tmp_ctx == NULL) {
1088 return NT_STATUS_NO_MEMORY;
1091 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
1092 if (!NT_STATUS_IS_OK(status)) {
1093 goto done;
1096 b = samr_pipe->binding_handle;
1098 status = rpc_sequence_number(tmp_ctx,
1099 samr_pipe,
1100 &dom_pol,
1101 domain->name,
1102 &seq);
1103 if (!NT_STATUS_IS_OK(status)) {
1104 goto done;
1107 if (pseq) {
1108 *pseq = seq;
1110 done:
1111 if (b && is_valid_policy_hnd(&dom_pol)) {
1112 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
1115 TALLOC_FREE(tmp_ctx);
1116 return status;
1119 /* the rpc backend methods are exposed via this structure */
1120 struct winbindd_methods builtin_passdb_methods = {
1121 .consistent = false,
1123 .query_user_list = builtin_query_user_list,
1124 .enum_dom_groups = builtin_enum_dom_groups,
1125 .enum_local_groups = sam_enum_local_groups,
1126 .name_to_sid = sam_name_to_sid,
1127 .sid_to_name = sam_sid_to_name,
1128 .rids_to_names = sam_rids_to_names,
1129 .query_user = builtin_query_user,
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
1139 /* the rpc backend methods are exposed via this structure */
1140 struct winbindd_methods sam_passdb_methods = {
1141 .consistent = false,
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 .query_user = sam_query_user,
1150 .lookup_usergroups = sam_lookup_usergroups,
1151 .lookup_useraliases = sam_lookup_useraliases,
1152 .lookup_groupmem = sam_lookup_groupmem,
1153 .sequence_number = sam_sequence_number,
1154 .lockout_policy = sam_lockout_policy,
1155 .password_policy = sam_password_policy,
1156 .trusted_domains = sam_trusted_domains