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"
40 #include "source3/lib/global_contexts.h"
43 #define DBGC_CLASS DBGC_WINBIND
46 * The other end of this won't go away easily, so we can trust it
48 * It is either a long-lived process with the same lifetime as
49 * winbindd or a part of this process
51 struct winbind_internal_pipes
{
52 struct tevent_timer
*shutdown_timer
;
53 struct rpc_pipe_client
*samr_pipe
;
54 struct policy_handle samr_domain_hnd
;
55 struct rpc_pipe_client
*lsa_pipe
;
56 struct policy_handle lsa_hnd
;
60 NTSTATUS
open_internal_samr_conn(TALLOC_CTX
*mem_ctx
,
61 struct winbindd_domain
*domain
,
62 struct rpc_pipe_client
**samr_pipe
,
63 struct policy_handle
*samr_domain_hnd
)
65 NTSTATUS status
, result
;
66 struct policy_handle samr_connect_hnd
;
67 struct dcerpc_binding_handle
*b
;
69 status
= wb_open_internal_pipe(mem_ctx
, &ndr_table_samr
, samr_pipe
);
70 if (!NT_STATUS_IS_OK(status
)) {
71 DBG_ERR("Could not connect to %s pipe: %s\n",
72 ndr_table_samr
.name
, nt_errstr(status
));
76 b
= (*samr_pipe
)->binding_handle
;
78 status
= dcerpc_samr_Connect2(b
, mem_ctx
,
79 (*samr_pipe
)->desthost
,
80 SEC_FLAG_MAXIMUM_ALLOWED
,
83 if (!NT_STATUS_IS_OK(status
)) {
86 if (!NT_STATUS_IS_OK(result
)) {
90 status
= dcerpc_samr_OpenDomain(b
, mem_ctx
,
92 SEC_FLAG_MAXIMUM_ALLOWED
,
96 if (!NT_STATUS_IS_OK(status
)) {
103 NTSTATUS
open_internal_lsa_conn(TALLOC_CTX
*mem_ctx
,
104 struct rpc_pipe_client
**lsa_pipe
,
105 struct policy_handle
*lsa_hnd
)
109 status
= wb_open_internal_pipe(mem_ctx
, &ndr_table_lsarpc
, lsa_pipe
);
110 if (!NT_STATUS_IS_OK(status
)) {
111 DBG_ERR("Could not connect to %s pipe: %s\n",
112 ndr_table_lsarpc
.name
, nt_errstr(status
));
116 status
= rpccli_lsa_open_policy((*lsa_pipe
),
119 SEC_FLAG_MAXIMUM_ALLOWED
,
125 static void cached_internal_pipe_close(
126 struct tevent_context
*ev
,
127 struct tevent_timer
*te
,
128 struct timeval current_time
,
131 struct winbindd_domain
*domain
= talloc_get_type_abort(
132 private_data
, struct winbindd_domain
);
134 * Freeing samr_pipes closes the cached pipes.
136 * We can do a hard close because at the time of this commit
137 * we only use synchronous calls to external pipes. So we can't
138 * have any outstanding requests. Also, we don't set
139 * dcerpc_binding_handle_set_sync_ev in winbind, so we don't
140 * get nested event loops. Once we start to get async in
141 * winbind children, we need to check for outstanding calls
143 TALLOC_FREE(domain
->backend_data
.samr_pipes
);
146 static NTSTATUS
open_cached_internal_pipe_conn(
147 struct winbindd_domain
*domain
,
148 struct rpc_pipe_client
**samr_pipe
,
149 struct policy_handle
*samr_domain_hnd
,
150 struct rpc_pipe_client
**lsa_pipe
,
151 struct policy_handle
*lsa_hnd
)
153 struct winbind_internal_pipes
*internal_pipes
=
154 domain
->backend_data
.samr_pipes
;
156 if (internal_pipes
== NULL
) {
157 TALLOC_CTX
*frame
= talloc_stackframe();
160 internal_pipes
= talloc_zero(frame
,
161 struct winbind_internal_pipes
);
163 status
= open_internal_samr_conn(
166 &internal_pipes
->samr_pipe
,
167 &internal_pipes
->samr_domain_hnd
);
168 if (!NT_STATUS_IS_OK(status
)) {
173 status
= open_internal_lsa_conn(internal_pipes
,
174 &internal_pipes
->lsa_pipe
,
175 &internal_pipes
->lsa_hnd
);
177 if (!NT_STATUS_IS_OK(status
)) {
182 internal_pipes
->shutdown_timer
= tevent_add_timer(
183 global_event_context(),
185 timeval_current_ofs(5, 0),
186 cached_internal_pipe_close
,
188 if (internal_pipes
->shutdown_timer
== NULL
) {
190 return NT_STATUS_NO_MEMORY
;
193 domain
->backend_data
.samr_pipes
=
194 talloc_steal(domain
, internal_pipes
);
199 if (samr_domain_hnd
) {
200 *samr_domain_hnd
= internal_pipes
->samr_domain_hnd
;
204 *samr_pipe
= internal_pipes
->samr_pipe
;
208 *lsa_hnd
= internal_pipes
->lsa_hnd
;
212 *lsa_pipe
= internal_pipes
->lsa_pipe
;
216 internal_pipes
->shutdown_timer
,
217 timeval_current_ofs(5, 0));
222 static bool reset_connection_on_error(struct winbindd_domain
*domain
,
223 struct rpc_pipe_client
*p
,
226 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
228 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_TIMEOUT
) ||
229 NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
))
231 TALLOC_FREE(domain
->backend_data
.samr_pipes
);
235 if (!dcerpc_binding_handle_is_connected(b
)) {
236 TALLOC_FREE(domain
->backend_data
.samr_pipes
);
243 /*********************************************************************
244 SAM specific functions.
245 *********************************************************************/
247 /* List all domain groups */
248 static NTSTATUS
sam_enum_dom_groups(struct winbindd_domain
*domain
,
251 struct wb_acct_info
**pinfo
)
253 struct rpc_pipe_client
*samr_pipe
;
254 struct policy_handle dom_pol
= { 0 };
255 struct wb_acct_info
*info
= NULL
;
256 uint32_t num_info
= 0;
257 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
261 DEBUG(3,("sam_enum_dom_groups\n"));
268 status
= open_cached_internal_pipe_conn(domain
,
273 if (!NT_STATUS_IS_OK(status
)) {
274 TALLOC_FREE(tmp_ctx
);
278 status
= rpc_enum_dom_groups(tmp_ctx
,
284 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
289 if (!NT_STATUS_IS_OK(status
)) {
290 TALLOC_FREE(tmp_ctx
);
295 *pnum_info
= num_info
;
299 *pinfo
= talloc_move(mem_ctx
, &info
);
302 TALLOC_FREE(tmp_ctx
);
306 /* Query display info for a domain */
307 static NTSTATUS
sam_query_user_list(struct winbindd_domain
*domain
,
311 struct rpc_pipe_client
*samr_pipe
= NULL
;
312 struct policy_handle dom_pol
= { 0 };
313 uint32_t *rids
= NULL
;
314 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
318 DEBUG(3,("samr_query_user_list\n"));
321 status
= open_cached_internal_pipe_conn(domain
,
326 if (!NT_STATUS_IS_OK(status
)) {
330 status
= rpc_query_user_list(tmp_ctx
,
335 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
340 if (!NT_STATUS_IS_OK(status
)) {
345 *prids
= talloc_move(mem_ctx
, &rids
);
350 TALLOC_FREE(tmp_ctx
);
354 /* get a list of trusted domains - builtin domain */
355 static NTSTATUS
sam_trusted_domains(struct winbindd_domain
*domain
,
357 struct netr_DomainTrustList
*ptrust_list
)
359 struct rpc_pipe_client
*lsa_pipe
;
360 struct policy_handle lsa_policy
= { 0 };
361 struct netr_DomainTrust
*trusts
= NULL
;
362 uint32_t num_trusts
= 0;
363 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
367 DEBUG(3,("samr: trusted domains\n"));
370 ZERO_STRUCTP(ptrust_list
);
374 status
= open_cached_internal_pipe_conn(domain
,
379 if (!NT_STATUS_IS_OK(status
)) {
383 status
= rpc_trusted_domains(tmp_ctx
,
389 if (!retry
&& reset_connection_on_error(domain
, lsa_pipe
, status
)) {
394 if (!NT_STATUS_IS_OK(status
)) {
399 ptrust_list
->count
= num_trusts
;
400 ptrust_list
->array
= talloc_move(mem_ctx
, &trusts
);
404 TALLOC_FREE(tmp_ctx
);
408 /* Lookup group membership given a rid. */
409 static NTSTATUS
sam_lookup_groupmem(struct winbindd_domain
*domain
,
411 const struct dom_sid
*group_sid
,
412 enum lsa_SidType type
,
413 uint32_t *pnum_names
,
414 struct dom_sid
**psid_mem
,
416 uint32_t **pname_types
)
418 struct rpc_pipe_client
*samr_pipe
;
419 struct policy_handle dom_pol
= { 0 };
421 uint32_t num_names
= 0;
422 struct dom_sid
*sid_mem
= NULL
;
424 uint32_t *name_types
= NULL
;
426 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
430 DEBUG(3,("sam_lookup_groupmem\n"));
433 if (sid_check_is_in_builtin(group_sid
) && (type
!= SID_NAME_ALIAS
)) {
434 /* There's no groups, only aliases in BUILTIN */
435 status
= NT_STATUS_NO_SUCH_GROUP
;
444 status
= open_cached_internal_pipe_conn(domain
,
449 if (!NT_STATUS_IS_OK(status
)) {
453 status
= rpc_lookup_groupmem(tmp_ctx
,
465 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
471 *pnum_names
= num_names
;
475 *pnames
= talloc_move(mem_ctx
, &names
);
479 *pname_types
= talloc_move(mem_ctx
, &name_types
);
483 *psid_mem
= talloc_move(mem_ctx
, &sid_mem
);
487 TALLOC_FREE(tmp_ctx
);
491 /* Lookup alias membership */
492 static NTSTATUS
sam_lookup_aliasmem(struct winbindd_domain
*domain
,
494 const struct dom_sid
*group_sid
,
495 enum lsa_SidType type
,
497 struct dom_sid
**psid_mem
)
499 struct rpc_pipe_client
*samr_pipe
;
500 struct policy_handle dom_pol
= {0};
502 uint32_t num_sids
= 0;
503 struct dom_sid
*sid_mem
= NULL
;
505 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
509 DBG_INFO("sam_lookup_aliasmem\n");
512 if (type
!= SID_NAME_ALIAS
) {
513 status
= NT_STATUS_NO_SUCH_ALIAS
;
522 status
= open_cached_internal_pipe_conn(domain
,
527 if (!NT_STATUS_IS_OK(status
)) {
531 status
= rpc_lookup_aliasmem(tmp_ctx
,
540 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
546 *pnum_sids
= num_sids
;
550 *psid_mem
= talloc_move(mem_ctx
, &sid_mem
);
554 TALLOC_FREE(tmp_ctx
);
558 /*********************************************************************
559 BUILTIN specific functions.
560 *********************************************************************/
562 /* List all domain groups */
563 static NTSTATUS
builtin_enum_dom_groups(struct winbindd_domain
*domain
,
565 uint32_t *num_entries
,
566 struct wb_acct_info
**info
)
568 /* BUILTIN doesn't have domain groups */
574 /* Query display info for a domain */
575 static NTSTATUS
builtin_query_user_list(struct winbindd_domain
*domain
,
579 /* We don't have users */
584 /* get a list of trusted domains - builtin domain */
585 static NTSTATUS
builtin_trusted_domains(struct winbindd_domain
*domain
,
587 struct netr_DomainTrustList
*trusts
)
589 ZERO_STRUCTP(trusts
);
593 /*********************************************************************
595 *********************************************************************/
597 /* List all local groups (aliases) */
598 static NTSTATUS
sam_enum_local_groups(struct winbindd_domain
*domain
,
601 struct wb_acct_info
**pinfo
)
603 struct rpc_pipe_client
*samr_pipe
;
604 struct policy_handle dom_pol
= { 0 };
605 struct wb_acct_info
*info
= NULL
;
606 uint32_t num_info
= 0;
607 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
611 DEBUG(3,("samr: enum local groups\n"));
618 status
= open_cached_internal_pipe_conn(domain
,
623 if (!NT_STATUS_IS_OK(status
)) {
627 status
= rpc_enum_local_groups(mem_ctx
,
633 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
638 if (!NT_STATUS_IS_OK(status
)) {
643 *pnum_info
= num_info
;
647 *pinfo
= talloc_move(mem_ctx
, &info
);
651 TALLOC_FREE(tmp_ctx
);
655 /* convert a single name to a sid in a domain */
656 static NTSTATUS
sam_name_to_sid(struct winbindd_domain
*domain
,
658 const char *domain_name
,
661 const char **pdom_name
,
662 struct dom_sid
*psid
,
663 enum lsa_SidType
*ptype
)
665 struct rpc_pipe_client
*samr_pipe
= NULL
;
666 struct dcerpc_binding_handle
*h
= NULL
;
667 struct policy_handle dom_pol
= { .handle_type
= 0, };
669 const char *dom_name
= domain_name
;
670 struct lsa_String lsa_name
= { .string
= name
};
671 struct samr_Ids rids
= { .count
= 0 };
672 struct samr_Ids types
= { .count
= 0 };
673 enum lsa_SidType type
;
674 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
675 NTSTATUS status
= NT_STATUS_NONE_MAPPED
;
680 DBG_NOTICE("%s\\%s\n", domain_name
, name
);
682 *ptype
= SID_NAME_UNKNOWN
;
684 if (strequal(domain_name
, unix_users_domain_name())) {
685 struct passwd
*pwd
= NULL
;
687 if (name
[0] == '\0') {
688 sid_copy(&sid
, &global_sid_Unix_Users
);
689 type
= SID_NAME_DOMAIN
;
693 pwd
= Get_Pwnam_alloc(tmp_ctx
, name
);
697 ok
= sid_compose(&sid
, &global_sid_Unix_Users
, pwd
->pw_uid
);
699 status
= NT_STATUS_INTERNAL_ERROR
;
702 type
= SID_NAME_USER
;
706 if (strequal(domain_name
, unix_groups_domain_name())) {
707 struct group
*grp
= NULL
;
709 if (name
[0] == '\0') {
710 sid_copy(&sid
, &global_sid_Unix_Groups
);
711 type
= SID_NAME_DOMAIN
;
715 grp
= getgrnam(name
);
719 ok
= sid_compose(&sid
, &global_sid_Unix_Groups
, grp
->gr_gid
);
721 status
= NT_STATUS_INTERNAL_ERROR
;
724 type
= SID_NAME_DOM_GRP
;
728 if (name
[0] == '\0') {
729 sid_copy(&sid
, &domain
->sid
);
730 type
= SID_NAME_DOMAIN
;
734 ok
= lookup_wellknown_name(tmp_ctx
, name
, &sid
, &dom_name
);
736 type
= SID_NAME_WKN_GRP
;
741 char *normalized
= NULL
;
742 NTSTATUS nstatus
= normalize_name_unmap(
743 tmp_ctx
, name
, &normalized
);
744 if (NT_STATUS_IS_OK(nstatus
) ||
745 NT_STATUS_EQUAL(nstatus
, NT_STATUS_FILE_RENAMED
)) {
746 lsa_name
.string
= normalized
;
751 status
= open_cached_internal_pipe_conn(
752 domain
, &samr_pipe
, &dom_pol
, NULL
, NULL
);
753 if (!NT_STATUS_IS_OK(status
)) {
756 h
= samr_pipe
->binding_handle
;
758 status
= dcerpc_samr_LookupNames(
759 h
, tmp_ctx
, &dom_pol
, 1, &lsa_name
, &rids
, &types
, &result
);
761 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
766 if (!NT_STATUS_IS_OK(status
)) {
767 DBG_DEBUG("dcerpc_samr_LookupNames returned %s\n",
771 if (!NT_STATUS_IS_OK(result
)) {
772 DBG_DEBUG("dcerpc_samr_LookupNames resulted in %s\n",
778 sid_compose(&sid
, &domain
->sid
, rids
.ids
[0]);
782 if (pdom_name
!= NULL
) {
783 *pdom_name
= talloc_strdup(mem_ctx
, dom_name
);
784 if (*pdom_name
== NULL
) {
785 status
= NT_STATUS_NO_MEMORY
;
791 sid_copy(psid
, &sid
);
797 status
= NT_STATUS_OK
;
799 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
) ||
800 NT_STATUS_EQUAL(status
, NT_STATUS_SOME_NOT_MAPPED
))
802 status
= NT_STATUS_OK
;
804 TALLOC_FREE(tmp_ctx
);
808 /* convert a domain SID to a user or group name */
809 static NTSTATUS
sam_sid_to_name(struct winbindd_domain
*domain
,
811 const struct dom_sid
*sid
,
814 enum lsa_SidType
*ptype
)
816 struct rpc_pipe_client
*samr_pipe
= NULL
;
817 struct dcerpc_binding_handle
*h
= NULL
;
818 struct policy_handle dom_pol
= { .handle_type
= 0, };
819 const char *domain_name
= "";
820 const char *name
= "";
821 enum lsa_SidType type
= SID_NAME_USE_NONE
;
822 struct lsa_Strings names
= { .count
= 0, };
823 struct samr_Ids types
= { .count
= 0 };
824 struct dom_sid domain_sid
;
826 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
827 NTSTATUS status
= NT_STATUS_NONE_MAPPED
;
832 DEBUG(3,("sam_sid_to_name\n"));
834 if (sid_check_is_unix_users(sid
)) {
835 domain_name
= unix_users_domain_name();
836 type
= SID_NAME_DOMAIN
;
839 if (sid_check_is_in_unix_users(sid
)) {
840 struct passwd
*pwd
= NULL
;
842 ok
= sid_peek_rid(sid
, &rid
);
851 domain_name
= unix_users_domain_name();
852 name
= talloc_strdup(tmp_ctx
, pwd
->pw_name
);
854 status
= NT_STATUS_NO_MEMORY
;
857 type
= SID_NAME_USER
;
861 if (sid_check_is_unix_groups(sid
)) {
862 domain_name
= unix_groups_domain_name();
863 type
= SID_NAME_DOMAIN
;
866 if (sid_check_is_in_unix_groups(sid
)) {
867 struct group
*grp
= NULL
;
869 ok
= sid_peek_rid(sid
, &rid
);
878 domain_name
= unix_groups_domain_name();
879 name
= talloc_strdup(tmp_ctx
, grp
->gr_name
);
881 status
= NT_STATUS_NO_MEMORY
;
884 type
= SID_NAME_DOM_GRP
;
888 ok
= lookup_wellknown_sid(tmp_ctx
, sid
, &domain_name
, &name
);
890 type
= SID_NAME_WKN_GRP
;
894 if (dom_sid_equal(sid
, &domain
->sid
)) {
895 domain_name
= domain
->name
;
896 type
= SID_NAME_DOMAIN
;
900 sid_copy(&domain_sid
, sid
);
901 ok
= sid_split_rid(&domain_sid
, &rid
);
906 if (!dom_sid_equal(&domain_sid
, &domain
->sid
)) {
911 status
= open_cached_internal_pipe_conn(
912 domain
, &samr_pipe
, &dom_pol
, NULL
, NULL
);
913 if (!NT_STATUS_IS_OK(status
)) {
916 h
= samr_pipe
->binding_handle
;
918 status
= dcerpc_samr_LookupRids(
919 h
, tmp_ctx
, &dom_pol
, 1, &rid
, &names
, &types
, &result
);
921 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
926 if (!NT_STATUS_IS_OK(status
)) {
927 DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
931 if (!NT_STATUS_IS_OK(result
)) {
932 DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
938 domain_name
= domain
->name
;
939 name
= names
.names
[0].string
;
943 char *normalized
= NULL
;
944 NTSTATUS nstatus
= normalize_name_map(
945 tmp_ctx
, domain_name
, name
, &normalized
);
946 if (NT_STATUS_IS_OK(nstatus
) ||
947 NT_STATUS_EQUAL(nstatus
, NT_STATUS_FILE_RENAMED
)) {
958 *pname
= talloc_strdup(mem_ctx
, name
);
959 if (*pname
== NULL
) {
960 status
= NT_STATUS_NO_MEMORY
;
966 *pdomain_name
= talloc_strdup(mem_ctx
, domain_name
);
967 if (*pdomain_name
== NULL
) {
968 status
= NT_STATUS_NO_MEMORY
;
973 status
= NT_STATUS_OK
;
975 TALLOC_FREE(tmp_ctx
);
979 static NTSTATUS
sam_rids_to_names(struct winbindd_domain
*domain
,
981 const struct dom_sid
*domain_sid
,
986 enum lsa_SidType
**ptypes
)
988 struct rpc_pipe_client
*samr_pipe
= NULL
;
989 struct dcerpc_binding_handle
*h
= NULL
;
990 struct policy_handle dom_pol
= { .handle_type
= 0, };
991 enum lsa_SidType
*types
= NULL
;
993 const char *domain_name
= NULL
;
994 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
995 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
1000 DEBUG(3,("sam_rids_to_names for %s\n", domain
->name
));
1002 types
= talloc_array(tmp_ctx
, enum lsa_SidType
, num_rids
);
1003 if (types
== NULL
) {
1007 names
= talloc_array(tmp_ctx
, char *, num_rids
);
1008 if (names
== NULL
) {
1012 if (sid_check_is_unix_users(domain_sid
)) {
1013 domain_name
= unix_users_domain_name();
1014 domain_sid
= &global_sid_Unix_Users
;
1016 if (sid_check_is_unix_groups(domain_sid
)) {
1017 domain_name
= unix_groups_domain_name();
1018 domain_sid
= &global_sid_Unix_Groups
;
1021 /* Here we're only interested in the domain name being set */
1022 sid_check_is_wellknown_domain(domain_sid
, &domain_name
);
1024 if (domain_name
!= NULL
) {
1025 uint32_t num_mapped
= 0;
1028 * Do unix users/groups and wkn in a loop. There is no
1029 * getpwuids() call & friends anyway
1032 for (i
=0; i
<num_rids
; i
++) {
1036 sid_compose(&sid
, domain_sid
, rids
[i
]);
1038 types
[i
] = SID_NAME_UNKNOWN
;
1041 status
= sam_sid_to_name(
1048 if (NT_STATUS_IS_OK(status
)) {
1049 names
[i
] = talloc_move(names
, &name
);
1054 status
= NT_STATUS_NONE_MAPPED
;
1055 if (num_mapped
> 0) {
1056 status
= (num_mapped
== num_rids
) ?
1057 NT_STATUS_OK
: STATUS_SOME_UNMAPPED
;
1062 domain_name
= domain
->name
;
1065 status
= open_cached_internal_pipe_conn(
1066 domain
, &samr_pipe
, &dom_pol
, NULL
, NULL
);
1067 if (!NT_STATUS_IS_OK(status
)) {
1070 h
= samr_pipe
->binding_handle
;
1073 * Magic number 1000 comes from samr.idl
1076 for (i
= 0; i
< num_rids
; i
+= 1000) {
1077 uint32_t num_lookup_rids
= MIN(num_rids
- i
, 1000);
1078 struct lsa_Strings lsa_names
= {
1081 struct samr_Ids samr_types
= {
1086 status
= dcerpc_samr_LookupRids(h
,
1096 reset_connection_on_error(domain
, samr_pipe
, status
)) {
1101 if (!NT_STATUS_IS_OK(status
)) {
1102 DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
1106 if (!NT_STATUS_IS_OK(result
) &&
1107 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
1108 DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
1114 for (j
= 0; j
< num_lookup_rids
; j
++) {
1115 uint32_t dst
= i
+ j
;
1117 types
[dst
] = samr_types
.ids
[j
];
1118 names
[dst
] = talloc_move(
1120 discard_const_p(char *,
1121 &lsa_names
.names
[j
].string
));
1122 if (names
[dst
] != NULL
) {
1123 char *normalized
= NULL
;
1125 normalize_name_map(names
,
1129 if (NT_STATUS_IS_OK(nstatus
) ||
1130 NT_STATUS_EQUAL(nstatus
,
1131 NT_STATUS_FILE_RENAMED
)) {
1132 names
[dst
] = normalized
;
1137 TALLOC_FREE(samr_types
.ids
);
1138 TALLOC_FREE(lsa_names
.names
);
1143 *pdomain_name
= talloc_strdup(mem_ctx
, domain_name
);
1144 if (*pdomain_name
== NULL
) {
1145 status
= NT_STATUS_NO_MEMORY
;
1151 *ptypes
= talloc_move(mem_ctx
, &types
);
1155 *pnames
= talloc_move(mem_ctx
, &names
);
1159 TALLOC_FREE(tmp_ctx
);
1163 static NTSTATUS
sam_lockout_policy(struct winbindd_domain
*domain
,
1164 TALLOC_CTX
*mem_ctx
,
1165 struct samr_DomInfo12
*lockout_policy
)
1167 struct rpc_pipe_client
*samr_pipe
;
1168 struct policy_handle dom_pol
= { 0 };
1169 union samr_DomainInfo
*info
= NULL
;
1170 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1171 NTSTATUS status
, result
;
1172 struct dcerpc_binding_handle
*b
= NULL
;
1175 DEBUG(3,("sam_lockout_policy\n"));
1178 status
= open_cached_internal_pipe_conn(domain
,
1183 if (!NT_STATUS_IS_OK(status
)) {
1187 b
= samr_pipe
->binding_handle
;
1189 status
= dcerpc_samr_QueryDomainInfo(b
,
1192 DomainLockoutInformation
,
1196 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1201 if (!NT_STATUS_IS_OK(status
)) {
1204 if (!NT_STATUS_IS_OK(result
)) {
1209 *lockout_policy
= info
->info12
;
1212 TALLOC_FREE(tmp_ctx
);
1216 static NTSTATUS
sam_password_policy(struct winbindd_domain
*domain
,
1217 TALLOC_CTX
*mem_ctx
,
1218 struct samr_DomInfo1
*passwd_policy
)
1220 struct rpc_pipe_client
*samr_pipe
;
1221 struct policy_handle dom_pol
= { 0 };
1222 union samr_DomainInfo
*info
= NULL
;
1223 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1224 NTSTATUS status
, result
;
1225 struct dcerpc_binding_handle
*b
= NULL
;
1228 DEBUG(3,("sam_password_policy\n"));
1231 status
= open_cached_internal_pipe_conn(domain
,
1236 if (!NT_STATUS_IS_OK(status
)) {
1240 b
= samr_pipe
->binding_handle
;
1242 status
= dcerpc_samr_QueryDomainInfo(b
,
1245 DomainPasswordInformation
,
1249 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1254 if (!NT_STATUS_IS_OK(status
)) {
1257 if (!NT_STATUS_IS_OK(result
)) {
1262 *passwd_policy
= info
->info1
;
1265 TALLOC_FREE(tmp_ctx
);
1269 /* Lookup groups a user is a member of. */
1270 static NTSTATUS
sam_lookup_usergroups(struct winbindd_domain
*domain
,
1271 TALLOC_CTX
*mem_ctx
,
1272 const struct dom_sid
*user_sid
,
1273 uint32_t *pnum_groups
,
1274 struct dom_sid
**puser_grpsids
)
1276 struct rpc_pipe_client
*samr_pipe
;
1277 struct policy_handle dom_pol
;
1278 struct dom_sid
*user_grpsids
= NULL
;
1279 uint32_t num_groups
= 0;
1280 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1284 DEBUG(3,("sam_lookup_usergroups\n"));
1286 ZERO_STRUCT(dom_pol
);
1293 status
= open_cached_internal_pipe_conn(domain
,
1298 if (!NT_STATUS_IS_OK(status
)) {
1302 status
= rpc_lookup_usergroups(tmp_ctx
,
1310 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1315 if (!NT_STATUS_IS_OK(status
)) {
1320 *pnum_groups
= num_groups
;
1323 if (puser_grpsids
) {
1324 *puser_grpsids
= talloc_move(mem_ctx
, &user_grpsids
);
1329 TALLOC_FREE(tmp_ctx
);
1333 static NTSTATUS
sam_lookup_useraliases(struct winbindd_domain
*domain
,
1334 TALLOC_CTX
*mem_ctx
,
1336 const struct dom_sid
*sids
,
1337 uint32_t *pnum_aliases
,
1338 uint32_t **palias_rids
)
1340 struct rpc_pipe_client
*samr_pipe
;
1341 struct policy_handle dom_pol
= { 0 };
1342 uint32_t num_aliases
= 0;
1343 uint32_t *alias_rids
= NULL
;
1344 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1348 DEBUG(3,("sam_lookup_useraliases\n"));
1355 status
= open_cached_internal_pipe_conn(domain
,
1360 if (!NT_STATUS_IS_OK(status
)) {
1364 status
= rpc_lookup_useraliases(tmp_ctx
,
1372 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1377 if (!NT_STATUS_IS_OK(status
)) {
1382 *pnum_aliases
= num_aliases
;
1386 *palias_rids
= talloc_move(mem_ctx
, &alias_rids
);
1391 TALLOC_FREE(tmp_ctx
);
1395 /* the rpc backend methods are exposed via this structure */
1396 struct winbindd_methods builtin_passdb_methods
= {
1397 .consistent
= false,
1399 .query_user_list
= builtin_query_user_list
,
1400 .enum_dom_groups
= builtin_enum_dom_groups
,
1401 .enum_local_groups
= sam_enum_local_groups
,
1402 .name_to_sid
= sam_name_to_sid
,
1403 .sid_to_name
= sam_sid_to_name
,
1404 .rids_to_names
= sam_rids_to_names
,
1405 .lookup_usergroups
= sam_lookup_usergroups
,
1406 .lookup_useraliases
= sam_lookup_useraliases
,
1407 .lookup_groupmem
= sam_lookup_groupmem
,
1408 .lookup_aliasmem
= sam_lookup_aliasmem
,
1409 .lockout_policy
= sam_lockout_policy
,
1410 .password_policy
= sam_password_policy
,
1411 .trusted_domains
= builtin_trusted_domains
1414 /* the rpc backend methods are exposed via this structure */
1415 struct winbindd_methods sam_passdb_methods
= {
1416 .consistent
= false,
1418 .query_user_list
= sam_query_user_list
,
1419 .enum_dom_groups
= sam_enum_dom_groups
,
1420 .enum_local_groups
= sam_enum_local_groups
,
1421 .name_to_sid
= sam_name_to_sid
,
1422 .sid_to_name
= sam_sid_to_name
,
1423 .rids_to_names
= sam_rids_to_names
,
1424 .lookup_usergroups
= sam_lookup_usergroups
,
1425 .lookup_useraliases
= sam_lookup_useraliases
,
1426 .lookup_groupmem
= sam_lookup_groupmem
,
1427 .lookup_aliasmem
= sam_lookup_aliasmem
,
1428 .lockout_policy
= sam_lockout_policy
,
1429 .password_policy
= sam_password_policy
,
1430 .trusted_domains
= sam_trusted_domains