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
43 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
44 struct winbindd_domain *domain,
45 struct rpc_pipe_client **samr_pipe,
46 struct policy_handle *samr_domain_hnd)
48 NTSTATUS status, result;
49 struct policy_handle samr_connect_hnd;
50 struct dcerpc_binding_handle *b;
52 status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
53 if (!NT_STATUS_IS_OK(status)) {
57 b = (*samr_pipe)->binding_handle;
59 status = dcerpc_samr_Connect2(b, mem_ctx,
60 (*samr_pipe)->desthost,
61 SEC_FLAG_MAXIMUM_ALLOWED,
64 if (!NT_STATUS_IS_OK(status)) {
67 if (!NT_STATUS_IS_OK(result)) {
71 status = dcerpc_samr_OpenDomain(b, mem_ctx,
73 SEC_FLAG_MAXIMUM_ALLOWED,
77 if (!NT_STATUS_IS_OK(status)) {
84 NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
85 struct rpc_pipe_client **lsa_pipe,
86 struct policy_handle *lsa_hnd)
90 status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
91 if (!NT_STATUS_IS_OK(status)) {
95 status = rpccli_lsa_open_policy((*lsa_pipe),
98 SEC_FLAG_MAXIMUM_ALLOWED,
104 /*********************************************************************
105 SAM specific functions.
106 *********************************************************************/
108 /* List all domain groups */
109 static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
112 struct wb_acct_info **pinfo)
114 struct rpc_pipe_client *samr_pipe;
115 struct policy_handle dom_pol = { 0 };
116 struct wb_acct_info *info = NULL;
117 uint32_t num_info = 0;
119 NTSTATUS status, result;
120 struct dcerpc_binding_handle *b = NULL;
122 DEBUG(3,("sam_enum_dom_groups\n"));
128 tmp_ctx = talloc_stackframe();
129 if (tmp_ctx == NULL) {
130 return NT_STATUS_NO_MEMORY;
133 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
134 if (!NT_STATUS_IS_OK(status)) {
138 b = samr_pipe->binding_handle;
140 status = rpc_enum_dom_groups(tmp_ctx,
145 if (!NT_STATUS_IS_OK(status)) {
150 *pnum_info = num_info;
154 *pinfo = talloc_move(mem_ctx, &info);
158 if (b && is_valid_policy_hnd(&dom_pol)) {
159 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
161 TALLOC_FREE(tmp_ctx);
165 /* Query display info for a domain */
166 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
170 struct rpc_pipe_client *samr_pipe = NULL;
171 struct policy_handle dom_pol = { 0 };
174 NTSTATUS status, result;
175 struct dcerpc_binding_handle *b = NULL;
177 DEBUG(3,("samr_query_user_list\n"));
181 tmp_ctx = talloc_stackframe();
182 if (tmp_ctx == NULL) {
183 return NT_STATUS_NO_MEMORY;
186 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
187 if (!NT_STATUS_IS_OK(status)) {
191 b = samr_pipe->binding_handle;
193 status = rpc_query_user_list(tmp_ctx,
198 if (!NT_STATUS_IS_OK(status)) {
203 *prids = talloc_move(mem_ctx, &rids);
207 if (b && is_valid_policy_hnd(&dom_pol)) {
208 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
211 TALLOC_FREE(tmp_ctx);
215 /* get a list of trusted domains - builtin domain */
216 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
218 struct netr_DomainTrustList *ptrust_list)
220 struct rpc_pipe_client *lsa_pipe;
221 struct policy_handle lsa_policy = { 0 };
222 struct netr_DomainTrust *trusts = NULL;
223 uint32_t num_trusts = 0;
225 NTSTATUS status, result;
226 struct dcerpc_binding_handle *b = NULL;
228 DEBUG(3,("samr: trusted domains\n"));
231 ZERO_STRUCTP(ptrust_list);
234 tmp_ctx = talloc_stackframe();
235 if (tmp_ctx == NULL) {
236 return NT_STATUS_NO_MEMORY;
239 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
240 if (!NT_STATUS_IS_OK(status)) {
244 b = lsa_pipe->binding_handle;
246 status = rpc_trusted_domains(tmp_ctx,
251 if (!NT_STATUS_IS_OK(status)) {
256 ptrust_list->count = num_trusts;
257 ptrust_list->array = talloc_move(mem_ctx, &trusts);
261 if (b && is_valid_policy_hnd(&lsa_policy)) {
262 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
265 TALLOC_FREE(tmp_ctx);
269 /* Lookup group membership given a rid. */
270 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
272 const struct dom_sid *group_sid,
273 enum lsa_SidType type,
274 uint32_t *pnum_names,
275 struct dom_sid **psid_mem,
277 uint32_t **pname_types)
279 struct rpc_pipe_client *samr_pipe;
280 struct policy_handle dom_pol = { 0 };
282 uint32_t num_names = 0;
283 struct dom_sid *sid_mem = NULL;
285 uint32_t *name_types = NULL;
288 NTSTATUS status, result;
289 struct dcerpc_binding_handle *b = NULL;
291 DEBUG(3,("sam_lookup_groupmem\n"));
294 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
295 /* There's no groups, only aliases in BUILTIN */
296 return NT_STATUS_NO_SUCH_GROUP;
303 tmp_ctx = talloc_stackframe();
304 if (tmp_ctx == NULL) {
305 return NT_STATUS_NO_MEMORY;
308 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
309 if (!NT_STATUS_IS_OK(status)) {
313 b = samr_pipe->binding_handle;
315 status = rpc_lookup_groupmem(tmp_ctx,
328 *pnum_names = num_names;
332 *pnames = talloc_move(mem_ctx, &names);
336 *pname_types = talloc_move(mem_ctx, &name_types);
340 *psid_mem = talloc_move(mem_ctx, &sid_mem);
344 if (b && is_valid_policy_hnd(&dom_pol)) {
345 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
348 TALLOC_FREE(tmp_ctx);
352 /*********************************************************************
353 BUILTIN specific functions.
354 *********************************************************************/
356 /* List all domain groups */
357 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
359 uint32_t *num_entries,
360 struct wb_acct_info **info)
362 /* BUILTIN doesn't have domain groups */
368 /* Query display info for a domain */
369 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
373 /* We don't have users */
378 /* get a list of trusted domains - builtin domain */
379 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
381 struct netr_DomainTrustList *trusts)
383 ZERO_STRUCTP(trusts);
387 /*********************************************************************
389 *********************************************************************/
391 /* List all local groups (aliases) */
392 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
395 struct wb_acct_info **pinfo)
397 struct rpc_pipe_client *samr_pipe;
398 struct policy_handle dom_pol = { 0 };
399 struct wb_acct_info *info = NULL;
400 uint32_t num_info = 0;
402 NTSTATUS status, result;
403 struct dcerpc_binding_handle *b = NULL;
405 DEBUG(3,("samr: enum local groups\n"));
411 tmp_ctx = talloc_stackframe();
412 if (tmp_ctx == NULL) {
413 return NT_STATUS_NO_MEMORY;
416 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
417 if (!NT_STATUS_IS_OK(status)) {
421 b = samr_pipe->binding_handle;
423 status = rpc_enum_local_groups(mem_ctx,
428 if (!NT_STATUS_IS_OK(status)) {
433 *pnum_info = num_info;
437 *pinfo = talloc_move(mem_ctx, &info);
441 if (b && is_valid_policy_hnd(&dom_pol)) {
442 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
445 TALLOC_FREE(tmp_ctx);
449 /* convert a single name to a sid in a domain */
450 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
452 const char *domain_name,
455 struct dom_sid *psid,
456 enum lsa_SidType *ptype)
458 struct rpc_pipe_client *lsa_pipe;
459 struct policy_handle lsa_policy = { 0 };
461 enum lsa_SidType type;
463 NTSTATUS status, result;
464 struct dcerpc_binding_handle *b = NULL;
466 DEBUG(3,("sam_name_to_sid\n"));
468 tmp_ctx = talloc_stackframe();
469 if (tmp_ctx == NULL) {
470 return NT_STATUS_NO_MEMORY;
473 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
474 if (!NT_STATUS_IS_OK(status)) {
478 b = lsa_pipe->binding_handle;
480 status = rpc_name_to_sid(tmp_ctx,
488 if (!NT_STATUS_IS_OK(status)) {
493 sid_copy(psid, &sid);
500 if (b && is_valid_policy_hnd(&lsa_policy)) {
501 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
504 TALLOC_FREE(tmp_ctx);
508 /* convert a domain SID to a user or group name */
509 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
511 const struct dom_sid *sid,
514 enum lsa_SidType *ptype)
516 struct rpc_pipe_client *lsa_pipe;
517 struct policy_handle lsa_policy = { 0 };
518 char *domain_name = NULL;
520 enum lsa_SidType type;
522 NTSTATUS status, result;
523 struct dcerpc_binding_handle *b = NULL;
525 DEBUG(3,("sam_sid_to_name\n"));
528 if (!sid_check_is_in_builtin(sid) &&
529 !sid_check_is_builtin(sid) &&
530 !sid_check_is_in_our_sam(sid) &&
531 !sid_check_is_our_sam(sid) &&
532 !sid_check_is_in_unix_users(sid) &&
533 !sid_check_is_unix_users(sid) &&
534 !sid_check_is_in_unix_groups(sid) &&
535 !sid_check_is_unix_groups(sid) &&
536 !sid_check_is_in_wellknown_domain(sid)) {
537 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
538 "lookup SID %s\n", sid_string_dbg(sid)));
539 return NT_STATUS_NONE_MAPPED;
542 tmp_ctx = talloc_stackframe();
543 if (tmp_ctx == NULL) {
544 return NT_STATUS_NO_MEMORY;
547 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
548 if (!NT_STATUS_IS_OK(status)) {
552 b = lsa_pipe->binding_handle;
554 status = rpc_sid_to_name(tmp_ctx,
568 *pname = talloc_move(mem_ctx, &name);
572 *pdomain_name = talloc_move(mem_ctx, &domain_name);
576 if (b && is_valid_policy_hnd(&lsa_policy)) {
577 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
580 TALLOC_FREE(tmp_ctx);
584 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
586 const struct dom_sid *domain_sid,
591 enum lsa_SidType **ptypes)
593 struct rpc_pipe_client *lsa_pipe;
594 struct policy_handle lsa_policy = { 0 };
595 enum lsa_SidType *types = NULL;
596 char *domain_name = NULL;
599 NTSTATUS status, result;
600 struct dcerpc_binding_handle *b = NULL;
602 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
605 if (!sid_check_is_builtin(domain_sid) &&
606 !sid_check_is_our_sam(domain_sid) &&
607 !sid_check_is_unix_users(domain_sid) &&
608 !sid_check_is_unix_groups(domain_sid) &&
609 !sid_check_is_in_wellknown_domain(domain_sid)) {
610 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
611 "lookup SID %s\n", sid_string_dbg(domain_sid)));
612 return NT_STATUS_NONE_MAPPED;
615 tmp_ctx = talloc_stackframe();
616 if (tmp_ctx == NULL) {
617 return NT_STATUS_NO_MEMORY;
620 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
621 if (!NT_STATUS_IS_OK(status)) {
625 b = lsa_pipe->binding_handle;
627 status = rpc_rids_to_names(tmp_ctx,
637 if (!NT_STATUS_IS_OK(status)) {
642 *pdomain_name = talloc_move(mem_ctx, &domain_name);
646 *ptypes = talloc_move(mem_ctx, &types);
650 *pnames = talloc_move(mem_ctx, &names);
654 if (b && is_valid_policy_hnd(&lsa_policy)) {
655 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
658 TALLOC_FREE(tmp_ctx);
662 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
664 struct samr_DomInfo12 *lockout_policy)
666 struct rpc_pipe_client *samr_pipe;
667 struct policy_handle dom_pol = { 0 };
668 union samr_DomainInfo *info = NULL;
670 NTSTATUS status, result;
671 struct dcerpc_binding_handle *b = NULL;
673 DEBUG(3,("sam_lockout_policy\n"));
675 tmp_ctx = talloc_stackframe();
676 if (tmp_ctx == NULL) {
677 return NT_STATUS_NO_MEMORY;
680 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
681 if (!NT_STATUS_IS_OK(status)) {
685 b = samr_pipe->binding_handle;
687 status = dcerpc_samr_QueryDomainInfo(b,
690 DomainLockoutInformation,
693 if (!NT_STATUS_IS_OK(status)) {
696 if (!NT_STATUS_IS_OK(result)) {
701 *lockout_policy = info->info12;
704 if (b && is_valid_policy_hnd(&dom_pol)) {
705 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
708 TALLOC_FREE(tmp_ctx);
712 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
714 struct samr_DomInfo1 *passwd_policy)
716 struct rpc_pipe_client *samr_pipe;
717 struct policy_handle dom_pol = { 0 };
718 union samr_DomainInfo *info = NULL;
720 NTSTATUS status, result;
721 struct dcerpc_binding_handle *b = NULL;
723 DEBUG(3,("sam_password_policy\n"));
725 tmp_ctx = talloc_stackframe();
726 if (tmp_ctx == NULL) {
727 return NT_STATUS_NO_MEMORY;
730 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
731 if (!NT_STATUS_IS_OK(status)) {
735 b = samr_pipe->binding_handle;
737 status = dcerpc_samr_QueryDomainInfo(b,
740 DomainPasswordInformation,
743 if (!NT_STATUS_IS_OK(status)) {
746 if (!NT_STATUS_IS_OK(result)) {
751 *passwd_policy = info->info1;
754 if (b && is_valid_policy_hnd(&dom_pol)) {
755 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
758 TALLOC_FREE(tmp_ctx);
762 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
765 const struct dom_sid *sids,
766 uint32_t *pnum_aliases,
767 uint32_t **palias_rids)
769 struct rpc_pipe_client *samr_pipe;
770 struct policy_handle dom_pol = { 0 };
771 uint32_t num_aliases = 0;
772 uint32_t *alias_rids = NULL;
774 NTSTATUS status, result;
775 struct dcerpc_binding_handle *b = NULL;
777 DEBUG(3,("sam_lookup_useraliases\n"));
783 tmp_ctx = talloc_stackframe();
784 if (tmp_ctx == NULL) {
785 return NT_STATUS_NO_MEMORY;
788 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
789 if (!NT_STATUS_IS_OK(status)) {
793 b = samr_pipe->binding_handle;
795 status = rpc_lookup_useraliases(tmp_ctx,
802 if (!NT_STATUS_IS_OK(status)) {
807 *pnum_aliases = num_aliases;
811 *palias_rids = talloc_move(mem_ctx, &alias_rids);
815 if (b && is_valid_policy_hnd(&dom_pol)) {
816 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
819 TALLOC_FREE(tmp_ctx);
823 /* find the sequence number for a domain */
824 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
827 struct rpc_pipe_client *samr_pipe;
828 struct policy_handle dom_pol = { 0 };
829 uint32_t seq = DOM_SEQUENCE_NONE;
831 NTSTATUS status, result;
832 struct dcerpc_binding_handle *b = NULL;
834 DEBUG(3,("samr: sequence number\n"));
837 *pseq = DOM_SEQUENCE_NONE;
840 tmp_ctx = talloc_stackframe();
841 if (tmp_ctx == NULL) {
842 return NT_STATUS_NO_MEMORY;
845 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
846 if (!NT_STATUS_IS_OK(status)) {
850 b = samr_pipe->binding_handle;
852 status = rpc_sequence_number(tmp_ctx,
857 if (!NT_STATUS_IS_OK(status)) {
865 if (b && is_valid_policy_hnd(&dom_pol)) {
866 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
869 TALLOC_FREE(tmp_ctx);
873 /* the rpc backend methods are exposed via this structure */
874 struct winbindd_methods builtin_passdb_methods = {
877 .query_user_list = builtin_query_user_list,
878 .enum_dom_groups = builtin_enum_dom_groups,
879 .enum_local_groups = sam_enum_local_groups,
880 .name_to_sid = sam_name_to_sid,
881 .sid_to_name = sam_sid_to_name,
882 .rids_to_names = sam_rids_to_names,
883 .lookup_useraliases = sam_lookup_useraliases,
884 .lookup_groupmem = sam_lookup_groupmem,
885 .sequence_number = sam_sequence_number,
886 .lockout_policy = sam_lockout_policy,
887 .password_policy = sam_password_policy,
888 .trusted_domains = builtin_trusted_domains
891 /* the rpc backend methods are exposed via this structure */
892 struct winbindd_methods sam_passdb_methods = {
895 .query_user_list = sam_query_user_list,
896 .enum_dom_groups = sam_enum_dom_groups,
897 .enum_local_groups = sam_enum_local_groups,
898 .name_to_sid = sam_name_to_sid,
899 .sid_to_name = sam_sid_to_name,
900 .rids_to_names = sam_rids_to_names,
901 .lookup_useraliases = sam_lookup_useraliases,
902 .lookup_groupmem = sam_lookup_groupmem,
903 .sequence_number = sam_sequence_number,
904 .lockout_policy = sam_lockout_policy,
905 .password_policy = sam_password_policy,
906 .trusted_domains = sam_trusted_domains