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 "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"
42 #define DBGC_CLASS DBGC_WINBIND
45 * The other end of this won't go away easily, so we can trust it
47 * It is either a long-lived process with the same lifetime as
48 * winbindd or a part of this process
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;
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)
63 NTSTATUS status, result;
64 struct policy_handle samr_connect_hnd;
65 struct dcerpc_binding_handle *b;
67 status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
68 if (!NT_STATUS_IS_OK(status)) {
72 b = (*samr_pipe)->binding_handle;
74 status = dcerpc_samr_Connect2(b, mem_ctx,
75 (*samr_pipe)->desthost,
76 SEC_FLAG_MAXIMUM_ALLOWED,
79 if (!NT_STATUS_IS_OK(status)) {
82 if (!NT_STATUS_IS_OK(result)) {
86 status = dcerpc_samr_OpenDomain(b, mem_ctx,
88 SEC_FLAG_MAXIMUM_ALLOWED,
92 if (!NT_STATUS_IS_OK(status)) {
99 NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
100 struct rpc_pipe_client **lsa_pipe,
101 struct policy_handle *lsa_hnd)
105 status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
106 if (!NT_STATUS_IS_OK(status)) {
110 status = rpccli_lsa_open_policy((*lsa_pipe),
113 SEC_FLAG_MAXIMUM_ALLOWED,
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)
127 struct winbind_internal_pipes *internal_pipes = NULL;
129 if (domain->private_data == NULL) {
130 TALLOC_CTX *frame = talloc_stackframe();
133 internal_pipes = talloc_zero(frame,
134 struct winbind_internal_pipes);
136 status = open_internal_samr_conn(
139 &internal_pipes->samr_pipe,
140 &internal_pipes->samr_domain_hnd);
141 if (!NT_STATUS_IS_OK(status)) {
146 status = open_internal_lsa_conn(internal_pipes,
147 &internal_pipes->lsa_pipe,
148 &internal_pipes->lsa_hnd);
150 if (!NT_STATUS_IS_OK(status)) {
155 domain->private_data = talloc_move(domain, &internal_pipes);
161 internal_pipes = talloc_get_type_abort(
162 domain->private_data, struct winbind_internal_pipes);
164 if (samr_domain_hnd) {
165 *samr_domain_hnd = internal_pipes->samr_domain_hnd;
169 *samr_pipe = internal_pipes->samr_pipe;
173 *lsa_hnd = internal_pipes->lsa_hnd;
177 *lsa_pipe = internal_pipes->lsa_pipe;
183 static bool reset_connection_on_error(struct winbindd_domain *domain,
184 struct rpc_pipe_client *p,
187 struct winbind_internal_pipes *internal_pipes = NULL;
188 struct dcerpc_binding_handle *b = p->binding_handle;
190 internal_pipes = talloc_get_type_abort(
191 domain->private_data, struct winbind_internal_pipes);
193 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
194 NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR))
196 TALLOC_FREE(internal_pipes);
197 domain->private_data = NULL;
201 if (!dcerpc_binding_handle_is_connected(b)) {
202 TALLOC_FREE(internal_pipes);
203 domain->private_data = NULL;
210 /*********************************************************************
211 SAM specific functions.
212 *********************************************************************/
214 /* List all domain groups */
215 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
218 struct wb_acct_info **pinfo)
220 struct rpc_pipe_client *samr_pipe;
221 struct policy_handle dom_pol = { 0 };
222 struct wb_acct_info *info = NULL;
223 uint32_t num_info = 0;
228 DEBUG(3,("sam_enum_dom_groups\n"));
234 tmp_ctx = talloc_stackframe();
235 if (tmp_ctx == NULL) {
236 return NT_STATUS_NO_MEMORY;
240 status = open_cached_internal_pipe_conn(domain,
245 if (!NT_STATUS_IS_OK(status)) {
246 TALLOC_FREE(tmp_ctx);
250 status = rpc_enum_dom_groups(tmp_ctx,
256 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
261 if (!NT_STATUS_IS_OK(status)) {
262 TALLOC_FREE(tmp_ctx);
267 *pnum_info = num_info;
271 *pinfo = talloc_move(mem_ctx, &info);
274 TALLOC_FREE(tmp_ctx);
278 /* Query display info for a domain */
279 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
283 struct rpc_pipe_client *samr_pipe = NULL;
284 struct policy_handle dom_pol = { 0 };
285 uint32_t *rids = NULL;
290 DEBUG(3,("samr_query_user_list\n"));
292 tmp_ctx = talloc_stackframe();
293 if (tmp_ctx == NULL) {
294 return NT_STATUS_NO_MEMORY;
298 status = open_cached_internal_pipe_conn(domain,
303 if (!NT_STATUS_IS_OK(status)) {
307 status = rpc_query_user_list(tmp_ctx,
312 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
317 if (!NT_STATUS_IS_OK(status)) {
322 *prids = talloc_move(mem_ctx, &rids);
327 TALLOC_FREE(tmp_ctx);
331 /* get a list of trusted domains - builtin domain */
332 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
334 struct netr_DomainTrustList *ptrust_list)
336 struct rpc_pipe_client *lsa_pipe;
337 struct policy_handle lsa_policy = { 0 };
338 struct netr_DomainTrust *trusts = NULL;
339 uint32_t num_trusts = 0;
344 DEBUG(3,("samr: trusted domains\n"));
347 ZERO_STRUCTP(ptrust_list);
350 tmp_ctx = talloc_stackframe();
351 if (tmp_ctx == NULL) {
352 return NT_STATUS_NO_MEMORY;
356 status = open_cached_internal_pipe_conn(domain,
361 if (!NT_STATUS_IS_OK(status)) {
365 status = rpc_trusted_domains(tmp_ctx,
371 if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
376 if (!NT_STATUS_IS_OK(status)) {
381 ptrust_list->count = num_trusts;
382 ptrust_list->array = talloc_move(mem_ctx, &trusts);
386 TALLOC_FREE(tmp_ctx);
390 /* Lookup group membership given a rid. */
391 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
393 const struct dom_sid *group_sid,
394 enum lsa_SidType type,
395 uint32_t *pnum_names,
396 struct dom_sid **psid_mem,
398 uint32_t **pname_types)
400 struct rpc_pipe_client *samr_pipe;
401 struct policy_handle dom_pol = { 0 };
403 uint32_t num_names = 0;
404 struct dom_sid *sid_mem = NULL;
406 uint32_t *name_types = NULL;
412 DEBUG(3,("sam_lookup_groupmem\n"));
415 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
416 /* There's no groups, only aliases in BUILTIN */
417 return NT_STATUS_NO_SUCH_GROUP;
424 tmp_ctx = talloc_stackframe();
425 if (tmp_ctx == NULL) {
426 return NT_STATUS_NO_MEMORY;
430 status = open_cached_internal_pipe_conn(domain,
435 if (!NT_STATUS_IS_OK(status)) {
439 status = rpc_lookup_groupmem(tmp_ctx,
451 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
457 *pnum_names = num_names;
461 *pnames = talloc_move(mem_ctx, &names);
465 *pname_types = talloc_move(mem_ctx, &name_types);
469 *psid_mem = talloc_move(mem_ctx, &sid_mem);
473 TALLOC_FREE(tmp_ctx);
477 /*********************************************************************
478 BUILTIN specific functions.
479 *********************************************************************/
481 /* List all domain groups */
482 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
484 uint32_t *num_entries,
485 struct wb_acct_info **info)
487 /* BUILTIN doesn't have domain groups */
493 /* Query display info for a domain */
494 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
498 /* We don't have users */
503 /* get a list of trusted domains - builtin domain */
504 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
506 struct netr_DomainTrustList *trusts)
508 ZERO_STRUCTP(trusts);
512 /*********************************************************************
514 *********************************************************************/
516 /* List all local groups (aliases) */
517 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
520 struct wb_acct_info **pinfo)
522 struct rpc_pipe_client *samr_pipe;
523 struct policy_handle dom_pol = { 0 };
524 struct wb_acct_info *info = NULL;
525 uint32_t num_info = 0;
530 DEBUG(3,("samr: enum local groups\n"));
536 tmp_ctx = talloc_stackframe();
537 if (tmp_ctx == NULL) {
538 return NT_STATUS_NO_MEMORY;
542 status = open_cached_internal_pipe_conn(domain,
547 if (!NT_STATUS_IS_OK(status)) {
551 status = rpc_enum_local_groups(mem_ctx,
557 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
562 if (!NT_STATUS_IS_OK(status)) {
567 *pnum_info = num_info;
571 *pinfo = talloc_move(mem_ctx, &info);
575 TALLOC_FREE(tmp_ctx);
579 /* convert a single name to a sid in a domain */
580 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
582 const char *domain_name,
585 const char **pdom_name,
586 struct dom_sid *psid,
587 enum lsa_SidType *ptype)
589 struct rpc_pipe_client *lsa_pipe;
590 struct policy_handle lsa_policy = { 0 };
592 const char *dom_name;
593 enum lsa_SidType type;
598 DEBUG(3,("sam_name_to_sid\n"));
600 tmp_ctx = talloc_stackframe();
601 if (tmp_ctx == NULL) {
602 return NT_STATUS_NO_MEMORY;
606 status = open_cached_internal_pipe_conn(domain,
611 if (!NT_STATUS_IS_OK(status)) {
615 status = rpc_name_to_sid(tmp_ctx,
625 if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
630 if (!NT_STATUS_IS_OK(status)) {
634 if (pdom_name != NULL) {
635 *pdom_name = talloc_strdup(mem_ctx, dom_name);
636 if (*pdom_name == NULL) {
637 status = NT_STATUS_NO_MEMORY;
643 sid_copy(psid, &sid);
650 TALLOC_FREE(tmp_ctx);
654 /* convert a domain SID to a user or group name */
655 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
657 const struct dom_sid *sid,
660 enum lsa_SidType *ptype)
662 struct rpc_pipe_client *lsa_pipe;
663 struct policy_handle lsa_policy = { 0 };
664 char *domain_name = NULL;
666 enum lsa_SidType type;
671 DEBUG(3,("sam_sid_to_name\n"));
674 if (!sid_check_is_in_builtin(sid) &&
675 !sid_check_is_builtin(sid) &&
676 !sid_check_is_in_our_sam(sid) &&
677 !sid_check_is_our_sam(sid) &&
678 !sid_check_is_in_unix_users(sid) &&
679 !sid_check_is_unix_users(sid) &&
680 !sid_check_is_in_unix_groups(sid) &&
681 !sid_check_is_unix_groups(sid) &&
682 !sid_check_is_in_wellknown_domain(sid)) {
683 struct dom_sid_buf buf;
684 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
686 dom_sid_str_buf(sid, &buf)));
687 return NT_STATUS_NONE_MAPPED;
690 tmp_ctx = talloc_stackframe();
691 if (tmp_ctx == NULL) {
692 return NT_STATUS_NO_MEMORY;
696 status = open_cached_internal_pipe_conn(domain,
701 if (!NT_STATUS_IS_OK(status)) {
705 status = rpc_sid_to_name(tmp_ctx,
714 if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
724 *pname = talloc_move(mem_ctx, &name);
728 *pdomain_name = talloc_move(mem_ctx, &domain_name);
733 TALLOC_FREE(tmp_ctx);
737 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
739 const struct dom_sid *domain_sid,
744 enum lsa_SidType **ptypes)
746 struct rpc_pipe_client *lsa_pipe;
747 struct policy_handle lsa_policy = { 0 };
748 enum lsa_SidType *types = NULL;
749 char *domain_name = NULL;
755 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
758 if (!sid_check_is_builtin(domain_sid) &&
759 !sid_check_is_our_sam(domain_sid) &&
760 !sid_check_is_unix_users(domain_sid) &&
761 !sid_check_is_unix_groups(domain_sid) &&
762 !sid_check_is_in_wellknown_domain(domain_sid)) {
763 struct dom_sid_buf buf;
764 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
766 dom_sid_str_buf(domain_sid, &buf)));
767 return NT_STATUS_NONE_MAPPED;
770 tmp_ctx = talloc_stackframe();
771 if (tmp_ctx == NULL) {
772 return NT_STATUS_NO_MEMORY;
776 status = open_cached_internal_pipe_conn(domain,
781 if (!NT_STATUS_IS_OK(status)) {
785 status = rpc_rids_to_names(tmp_ctx,
796 if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
801 if (!NT_STATUS_IS_OK(status)) {
806 *pdomain_name = talloc_move(mem_ctx, &domain_name);
810 *ptypes = talloc_move(mem_ctx, &types);
814 *pnames = talloc_move(mem_ctx, &names);
818 TALLOC_FREE(tmp_ctx);
822 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
824 struct samr_DomInfo12 *lockout_policy)
826 struct rpc_pipe_client *samr_pipe;
827 struct policy_handle dom_pol = { 0 };
828 union samr_DomainInfo *info = NULL;
830 NTSTATUS status, result;
831 struct dcerpc_binding_handle *b = NULL;
834 DEBUG(3,("sam_lockout_policy\n"));
836 tmp_ctx = talloc_stackframe();
837 if (tmp_ctx == NULL) {
838 return NT_STATUS_NO_MEMORY;
842 status = open_cached_internal_pipe_conn(domain,
847 if (!NT_STATUS_IS_OK(status)) {
851 b = samr_pipe->binding_handle;
853 status = dcerpc_samr_QueryDomainInfo(b,
856 DomainLockoutInformation,
860 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
865 if (!NT_STATUS_IS_OK(status)) {
868 if (!NT_STATUS_IS_OK(result)) {
873 *lockout_policy = info->info12;
876 TALLOC_FREE(tmp_ctx);
880 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
882 struct samr_DomInfo1 *passwd_policy)
884 struct rpc_pipe_client *samr_pipe;
885 struct policy_handle dom_pol = { 0 };
886 union samr_DomainInfo *info = NULL;
888 NTSTATUS status, result;
889 struct dcerpc_binding_handle *b = NULL;
892 DEBUG(3,("sam_password_policy\n"));
894 tmp_ctx = talloc_stackframe();
895 if (tmp_ctx == NULL) {
896 return NT_STATUS_NO_MEMORY;
900 status = open_cached_internal_pipe_conn(domain,
905 if (!NT_STATUS_IS_OK(status)) {
909 b = samr_pipe->binding_handle;
911 status = dcerpc_samr_QueryDomainInfo(b,
914 DomainPasswordInformation,
918 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
923 if (!NT_STATUS_IS_OK(status)) {
926 if (!NT_STATUS_IS_OK(result)) {
931 *passwd_policy = info->info1;
934 TALLOC_FREE(tmp_ctx);
938 /* Lookup groups a user is a member of. */
939 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
941 const struct dom_sid *user_sid,
942 uint32_t *pnum_groups,
943 struct dom_sid **puser_grpsids)
945 struct rpc_pipe_client *samr_pipe;
946 struct policy_handle dom_pol;
947 struct dom_sid *user_grpsids = NULL;
948 uint32_t num_groups = 0;
953 DEBUG(3,("sam_lookup_usergroups\n"));
955 ZERO_STRUCT(dom_pol);
961 tmp_ctx = talloc_stackframe();
962 if (tmp_ctx == NULL) {
963 return NT_STATUS_NO_MEMORY;
967 status = open_cached_internal_pipe_conn(domain,
972 if (!NT_STATUS_IS_OK(status)) {
976 status = rpc_lookup_usergroups(tmp_ctx,
984 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
989 if (!NT_STATUS_IS_OK(status)) {
994 *pnum_groups = num_groups;
998 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
1003 TALLOC_FREE(tmp_ctx);
1007 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
1008 TALLOC_CTX *mem_ctx,
1010 const struct dom_sid *sids,
1011 uint32_t *pnum_aliases,
1012 uint32_t **palias_rids)
1014 struct rpc_pipe_client *samr_pipe;
1015 struct policy_handle dom_pol = { 0 };
1016 uint32_t num_aliases = 0;
1017 uint32_t *alias_rids = NULL;
1018 TALLOC_CTX *tmp_ctx;
1022 DEBUG(3,("sam_lookup_useraliases\n"));
1028 tmp_ctx = talloc_stackframe();
1029 if (tmp_ctx == NULL) {
1030 return NT_STATUS_NO_MEMORY;
1034 status = open_cached_internal_pipe_conn(domain,
1039 if (!NT_STATUS_IS_OK(status)) {
1043 status = rpc_lookup_useraliases(tmp_ctx,
1051 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
1056 if (!NT_STATUS_IS_OK(status)) {
1061 *pnum_aliases = num_aliases;
1065 *palias_rids = talloc_move(mem_ctx, &alias_rids);
1070 TALLOC_FREE(tmp_ctx);
1074 /* find the sequence number for a domain */
1075 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
1078 struct rpc_pipe_client *samr_pipe;
1079 struct policy_handle dom_pol = { 0 };
1080 uint32_t seq = DOM_SEQUENCE_NONE;
1081 TALLOC_CTX *tmp_ctx;
1085 DEBUG(3,("samr: sequence number\n"));
1088 *pseq = DOM_SEQUENCE_NONE;
1091 tmp_ctx = talloc_stackframe();
1092 if (tmp_ctx == NULL) {
1093 return NT_STATUS_NO_MEMORY;
1097 status = open_cached_internal_pipe_conn(domain,
1102 if (!NT_STATUS_IS_OK(status)) {
1106 status = rpc_sequence_number(tmp_ctx,
1112 if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
1117 if (!NT_STATUS_IS_OK(status)) {
1126 TALLOC_FREE(tmp_ctx);
1130 /* the rpc backend methods are exposed via this structure */
1131 struct winbindd_methods builtin_passdb_methods = {
1132 .consistent = false,
1134 .query_user_list = builtin_query_user_list,
1135 .enum_dom_groups = builtin_enum_dom_groups,
1136 .enum_local_groups = sam_enum_local_groups,
1137 .name_to_sid = sam_name_to_sid,
1138 .sid_to_name = sam_sid_to_name,
1139 .rids_to_names = sam_rids_to_names,
1140 .lookup_usergroups = sam_lookup_usergroups,
1141 .lookup_useraliases = sam_lookup_useraliases,
1142 .lookup_groupmem = sam_lookup_groupmem,
1143 .sequence_number = sam_sequence_number,
1144 .lockout_policy = sam_lockout_policy,
1145 .password_policy = sam_password_policy,
1146 .trusted_domains = builtin_trusted_domains
1149 /* the rpc backend methods are exposed via this structure */
1150 struct winbindd_methods sam_passdb_methods = {
1151 .consistent = false,
1153 .query_user_list = sam_query_user_list,
1154 .enum_dom_groups = sam_enum_dom_groups,
1155 .enum_local_groups = sam_enum_local_groups,
1156 .name_to_sid = sam_name_to_sid,
1157 .sid_to_name = sam_sid_to_name,
1158 .rids_to_names = sam_rids_to_names,
1159 .lookup_usergroups = sam_lookup_usergroups,
1160 .lookup_useraliases = sam_lookup_useraliases,
1161 .lookup_groupmem = sam_lookup_groupmem,
1162 .sequence_number = sam_sequence_number,
1163 .lockout_policy = sam_lockout_policy,
1164 .password_policy = sam_password_policy,
1165 .trusted_domains = sam_trusted_domains