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,
171 struct wbint_userinfo **pinfo)
173 struct rpc_pipe_client *samr_pipe = NULL;
174 struct policy_handle dom_pol;
175 struct wbint_userinfo *info = NULL;
176 uint32_t num_info = 0;
178 NTSTATUS status, result;
179 struct dcerpc_binding_handle *b = NULL;
181 DEBUG(3,("samr_query_user_list\n"));
183 ZERO_STRUCT(dom_pol);
189 tmp_ctx = talloc_stackframe();
190 if (tmp_ctx == NULL) {
191 return NT_STATUS_NO_MEMORY;
194 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
195 if (!NT_STATUS_IS_OK(status)) {
199 b = samr_pipe->binding_handle;
201 status = rpc_query_user_list(tmp_ctx,
207 if (!NT_STATUS_IS_OK(status)) {
212 *pnum_info = num_info;
216 *pinfo = talloc_move(mem_ctx, &info);
220 if (b && is_valid_policy_hnd(&dom_pol)) {
221 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
224 TALLOC_FREE(tmp_ctx);
228 /* get a list of trusted domains - builtin domain */
229 static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
231 struct netr_DomainTrustList *ptrust_list)
233 struct rpc_pipe_client *lsa_pipe;
234 struct policy_handle lsa_policy;
235 struct netr_DomainTrust *trusts = NULL;
236 uint32_t num_trusts = 0;
238 NTSTATUS status, result;
239 struct dcerpc_binding_handle *b = NULL;
241 DEBUG(3,("samr: trusted domains\n"));
243 ZERO_STRUCT(lsa_policy);
246 ZERO_STRUCTP(ptrust_list);
249 tmp_ctx = talloc_stackframe();
250 if (tmp_ctx == NULL) {
251 return NT_STATUS_NO_MEMORY;
254 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
255 if (!NT_STATUS_IS_OK(status)) {
259 b = lsa_pipe->binding_handle;
261 status = rpc_trusted_domains(tmp_ctx,
266 if (!NT_STATUS_IS_OK(status)) {
271 ptrust_list->count = num_trusts;
272 ptrust_list->array = talloc_move(mem_ctx, &trusts);
276 if (b && is_valid_policy_hnd(&lsa_policy)) {
277 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
280 TALLOC_FREE(tmp_ctx);
284 /* Lookup group membership given a rid. */
285 static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
287 const struct dom_sid *group_sid,
288 enum lsa_SidType type,
289 uint32_t *pnum_names,
290 struct dom_sid **psid_mem,
292 uint32_t **pname_types)
294 struct rpc_pipe_client *samr_pipe;
295 struct policy_handle dom_pol;
297 uint32_t num_names = 0;
298 struct dom_sid *sid_mem = NULL;
300 uint32_t *name_types = NULL;
303 NTSTATUS status, result;
304 struct dcerpc_binding_handle *b = NULL;
306 DEBUG(3,("sam_lookup_groupmem\n"));
308 ZERO_STRUCT(dom_pol);
311 if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
312 /* There's no groups, only aliases in BUILTIN */
313 return NT_STATUS_NO_SUCH_GROUP;
320 tmp_ctx = talloc_stackframe();
321 if (tmp_ctx == NULL) {
322 return NT_STATUS_NO_MEMORY;
325 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
326 if (!NT_STATUS_IS_OK(status)) {
330 b = samr_pipe->binding_handle;
332 status = rpc_lookup_groupmem(tmp_ctx,
345 *pnum_names = num_names;
349 *pnames = talloc_move(mem_ctx, &names);
353 *pname_types = talloc_move(mem_ctx, &name_types);
357 *psid_mem = talloc_move(mem_ctx, &sid_mem);
361 if (b && is_valid_policy_hnd(&dom_pol)) {
362 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
365 TALLOC_FREE(tmp_ctx);
369 /*********************************************************************
370 BUILTIN specific functions.
371 *********************************************************************/
373 /* List all domain groups */
374 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
376 uint32_t *num_entries,
377 struct wb_acct_info **info)
379 /* BUILTIN doesn't have domain groups */
385 /* Query display info for a domain */
386 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
388 uint32_t *num_entries,
389 struct wbint_userinfo **info)
391 /* We don't have users */
397 /* get a list of trusted domains - builtin domain */
398 static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
400 struct netr_DomainTrustList *trusts)
402 ZERO_STRUCTP(trusts);
406 /*********************************************************************
408 *********************************************************************/
410 /* List all local groups (aliases) */
411 static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
414 struct wb_acct_info **pinfo)
416 struct rpc_pipe_client *samr_pipe;
417 struct policy_handle dom_pol;
418 struct wb_acct_info *info = NULL;
419 uint32_t num_info = 0;
421 NTSTATUS status, result;
422 struct dcerpc_binding_handle *b = NULL;
424 DEBUG(3,("samr: enum local groups\n"));
426 ZERO_STRUCT(dom_pol);
432 tmp_ctx = talloc_stackframe();
433 if (tmp_ctx == NULL) {
434 return NT_STATUS_NO_MEMORY;
437 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
438 if (!NT_STATUS_IS_OK(status)) {
442 b = samr_pipe->binding_handle;
444 status = rpc_enum_local_groups(mem_ctx,
449 if (!NT_STATUS_IS_OK(status)) {
454 *pnum_info = num_info;
458 *pinfo = talloc_move(mem_ctx, &info);
462 if (b && is_valid_policy_hnd(&dom_pol)) {
463 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
466 TALLOC_FREE(tmp_ctx);
470 /* convert a single name to a sid in a domain */
471 static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
473 const char *domain_name,
476 struct dom_sid *psid,
477 enum lsa_SidType *ptype)
479 struct rpc_pipe_client *lsa_pipe;
480 struct policy_handle lsa_policy;
482 enum lsa_SidType type;
484 NTSTATUS status, result;
485 struct dcerpc_binding_handle *b = NULL;
487 DEBUG(3,("sam_name_to_sid\n"));
489 ZERO_STRUCT(lsa_policy);
491 tmp_ctx = talloc_stackframe();
492 if (tmp_ctx == NULL) {
493 return NT_STATUS_NO_MEMORY;
496 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
497 if (!NT_STATUS_IS_OK(status)) {
501 b = lsa_pipe->binding_handle;
503 status = rpc_name_to_sid(tmp_ctx,
511 if (!NT_STATUS_IS_OK(status)) {
516 sid_copy(psid, &sid);
523 if (b && is_valid_policy_hnd(&lsa_policy)) {
524 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
527 TALLOC_FREE(tmp_ctx);
531 /* convert a domain SID to a user or group name */
532 static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
534 const struct dom_sid *sid,
537 enum lsa_SidType *ptype)
539 struct rpc_pipe_client *lsa_pipe;
540 struct policy_handle lsa_policy;
541 char *domain_name = NULL;
543 enum lsa_SidType type;
545 NTSTATUS status, result;
546 struct dcerpc_binding_handle *b = NULL;
548 DEBUG(3,("sam_sid_to_name\n"));
550 ZERO_STRUCT(lsa_policy);
553 if (!sid_check_is_in_builtin(sid) &&
554 !sid_check_is_builtin(sid) &&
555 !sid_check_is_in_our_sam(sid) &&
556 !sid_check_is_our_sam(sid) &&
557 !sid_check_is_in_unix_users(sid) &&
558 !sid_check_is_unix_users(sid) &&
559 !sid_check_is_in_unix_groups(sid) &&
560 !sid_check_is_unix_groups(sid) &&
561 !sid_check_is_in_wellknown_domain(sid)) {
562 DEBUG(0, ("sam_sid_to_name: possible deadlock - trying to "
563 "lookup SID %s\n", sid_string_dbg(sid)));
564 return NT_STATUS_NONE_MAPPED;
567 tmp_ctx = talloc_stackframe();
568 if (tmp_ctx == NULL) {
569 return NT_STATUS_NO_MEMORY;
572 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
573 if (!NT_STATUS_IS_OK(status)) {
577 b = lsa_pipe->binding_handle;
579 status = rpc_sid_to_name(tmp_ctx,
593 *pname = talloc_move(mem_ctx, &name);
597 *pdomain_name = talloc_move(mem_ctx, &domain_name);
601 if (b && is_valid_policy_hnd(&lsa_policy)) {
602 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
605 TALLOC_FREE(tmp_ctx);
609 static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
611 const struct dom_sid *domain_sid,
616 enum lsa_SidType **ptypes)
618 struct rpc_pipe_client *lsa_pipe;
619 struct policy_handle lsa_policy;
620 enum lsa_SidType *types = NULL;
621 char *domain_name = NULL;
624 NTSTATUS status, result;
625 struct dcerpc_binding_handle *b = NULL;
627 DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
629 ZERO_STRUCT(lsa_policy);
632 if (!sid_check_is_builtin(domain_sid) &&
633 !sid_check_is_our_sam(domain_sid) &&
634 !sid_check_is_unix_users(domain_sid) &&
635 !sid_check_is_unix_groups(domain_sid) &&
636 !sid_check_is_in_wellknown_domain(domain_sid)) {
637 DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
638 "lookup SID %s\n", sid_string_dbg(domain_sid)));
639 return NT_STATUS_NONE_MAPPED;
642 tmp_ctx = talloc_stackframe();
643 if (tmp_ctx == NULL) {
644 return NT_STATUS_NO_MEMORY;
647 status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
648 if (!NT_STATUS_IS_OK(status)) {
652 b = lsa_pipe->binding_handle;
654 status = rpc_rids_to_names(tmp_ctx,
664 if (!NT_STATUS_IS_OK(status)) {
669 *pdomain_name = talloc_move(mem_ctx, &domain_name);
673 *ptypes = talloc_move(mem_ctx, &types);
677 *pnames = talloc_move(mem_ctx, &names);
681 if (b && is_valid_policy_hnd(&lsa_policy)) {
682 dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
685 TALLOC_FREE(tmp_ctx);
689 static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
691 struct samr_DomInfo12 *lockout_policy)
693 struct rpc_pipe_client *samr_pipe;
694 struct policy_handle dom_pol;
695 union samr_DomainInfo *info = NULL;
697 NTSTATUS status, result;
698 struct dcerpc_binding_handle *b = NULL;
700 DEBUG(3,("sam_lockout_policy\n"));
702 ZERO_STRUCT(dom_pol);
704 tmp_ctx = talloc_stackframe();
705 if (tmp_ctx == NULL) {
706 return NT_STATUS_NO_MEMORY;
709 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
710 if (!NT_STATUS_IS_OK(status)) {
714 b = samr_pipe->binding_handle;
716 status = dcerpc_samr_QueryDomainInfo(b,
719 DomainLockoutInformation,
722 if (!NT_STATUS_IS_OK(status)) {
725 if (!NT_STATUS_IS_OK(result)) {
730 *lockout_policy = info->info12;
733 if (b && is_valid_policy_hnd(&dom_pol)) {
734 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
737 TALLOC_FREE(tmp_ctx);
741 static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
743 struct samr_DomInfo1 *passwd_policy)
745 struct rpc_pipe_client *samr_pipe;
746 struct policy_handle dom_pol;
747 union samr_DomainInfo *info = NULL;
749 NTSTATUS status, result;
750 struct dcerpc_binding_handle *b = NULL;
752 DEBUG(3,("sam_password_policy\n"));
754 ZERO_STRUCT(dom_pol);
756 tmp_ctx = talloc_stackframe();
757 if (tmp_ctx == NULL) {
758 return NT_STATUS_NO_MEMORY;
761 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
762 if (!NT_STATUS_IS_OK(status)) {
766 b = samr_pipe->binding_handle;
768 status = dcerpc_samr_QueryDomainInfo(b,
771 DomainPasswordInformation,
774 if (!NT_STATUS_IS_OK(status)) {
777 if (!NT_STATUS_IS_OK(result)) {
782 *passwd_policy = info->info1;
785 if (b && is_valid_policy_hnd(&dom_pol)) {
786 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
789 TALLOC_FREE(tmp_ctx);
793 /* Lookup groups a user is a member of. */
794 static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
796 const struct dom_sid *user_sid,
797 uint32_t *pnum_groups,
798 struct dom_sid **puser_grpsids)
800 struct rpc_pipe_client *samr_pipe;
801 struct policy_handle dom_pol;
802 struct dom_sid *user_grpsids = NULL;
803 uint32_t num_groups = 0;
805 NTSTATUS status, result;
806 struct dcerpc_binding_handle *b = NULL;
808 DEBUG(3,("sam_lookup_usergroups\n"));
810 ZERO_STRUCT(dom_pol);
816 tmp_ctx = talloc_stackframe();
817 if (tmp_ctx == NULL) {
818 return NT_STATUS_NO_MEMORY;
821 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
822 if (!NT_STATUS_IS_OK(status)) {
826 b = samr_pipe->binding_handle;
828 status = rpc_lookup_usergroups(tmp_ctx,
835 if (!NT_STATUS_IS_OK(status)) {
840 *pnum_groups = num_groups;
844 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
848 if (b && is_valid_policy_hnd(&dom_pol)) {
849 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
852 TALLOC_FREE(tmp_ctx);
856 static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
859 const struct dom_sid *sids,
860 uint32_t *pnum_aliases,
861 uint32_t **palias_rids)
863 struct rpc_pipe_client *samr_pipe;
864 struct policy_handle dom_pol;
865 uint32_t num_aliases = 0;
866 uint32_t *alias_rids = NULL;
868 NTSTATUS status, result;
869 struct dcerpc_binding_handle *b = NULL;
871 DEBUG(3,("sam_lookup_useraliases\n"));
873 ZERO_STRUCT(dom_pol);
879 tmp_ctx = talloc_stackframe();
880 if (tmp_ctx == NULL) {
881 return NT_STATUS_NO_MEMORY;
884 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
885 if (!NT_STATUS_IS_OK(status)) {
889 b = samr_pipe->binding_handle;
891 status = rpc_lookup_useraliases(tmp_ctx,
898 if (!NT_STATUS_IS_OK(status)) {
903 *pnum_aliases = num_aliases;
907 *palias_rids = talloc_move(mem_ctx, &alias_rids);
911 if (b && is_valid_policy_hnd(&dom_pol)) {
912 dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
915 TALLOC_FREE(tmp_ctx);
919 /* find the sequence number for a domain */
920 static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
923 struct rpc_pipe_client *samr_pipe;
924 struct policy_handle dom_pol;
925 uint32_t seq = DOM_SEQUENCE_NONE;
927 NTSTATUS status, result;
928 struct dcerpc_binding_handle *b = NULL;
930 DEBUG(3,("samr: sequence number\n"));
932 ZERO_STRUCT(dom_pol);
935 *pseq = DOM_SEQUENCE_NONE;
938 tmp_ctx = talloc_stackframe();
939 if (tmp_ctx == NULL) {
940 return NT_STATUS_NO_MEMORY;
943 status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
944 if (!NT_STATUS_IS_OK(status)) {
948 b = samr_pipe->binding_handle;
950 status = rpc_sequence_number(tmp_ctx,
955 if (!NT_STATUS_IS_OK(status)) {
963 if (b && is_valid_policy_hnd(&dom_pol)) {
964 dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
967 TALLOC_FREE(tmp_ctx);
971 /* the rpc backend methods are exposed via this structure */
972 struct winbindd_methods builtin_passdb_methods = {
975 .query_user_list = builtin_query_user_list,
976 .enum_dom_groups = builtin_enum_dom_groups,
977 .enum_local_groups = sam_enum_local_groups,
978 .name_to_sid = sam_name_to_sid,
979 .sid_to_name = sam_sid_to_name,
980 .rids_to_names = sam_rids_to_names,
981 .lookup_usergroups = sam_lookup_usergroups,
982 .lookup_useraliases = sam_lookup_useraliases,
983 .lookup_groupmem = sam_lookup_groupmem,
984 .sequence_number = sam_sequence_number,
985 .lockout_policy = sam_lockout_policy,
986 .password_policy = sam_password_policy,
987 .trusted_domains = builtin_trusted_domains
990 /* the rpc backend methods are exposed via this structure */
991 struct winbindd_methods sam_passdb_methods = {
994 .query_user_list = sam_query_user_list,
995 .enum_dom_groups = sam_enum_dom_groups,
996 .enum_local_groups = sam_enum_local_groups,
997 .name_to_sid = sam_name_to_sid,
998 .sid_to_name = sam_sid_to_name,
999 .rids_to_names = sam_rids_to_names,
1000 .lookup_usergroups = sam_lookup_usergroups,
1001 .lookup_useraliases = sam_lookup_useraliases,
1002 .lookup_groupmem = sam_lookup_groupmem,
1003 .sequence_number = sam_sequence_number,
1004 .lockout_policy = sam_lockout_policy,
1005 .password_policy = sam_password_policy,
1006 .trusted_domains = sam_trusted_domains