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/>.
28 #include "winbindd_rpc.h"
29 #include "lib/util_unixsids.h"
30 #include "rpc_client/rpc_client.h"
31 #include "../librpc/gen_ndr/ndr_samr_c.h"
32 #include "rpc_client/cli_samr.h"
33 #include "../librpc/gen_ndr/ndr_lsa_c.h"
34 #include "rpc_client/cli_lsarpc.h"
35 #include "rpc_server/rpc_ncacn_np.h"
36 #include "../libcli/security/security.h"
37 #include "passdb/machine_sid.h"
41 #define DBGC_CLASS DBGC_WINBIND
44 * The other end of this won't go away easily, so we can trust it
46 * It is either a long-lived process with the same lifetime as
47 * winbindd or a part of this process
49 struct winbind_internal_pipes {
50 struct rpc_pipe_client *samr_pipe;
51 struct policy_handle samr_domain_hnd;
52 struct rpc_pipe_client *lsa_pipe;
53 struct policy_handle lsa_hnd;
57 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
58 struct winbindd_domain *domain,
59 struct rpc_pipe_client **samr_pipe,
60 struct policy_handle *samr_domain_hnd)
62 NTSTATUS status, result;
63 struct policy_handle samr_connect_hnd;
64 struct dcerpc_binding_handle *b;
66 status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
67 if (!NT_STATUS_IS_OK(status)) {
71 b = (*samr_pipe)->binding_handle;
73 status = dcerpc_samr_Connect2(b, mem_ctx,
74 (*samr_pipe)->desthost,
75 SEC_FLAG_MAXIMUM_ALLOWED,
78 if (!NT_STATUS_IS_OK(status)) {
81 if (!NT_STATUS_IS_OK(result)) {
85 status = dcerpc_samr_OpenDomain(b, mem_ctx,
87 SEC_FLAG_MAXIMUM_ALLOWED,
91 if (!NT_STATUS_IS_OK(status)) {
98 NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
99 struct rpc_pipe_client **lsa_pipe,
100 struct policy_handle *lsa_hnd)
104 status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
105 if (!NT_STATUS_IS_OK(status)) {
109 status = rpccli_lsa_open_policy((*lsa_pipe),
112 SEC_FLAG_MAXIMUM_ALLOWED,
119 static NTSTATUS open_cached_internal_pipe_conn(
120 struct winbindd_domain *domain,
121 struct rpc_pipe_client **samr_pipe,
122 struct policy_handle *samr_domain_hnd,
123 struct rpc_pipe_client **lsa_pipe,
124 struct policy_handle *lsa_hnd)
126 struct winbind_internal_pipes *internal_pipes = NULL;
128 if (domain->private_data == NULL) {
129 TALLOC_CTX *frame = talloc_stackframe();
132 internal_pipes = talloc_zero(frame,
133 struct winbind_internal_pipes);
135 status = open_internal_samr_conn(
138 &internal_pipes->samr_pipe,
139 &internal_pipes->samr_domain_hnd);
140 if (!NT_STATUS_IS_OK(status)) {
145 status = open_internal_lsa_conn(internal_pipes,
146 &internal_pipes->lsa_pipe,
147 &internal_pipes->lsa_hnd);
149 if (!NT_STATUS_IS_OK(status)) {
154 domain->private_data = talloc_move(domain, &internal_pipes);
160 internal_pipes = talloc_get_type_abort(
161 domain->private_data, struct winbind_internal_pipes);
163 if (samr_domain_hnd) {
164 *samr_domain_hnd = internal_pipes->samr_domain_hnd;
168 *samr_pipe = internal_pipes->samr_pipe;
172 *lsa_hnd = internal_pipes->lsa_hnd;
176 *lsa_pipe = internal_pipes->lsa_pipe;
182 /*********************************************************************
183 SAM specific functions.
184 *********************************************************************/
186 /* List all domain groups */
187 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
190 struct wb_acct_info **pinfo)
192 struct rpc_pipe_client *samr_pipe;
193 struct policy_handle dom_pol = { 0 };
194 struct wb_acct_info *info = NULL;
195 uint32_t num_info = 0;
199 DEBUG(3,("sam_enum_dom_groups\n"));
205 tmp_ctx = talloc_stackframe();
206 if (tmp_ctx == NULL) {
207 return NT_STATUS_NO_MEMORY;
210 status = open_cached_internal_pipe_conn(domain,
215 if (!NT_STATUS_IS_OK(status)) {
216 TALLOC_FREE(tmp_ctx);
220 status = rpc_enum_dom_groups(tmp_ctx,
225 if (!NT_STATUS_IS_OK(status)) {
226 TALLOC_FREE(tmp_ctx);
231 *pnum_info = num_info;
235 *pinfo = talloc_move(mem_ctx, &info);
238 TALLOC_FREE(tmp_ctx);
242 /* Query display info for a domain */
243 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
247 struct rpc_pipe_client *samr_pipe = NULL;
248 struct policy_handle dom_pol = { 0 };
249 uint32_t *rids = NULL;
253 DEBUG(3,("samr_query_user_list\n"));
255 tmp_ctx = talloc_stackframe();
256 if (tmp_ctx == NULL) {
257 return NT_STATUS_NO_MEMORY;
260 status = open_cached_internal_pipe_conn(domain,
265 if (!NT_STATUS_IS_OK(status)) {
269 status = rpc_query_user_list(tmp_ctx,
274 if (!NT_STATUS_IS_OK(status)) {
279 *prids = talloc_move(mem_ctx, &rids);
284 TALLOC_FREE(tmp_ctx);
288 /* get a list of trusted domains - builtin domain */
289 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
291 struct netr_DomainTrustList *ptrust_list)
293 struct rpc_pipe_client *lsa_pipe;
294 struct policy_handle lsa_policy = { 0 };
295 struct netr_DomainTrust *trusts = NULL;
296 uint32_t num_trusts = 0;
300 DEBUG(3,("samr: trusted domains\n"));
303 ZERO_STRUCTP(ptrust_list);
306 tmp_ctx = talloc_stackframe();
307 if (tmp_ctx == NULL) {
308 return NT_STATUS_NO_MEMORY;
311 status = open_cached_internal_pipe_conn(domain,
316 if (!NT_STATUS_IS_OK(status)) {
320 status = rpc_trusted_domains(tmp_ctx,
325 if (!NT_STATUS_IS_OK(status)) {
330 ptrust_list->count = num_trusts;
331 ptrust_list->array = talloc_move(mem_ctx, &trusts);
335 TALLOC_FREE(tmp_ctx);
339 /* Lookup group membership given a rid. */
340 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
342 const struct dom_sid *group_sid,
343 enum lsa_SidType type,
344 uint32_t *pnum_names,
345 struct dom_sid **psid_mem,
347 uint32_t **pname_types)
349 struct rpc_pipe_client *samr_pipe;
350 struct policy_handle dom_pol = { 0 };
352 uint32_t num_names = 0;
353 struct dom_sid *sid_mem = NULL;
355 uint32_t *name_types = NULL;
360 DEBUG(3,("sam_lookup_groupmem\n"));
363 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
364 /* There's no groups, only aliases in BUILTIN */
365 return NT_STATUS_NO_SUCH_GROUP;
372 tmp_ctx = talloc_stackframe();
373 if (tmp_ctx == NULL) {
374 return NT_STATUS_NO_MEMORY;
377 status = open_cached_internal_pipe_conn(domain,
382 if (!NT_STATUS_IS_OK(status)) {
386 status = rpc_lookup_groupmem(tmp_ctx,
399 *pnum_names = num_names;
403 *pnames = talloc_move(mem_ctx, &names);
407 *pname_types = talloc_move(mem_ctx, &name_types);
411 *psid_mem = talloc_move(mem_ctx, &sid_mem);
415 TALLOC_FREE(tmp_ctx);
419 /*********************************************************************
420 BUILTIN specific functions.
421 *********************************************************************/
423 /* List all domain groups */
424 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
426 uint32_t *num_entries,
427 struct wb_acct_info **info)
429 /* BUILTIN doesn't have domain groups */
435 /* Query display info for a domain */
436 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
440 /* We don't have users */
445 /* get a list of trusted domains - builtin domain */
446 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
448 struct netr_DomainTrustList *trusts)
450 ZERO_STRUCTP(trusts);
454 /*********************************************************************
456 *********************************************************************/
458 /* List all local groups (aliases) */
459 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
462 struct wb_acct_info **pinfo)
464 struct rpc_pipe_client *samr_pipe;
465 struct policy_handle dom_pol = { 0 };
466 struct wb_acct_info *info = NULL;
467 uint32_t num_info = 0;
471 DEBUG(3,("samr: enum local groups\n"));
477 tmp_ctx = talloc_stackframe();
478 if (tmp_ctx == NULL) {
479 return NT_STATUS_NO_MEMORY;
482 status = open_cached_internal_pipe_conn(domain,
487 if (!NT_STATUS_IS_OK(status)) {
491 status = rpc_enum_local_groups(mem_ctx,
496 if (!NT_STATUS_IS_OK(status)) {
501 *pnum_info = num_info;
505 *pinfo = talloc_move(mem_ctx, &info);
509 TALLOC_FREE(tmp_ctx);
513 /* convert a single name to a sid in a domain */
514 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
516 const char *domain_name,
519 struct dom_sid *psid,
520 enum lsa_SidType *ptype)
522 struct rpc_pipe_client *lsa_pipe;
523 struct policy_handle lsa_policy = { 0 };
525 enum lsa_SidType type;
529 DEBUG(3,("sam_name_to_sid\n"));
531 tmp_ctx = talloc_stackframe();
532 if (tmp_ctx == NULL) {
533 return NT_STATUS_NO_MEMORY;
536 status = open_cached_internal_pipe_conn(domain,
541 if (!NT_STATUS_IS_OK(status)) {
545 status = rpc_name_to_sid(tmp_ctx,
553 if (!NT_STATUS_IS_OK(status)) {
558 sid_copy(psid, &sid);
565 TALLOC_FREE(tmp_ctx);
569 /* convert a domain SID to a user or group name */
570 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
572 const struct dom_sid *sid,
575 enum lsa_SidType *ptype)
577 struct rpc_pipe_client *lsa_pipe;
578 struct policy_handle lsa_policy = { 0 };
579 char *domain_name = NULL;
581 enum lsa_SidType type;
585 DEBUG(3,("sam_sid_to_name\n"));
588 if (!sid_check_is_in_builtin(sid) &&
589 !sid_check_is_builtin(sid) &&
590 !sid_check_is_in_our_sam(sid) &&
591 !sid_check_is_our_sam(sid) &&
592 !sid_check_is_in_unix_users(sid) &&
593 !sid_check_is_unix_users(sid) &&
594 !sid_check_is_in_unix_groups(sid) &&
595 !sid_check_is_unix_groups(sid) &&
596 !sid_check_is_in_wellknown_domain(sid)) {
597 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
598 "lookup SID %s\n", sid_string_dbg(sid)));
599 return NT_STATUS_NONE_MAPPED;
602 tmp_ctx = talloc_stackframe();
603 if (tmp_ctx == NULL) {
604 return NT_STATUS_NO_MEMORY;
607 status = open_cached_internal_pipe_conn(domain,
612 if (!NT_STATUS_IS_OK(status)) {
616 status = rpc_sid_to_name(tmp_ctx,
630 *pname = talloc_move(mem_ctx, &name);
634 *pdomain_name = talloc_move(mem_ctx, &domain_name);
639 TALLOC_FREE(tmp_ctx);
643 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
645 const struct dom_sid *domain_sid,
650 enum lsa_SidType **ptypes)
652 struct rpc_pipe_client *lsa_pipe;
653 struct policy_handle lsa_policy = { 0 };
654 enum lsa_SidType *types = NULL;
655 char *domain_name = NULL;
660 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
663 if (!sid_check_is_builtin(domain_sid) &&
664 !sid_check_is_our_sam(domain_sid) &&
665 !sid_check_is_unix_users(domain_sid) &&
666 !sid_check_is_unix_groups(domain_sid) &&
667 !sid_check_is_in_wellknown_domain(domain_sid)) {
668 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
669 "lookup SID %s\n", sid_string_dbg(domain_sid)));
670 return NT_STATUS_NONE_MAPPED;
673 tmp_ctx = talloc_stackframe();
674 if (tmp_ctx == NULL) {
675 return NT_STATUS_NO_MEMORY;
678 status = open_cached_internal_pipe_conn(domain,
683 if (!NT_STATUS_IS_OK(status)) {
687 status = rpc_rids_to_names(tmp_ctx,
697 if (!NT_STATUS_IS_OK(status)) {
702 *pdomain_name = talloc_move(mem_ctx, &domain_name);
706 *ptypes = talloc_move(mem_ctx, &types);
710 *pnames = talloc_move(mem_ctx, &names);
714 TALLOC_FREE(tmp_ctx);
718 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
720 struct samr_DomInfo12 *lockout_policy)
722 struct rpc_pipe_client *samr_pipe;
723 struct policy_handle dom_pol = { 0 };
724 union samr_DomainInfo *info = NULL;
726 NTSTATUS status, result;
727 struct dcerpc_binding_handle *b = NULL;
729 DEBUG(3,("sam_lockout_policy\n"));
731 tmp_ctx = talloc_stackframe();
732 if (tmp_ctx == NULL) {
733 return NT_STATUS_NO_MEMORY;
736 status = open_cached_internal_pipe_conn(domain,
741 if (!NT_STATUS_IS_OK(status)) {
745 b = samr_pipe->binding_handle;
747 status = dcerpc_samr_QueryDomainInfo(b,
750 DomainLockoutInformation,
753 if (!NT_STATUS_IS_OK(status)) {
756 if (!NT_STATUS_IS_OK(result)) {
761 *lockout_policy = info->info12;
764 TALLOC_FREE(tmp_ctx);
768 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
770 struct samr_DomInfo1 *passwd_policy)
772 struct rpc_pipe_client *samr_pipe;
773 struct policy_handle dom_pol = { 0 };
774 union samr_DomainInfo *info = NULL;
776 NTSTATUS status, result;
777 struct dcerpc_binding_handle *b = NULL;
779 DEBUG(3,("sam_password_policy\n"));
781 tmp_ctx = talloc_stackframe();
782 if (tmp_ctx == NULL) {
783 return NT_STATUS_NO_MEMORY;
786 status = open_cached_internal_pipe_conn(domain,
791 if (!NT_STATUS_IS_OK(status)) {
795 b = samr_pipe->binding_handle;
797 status = dcerpc_samr_QueryDomainInfo(b,
800 DomainPasswordInformation,
803 if (!NT_STATUS_IS_OK(status)) {
806 if (!NT_STATUS_IS_OK(result)) {
811 *passwd_policy = info->info1;
814 TALLOC_FREE(tmp_ctx);
818 /* Lookup groups a user is a member of. */
819 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
821 const struct dom_sid *user_sid,
822 uint32_t *pnum_groups,
823 struct dom_sid **puser_grpsids)
825 struct rpc_pipe_client *samr_pipe;
826 struct policy_handle dom_pol;
827 struct dom_sid *user_grpsids = NULL;
828 uint32_t num_groups = 0;
832 DEBUG(3,("sam_lookup_usergroups\n"));
834 ZERO_STRUCT(dom_pol);
840 tmp_ctx = talloc_stackframe();
841 if (tmp_ctx == NULL) {
842 return NT_STATUS_NO_MEMORY;
845 status = open_cached_internal_pipe_conn(domain,
850 if (!NT_STATUS_IS_OK(status)) {
854 status = rpc_lookup_usergroups(tmp_ctx,
861 if (!NT_STATUS_IS_OK(status)) {
866 *pnum_groups = num_groups;
870 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
875 TALLOC_FREE(tmp_ctx);
879 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
882 const struct dom_sid *sids,
883 uint32_t *pnum_aliases,
884 uint32_t **palias_rids)
886 struct rpc_pipe_client *samr_pipe;
887 struct policy_handle dom_pol = { 0 };
888 uint32_t num_aliases = 0;
889 uint32_t *alias_rids = NULL;
893 DEBUG(3,("sam_lookup_useraliases\n"));
899 tmp_ctx = talloc_stackframe();
900 if (tmp_ctx == NULL) {
901 return NT_STATUS_NO_MEMORY;
904 status = open_cached_internal_pipe_conn(domain,
909 if (!NT_STATUS_IS_OK(status)) {
913 status = rpc_lookup_useraliases(tmp_ctx,
920 if (!NT_STATUS_IS_OK(status)) {
925 *pnum_aliases = num_aliases;
929 *palias_rids = talloc_move(mem_ctx, &alias_rids);
934 TALLOC_FREE(tmp_ctx);
938 /* find the sequence number for a domain */
939 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
942 struct rpc_pipe_client *samr_pipe;
943 struct policy_handle dom_pol = { 0 };
944 uint32_t seq = DOM_SEQUENCE_NONE;
948 DEBUG(3,("samr: sequence number\n"));
951 *pseq = DOM_SEQUENCE_NONE;
954 tmp_ctx = talloc_stackframe();
955 if (tmp_ctx == NULL) {
956 return NT_STATUS_NO_MEMORY;
959 status = open_cached_internal_pipe_conn(domain,
964 if (!NT_STATUS_IS_OK(status)) {
968 status = rpc_sequence_number(tmp_ctx,
973 if (!NT_STATUS_IS_OK(status)) {
982 TALLOC_FREE(tmp_ctx);
986 /* the rpc backend methods are exposed via this structure */
987 struct winbindd_methods builtin_passdb_methods = {
990 .query_user_list = builtin_query_user_list,
991 .enum_dom_groups = builtin_enum_dom_groups,
992 .enum_local_groups = sam_enum_local_groups,
993 .name_to_sid = sam_name_to_sid,
994 .sid_to_name = sam_sid_to_name,
995 .rids_to_names = sam_rids_to_names,
996 .lookup_usergroups = sam_lookup_usergroups,
997 .lookup_useraliases = sam_lookup_useraliases,
998 .lookup_groupmem = sam_lookup_groupmem,
999 .sequence_number = sam_sequence_number,
1000 .lockout_policy = sam_lockout_policy,
1001 .password_policy = sam_password_policy,
1002 .trusted_domains = builtin_trusted_domains
1005 /* the rpc backend methods are exposed via this structure */
1006 struct winbindd_methods sam_passdb_methods = {
1007 .consistent = false,
1009 .query_user_list = sam_query_user_list,
1010 .enum_dom_groups = sam_enum_dom_groups,
1011 .enum_local_groups = sam_enum_local_groups,
1012 .name_to_sid = sam_name_to_sid,
1013 .sid_to_name = sam_sid_to_name,
1014 .rids_to_names = sam_rids_to_names,
1015 .lookup_usergroups = sam_lookup_usergroups,
1016 .lookup_useraliases = sam_lookup_useraliases,
1017 .lookup_groupmem = sam_lookup_groupmem,
1018 .sequence_number = sam_sequence_number,
1019 .lockout_policy = sam_lockout_policy,
1020 .password_policy = sam_password_policy,
1021 .trusted_domains = sam_trusted_domains