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;
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"));
124 ZERO_STRUCT(dom_pol);
130 tmp_ctx = talloc_stackframe();
131 if (tmp_ctx == NULL) {
132 return NT_STATUS_NO_MEMORY;
135 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
136 if (!NT_STATUS_IS_OK(status)) {
140 b = samr_pipe->binding_handle;
142 status = rpc_enum_dom_groups(tmp_ctx,
147 if (!NT_STATUS_IS_OK(status)) {
152 *pnum_info = num_info;
156 *pinfo = talloc_move(mem_ctx, &info);
160 if (b && is_valid_policy_hnd(&dom_pol)) {
161 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
163 TALLOC_FREE(tmp_ctx);
167 /* Query display info for a domain */
168 static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
172 struct rpc_pipe_client *samr_pipe = NULL;
173 struct policy_handle dom_pol;
176 NTSTATUS status, result;
177 struct dcerpc_binding_handle *b = NULL;
179 DEBUG(3,("samr_query_user_list\n"));
181 ZERO_STRUCT(dom_pol);
185 tmp_ctx = talloc_stackframe();
186 if (tmp_ctx == NULL) {
187 return NT_STATUS_NO_MEMORY;
190 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
191 if (!NT_STATUS_IS_OK(status)) {
195 b = samr_pipe->binding_handle;
197 status = rpc_query_user_list(tmp_ctx,
202 if (!NT_STATUS_IS_OK(status)) {
207 *prids = talloc_move(mem_ctx, &rids);
211 if (b && is_valid_policy_hnd(&dom_pol)) {
212 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
215 TALLOC_FREE(tmp_ctx);
219 /* get a list of trusted domains - builtin domain */
220 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
222 struct netr_DomainTrustList *ptrust_list)
224 struct rpc_pipe_client *lsa_pipe;
225 struct policy_handle lsa_policy;
226 struct netr_DomainTrust *trusts = NULL;
227 uint32_t num_trusts = 0;
229 NTSTATUS status, result;
230 struct dcerpc_binding_handle *b = NULL;
232 DEBUG(3,("samr: trusted domains\n"));
234 ZERO_STRUCT(lsa_policy);
237 ZERO_STRUCTP(ptrust_list);
240 tmp_ctx = talloc_stackframe();
241 if (tmp_ctx == NULL) {
242 return NT_STATUS_NO_MEMORY;
245 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
246 if (!NT_STATUS_IS_OK(status)) {
250 b = lsa_pipe->binding_handle;
252 status = rpc_trusted_domains(tmp_ctx,
257 if (!NT_STATUS_IS_OK(status)) {
262 ptrust_list->count = num_trusts;
263 ptrust_list->array = talloc_move(mem_ctx, &trusts);
267 if (b && is_valid_policy_hnd(&lsa_policy)) {
268 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
271 TALLOC_FREE(tmp_ctx);
275 /* Lookup group membership given a rid. */
276 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
278 const struct dom_sid *group_sid,
279 enum lsa_SidType type,
280 uint32_t *pnum_names,
281 struct dom_sid **psid_mem,
283 uint32_t **pname_types)
285 struct rpc_pipe_client *samr_pipe;
286 struct policy_handle dom_pol;
288 uint32_t num_names = 0;
289 struct dom_sid *sid_mem = NULL;
291 uint32_t *name_types = NULL;
294 NTSTATUS status, result;
295 struct dcerpc_binding_handle *b = NULL;
297 DEBUG(3,("sam_lookup_groupmem\n"));
299 ZERO_STRUCT(dom_pol);
302 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
303 /* There's no groups, only aliases in BUILTIN */
304 return NT_STATUS_NO_SUCH_GROUP;
311 tmp_ctx = talloc_stackframe();
312 if (tmp_ctx == NULL) {
313 return NT_STATUS_NO_MEMORY;
316 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
317 if (!NT_STATUS_IS_OK(status)) {
321 b = samr_pipe->binding_handle;
323 status = rpc_lookup_groupmem(tmp_ctx,
336 *pnum_names = num_names;
340 *pnames = talloc_move(mem_ctx, &names);
344 *pname_types = talloc_move(mem_ctx, &name_types);
348 *psid_mem = talloc_move(mem_ctx, &sid_mem);
352 if (b && is_valid_policy_hnd(&dom_pol)) {
353 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
356 TALLOC_FREE(tmp_ctx);
360 /*********************************************************************
361 BUILTIN specific functions.
362 *********************************************************************/
364 /* List all domain groups */
365 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
367 uint32_t *num_entries,
368 struct wb_acct_info **info)
370 /* BUILTIN doesn't have domain groups */
376 /* Query display info for a domain */
377 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
381 /* We don't have users */
386 /* get a list of trusted domains - builtin domain */
387 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
389 struct netr_DomainTrustList *trusts)
391 ZERO_STRUCTP(trusts);
395 /*********************************************************************
397 *********************************************************************/
399 /* List all local groups (aliases) */
400 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
403 struct wb_acct_info **pinfo)
405 struct rpc_pipe_client *samr_pipe;
406 struct policy_handle dom_pol;
407 struct wb_acct_info *info = NULL;
408 uint32_t num_info = 0;
410 NTSTATUS status, result;
411 struct dcerpc_binding_handle *b = NULL;
413 DEBUG(3,("samr: enum local groups\n"));
415 ZERO_STRUCT(dom_pol);
421 tmp_ctx = talloc_stackframe();
422 if (tmp_ctx == NULL) {
423 return NT_STATUS_NO_MEMORY;
426 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
427 if (!NT_STATUS_IS_OK(status)) {
431 b = samr_pipe->binding_handle;
433 status = rpc_enum_local_groups(mem_ctx,
438 if (!NT_STATUS_IS_OK(status)) {
443 *pnum_info = num_info;
447 *pinfo = talloc_move(mem_ctx, &info);
451 if (b && is_valid_policy_hnd(&dom_pol)) {
452 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
455 TALLOC_FREE(tmp_ctx);
459 /* convert a single name to a sid in a domain */
460 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
462 const char *domain_name,
465 struct dom_sid *psid,
466 enum lsa_SidType *ptype)
468 struct rpc_pipe_client *lsa_pipe;
469 struct policy_handle lsa_policy;
471 enum lsa_SidType type;
473 NTSTATUS status, result;
474 struct dcerpc_binding_handle *b = NULL;
476 DEBUG(3,("sam_name_to_sid\n"));
478 ZERO_STRUCT(lsa_policy);
480 tmp_ctx = talloc_stackframe();
481 if (tmp_ctx == NULL) {
482 return NT_STATUS_NO_MEMORY;
485 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
486 if (!NT_STATUS_IS_OK(status)) {
490 b = lsa_pipe->binding_handle;
492 status = rpc_name_to_sid(tmp_ctx,
500 if (!NT_STATUS_IS_OK(status)) {
505 sid_copy(psid, &sid);
512 if (b && is_valid_policy_hnd(&lsa_policy)) {
513 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
516 TALLOC_FREE(tmp_ctx);
520 /* convert a domain SID to a user or group name */
521 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
523 const struct dom_sid *sid,
526 enum lsa_SidType *ptype)
528 struct rpc_pipe_client *lsa_pipe;
529 struct policy_handle lsa_policy;
530 char *domain_name = NULL;
532 enum lsa_SidType type;
534 NTSTATUS status, result;
535 struct dcerpc_binding_handle *b = NULL;
537 DEBUG(3,("sam_sid_to_name\n"));
539 ZERO_STRUCT(lsa_policy);
542 if (!sid_check_is_in_builtin(sid) &&
543 !sid_check_is_builtin(sid) &&
544 !sid_check_is_in_our_sam(sid) &&
545 !sid_check_is_our_sam(sid) &&
546 !sid_check_is_in_unix_users(sid) &&
547 !sid_check_is_unix_users(sid) &&
548 !sid_check_is_in_unix_groups(sid) &&
549 !sid_check_is_unix_groups(sid) &&
550 !sid_check_is_in_wellknown_domain(sid)) {
551 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
552 "lookup SID %s\n", sid_string_dbg(sid)));
553 return NT_STATUS_NONE_MAPPED;
556 tmp_ctx = talloc_stackframe();
557 if (tmp_ctx == NULL) {
558 return NT_STATUS_NO_MEMORY;
561 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
562 if (!NT_STATUS_IS_OK(status)) {
566 b = lsa_pipe->binding_handle;
568 status = rpc_sid_to_name(tmp_ctx,
582 *pname = talloc_move(mem_ctx, &name);
586 *pdomain_name = talloc_move(mem_ctx, &domain_name);
590 if (b && is_valid_policy_hnd(&lsa_policy)) {
591 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
594 TALLOC_FREE(tmp_ctx);
598 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
600 const struct dom_sid *domain_sid,
605 enum lsa_SidType **ptypes)
607 struct rpc_pipe_client *lsa_pipe;
608 struct policy_handle lsa_policy;
609 enum lsa_SidType *types = NULL;
610 char *domain_name = NULL;
613 NTSTATUS status, result;
614 struct dcerpc_binding_handle *b = NULL;
616 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
618 ZERO_STRUCT(lsa_policy);
621 if (!sid_check_is_builtin(domain_sid) &&
622 !sid_check_is_our_sam(domain_sid) &&
623 !sid_check_is_unix_users(domain_sid) &&
624 !sid_check_is_unix_groups(domain_sid) &&
625 !sid_check_is_in_wellknown_domain(domain_sid)) {
626 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
627 "lookup SID %s\n", sid_string_dbg(domain_sid)));
628 return NT_STATUS_NONE_MAPPED;
631 tmp_ctx = talloc_stackframe();
632 if (tmp_ctx == NULL) {
633 return NT_STATUS_NO_MEMORY;
636 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
637 if (!NT_STATUS_IS_OK(status)) {
641 b = lsa_pipe->binding_handle;
643 status = rpc_rids_to_names(tmp_ctx,
653 if (!NT_STATUS_IS_OK(status)) {
658 *pdomain_name = talloc_move(mem_ctx, &domain_name);
662 *ptypes = talloc_move(mem_ctx, &types);
666 *pnames = talloc_move(mem_ctx, &names);
670 if (b && is_valid_policy_hnd(&lsa_policy)) {
671 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
674 TALLOC_FREE(tmp_ctx);
678 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
680 struct samr_DomInfo12 *lockout_policy)
682 struct rpc_pipe_client *samr_pipe;
683 struct policy_handle dom_pol;
684 union samr_DomainInfo *info = NULL;
686 NTSTATUS status, result;
687 struct dcerpc_binding_handle *b = NULL;
689 DEBUG(3,("sam_lockout_policy\n"));
691 ZERO_STRUCT(dom_pol);
693 tmp_ctx = talloc_stackframe();
694 if (tmp_ctx == NULL) {
695 return NT_STATUS_NO_MEMORY;
698 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
699 if (!NT_STATUS_IS_OK(status)) {
703 b = samr_pipe->binding_handle;
705 status = dcerpc_samr_QueryDomainInfo(b,
708 DomainLockoutInformation,
711 if (!NT_STATUS_IS_OK(status)) {
714 if (!NT_STATUS_IS_OK(result)) {
719 *lockout_policy = info->info12;
722 if (b && is_valid_policy_hnd(&dom_pol)) {
723 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
726 TALLOC_FREE(tmp_ctx);
730 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
732 struct samr_DomInfo1 *passwd_policy)
734 struct rpc_pipe_client *samr_pipe;
735 struct policy_handle dom_pol;
736 union samr_DomainInfo *info = NULL;
738 NTSTATUS status, result;
739 struct dcerpc_binding_handle *b = NULL;
741 DEBUG(3,("sam_password_policy\n"));
743 ZERO_STRUCT(dom_pol);
745 tmp_ctx = talloc_stackframe();
746 if (tmp_ctx == NULL) {
747 return NT_STATUS_NO_MEMORY;
750 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
751 if (!NT_STATUS_IS_OK(status)) {
755 b = samr_pipe->binding_handle;
757 status = dcerpc_samr_QueryDomainInfo(b,
760 DomainPasswordInformation,
763 if (!NT_STATUS_IS_OK(status)) {
766 if (!NT_STATUS_IS_OK(result)) {
771 *passwd_policy = info->info1;
774 if (b && is_valid_policy_hnd(&dom_pol)) {
775 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
778 TALLOC_FREE(tmp_ctx);
782 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
785 const struct dom_sid *sids,
786 uint32_t *pnum_aliases,
787 uint32_t **palias_rids)
789 struct rpc_pipe_client *samr_pipe;
790 struct policy_handle dom_pol;
791 uint32_t num_aliases = 0;
792 uint32_t *alias_rids = NULL;
794 NTSTATUS status, result;
795 struct dcerpc_binding_handle *b = NULL;
797 DEBUG(3,("sam_lookup_useraliases\n"));
799 ZERO_STRUCT(dom_pol);
805 tmp_ctx = talloc_stackframe();
806 if (tmp_ctx == NULL) {
807 return NT_STATUS_NO_MEMORY;
810 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
811 if (!NT_STATUS_IS_OK(status)) {
815 b = samr_pipe->binding_handle;
817 status = rpc_lookup_useraliases(tmp_ctx,
824 if (!NT_STATUS_IS_OK(status)) {
829 *pnum_aliases = num_aliases;
833 *palias_rids = talloc_move(mem_ctx, &alias_rids);
837 if (b && is_valid_policy_hnd(&dom_pol)) {
838 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
841 TALLOC_FREE(tmp_ctx);
845 /* find the sequence number for a domain */
846 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
849 struct rpc_pipe_client *samr_pipe;
850 struct policy_handle dom_pol;
851 uint32_t seq = DOM_SEQUENCE_NONE;
853 NTSTATUS status, result;
854 struct dcerpc_binding_handle *b = NULL;
856 DEBUG(3,("samr: sequence number\n"));
858 ZERO_STRUCT(dom_pol);
861 *pseq = DOM_SEQUENCE_NONE;
864 tmp_ctx = talloc_stackframe();
865 if (tmp_ctx == NULL) {
866 return NT_STATUS_NO_MEMORY;
869 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
870 if (!NT_STATUS_IS_OK(status)) {
874 b = samr_pipe->binding_handle;
876 status = rpc_sequence_number(tmp_ctx,
881 if (!NT_STATUS_IS_OK(status)) {
889 if (b && is_valid_policy_hnd(&dom_pol)) {
890 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
893 TALLOC_FREE(tmp_ctx);
897 /* the rpc backend methods are exposed via this structure */
898 struct winbindd_methods builtin_passdb_methods = {
901 .query_user_list = builtin_query_user_list,
902 .enum_dom_groups = builtin_enum_dom_groups,
903 .enum_local_groups = sam_enum_local_groups,
904 .name_to_sid = sam_name_to_sid,
905 .sid_to_name = sam_sid_to_name,
906 .rids_to_names = sam_rids_to_names,
907 .lookup_useraliases = sam_lookup_useraliases,
908 .lookup_groupmem = sam_lookup_groupmem,
909 .sequence_number = sam_sequence_number,
910 .lockout_policy = sam_lockout_policy,
911 .password_policy = sam_password_policy,
912 .trusted_domains = builtin_trusted_domains
915 /* the rpc backend methods are exposed via this structure */
916 struct winbindd_methods sam_passdb_methods = {
919 .query_user_list = sam_query_user_list,
920 .enum_dom_groups = sam_enum_dom_groups,
921 .enum_local_groups = sam_enum_local_groups,
922 .name_to_sid = sam_name_to_sid,
923 .sid_to_name = sam_sid_to_name,
924 .rids_to_names = sam_rids_to_names,
925 .lookup_useraliases = sam_lookup_useraliases,
926 .lookup_groupmem = sam_lookup_groupmem,
927 .sequence_number = sam_sequence_number,
928 .lockout_policy = sam_lockout_policy,
929 .password_policy = sam_password_policy,
930 .trusted_domains = sam_trusted_domains