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 if (strequal(domain_name
, unix_users_domain_name())) {
683 struct passwd
*pwd
= NULL
;
685 if (name
[0] == '\0') {
686 sid_copy(&sid
, &global_sid_Unix_Users
);
687 type
= SID_NAME_DOMAIN
;
691 pwd
= Get_Pwnam_alloc(tmp_ctx
, name
);
695 ok
= sid_compose(&sid
, &global_sid_Unix_Users
, pwd
->pw_uid
);
697 status
= NT_STATUS_INTERNAL_ERROR
;
700 type
= SID_NAME_USER
;
704 if (strequal(domain_name
, unix_groups_domain_name())) {
705 struct group
*grp
= NULL
;
707 if (name
[0] == '\0') {
708 sid_copy(&sid
, &global_sid_Unix_Groups
);
709 type
= SID_NAME_DOMAIN
;
713 grp
= getgrnam(name
);
717 ok
= sid_compose(&sid
, &global_sid_Unix_Groups
, grp
->gr_gid
);
719 status
= NT_STATUS_INTERNAL_ERROR
;
722 type
= SID_NAME_DOM_GRP
;
726 if (name
[0] == '\0') {
727 sid_copy(&sid
, &domain
->sid
);
728 type
= SID_NAME_DOMAIN
;
732 ok
= lookup_wellknown_name(tmp_ctx
, name
, &sid
, &dom_name
);
734 type
= SID_NAME_WKN_GRP
;
739 char *normalized
= NULL
;
740 NTSTATUS nstatus
= normalize_name_unmap(
741 tmp_ctx
, name
, &normalized
);
742 if (NT_STATUS_IS_OK(nstatus
) ||
743 NT_STATUS_EQUAL(nstatus
, NT_STATUS_FILE_RENAMED
)) {
744 lsa_name
.string
= normalized
;
749 status
= open_cached_internal_pipe_conn(
750 domain
, &samr_pipe
, &dom_pol
, NULL
, NULL
);
751 if (!NT_STATUS_IS_OK(status
)) {
754 h
= samr_pipe
->binding_handle
;
756 status
= dcerpc_samr_LookupNames(
757 h
, tmp_ctx
, &dom_pol
, 1, &lsa_name
, &rids
, &types
, &result
);
759 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
764 if (!NT_STATUS_IS_OK(status
)) {
765 DBG_DEBUG("dcerpc_samr_LookupNames returned %s\n",
769 if (!NT_STATUS_IS_OK(result
)) {
770 DBG_DEBUG("dcerpc_samr_LookupNames resulted in %s\n",
776 sid_compose(&sid
, &domain
->sid
, rids
.ids
[0]);
780 if (pdom_name
!= NULL
) {
781 *pdom_name
= talloc_strdup(mem_ctx
, dom_name
);
782 if (*pdom_name
== NULL
) {
783 status
= NT_STATUS_NO_MEMORY
;
789 sid_copy(psid
, &sid
);
795 status
= NT_STATUS_OK
;
797 TALLOC_FREE(tmp_ctx
);
801 /* convert a domain SID to a user or group name */
802 static NTSTATUS
sam_sid_to_name(struct winbindd_domain
*domain
,
804 const struct dom_sid
*sid
,
807 enum lsa_SidType
*ptype
)
809 struct rpc_pipe_client
*samr_pipe
= NULL
;
810 struct dcerpc_binding_handle
*h
= NULL
;
811 struct policy_handle dom_pol
= { .handle_type
= 0, };
812 const char *domain_name
= "";
813 const char *name
= "";
814 enum lsa_SidType type
= SID_NAME_USE_NONE
;
815 struct lsa_Strings names
= { .count
= 0, };
816 struct samr_Ids types
= { .count
= 0 };
817 struct dom_sid domain_sid
;
819 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
820 NTSTATUS status
= NT_STATUS_NONE_MAPPED
;
825 DEBUG(3,("sam_sid_to_name\n"));
827 if (sid_check_is_unix_users(sid
)) {
828 domain_name
= unix_users_domain_name();
829 type
= SID_NAME_DOMAIN
;
832 if (sid_check_is_in_unix_users(sid
)) {
833 struct passwd
*pwd
= NULL
;
835 ok
= sid_peek_rid(sid
, &rid
);
844 domain_name
= unix_users_domain_name();
845 name
= talloc_strdup(tmp_ctx
, pwd
->pw_name
);
847 status
= NT_STATUS_NO_MEMORY
;
850 type
= SID_NAME_USER
;
854 if (sid_check_is_unix_groups(sid
)) {
855 domain_name
= unix_groups_domain_name();
856 type
= SID_NAME_DOMAIN
;
859 if (sid_check_is_in_unix_groups(sid
)) {
860 struct group
*grp
= NULL
;
862 ok
= sid_peek_rid(sid
, &rid
);
871 domain_name
= unix_groups_domain_name();
872 name
= talloc_strdup(tmp_ctx
, grp
->gr_name
);
874 status
= NT_STATUS_NO_MEMORY
;
877 type
= SID_NAME_DOM_GRP
;
881 ok
= lookup_wellknown_sid(tmp_ctx
, sid
, &domain_name
, &name
);
883 type
= SID_NAME_WKN_GRP
;
887 if (dom_sid_equal(sid
, &domain
->sid
)) {
888 domain_name
= domain
->name
;
889 type
= SID_NAME_DOMAIN
;
893 sid_copy(&domain_sid
, sid
);
894 ok
= sid_split_rid(&domain_sid
, &rid
);
899 if (!dom_sid_equal(&domain_sid
, &domain
->sid
)) {
904 status
= open_cached_internal_pipe_conn(
905 domain
, &samr_pipe
, &dom_pol
, NULL
, NULL
);
906 if (!NT_STATUS_IS_OK(status
)) {
909 h
= samr_pipe
->binding_handle
;
911 status
= dcerpc_samr_LookupRids(
912 h
, tmp_ctx
, &dom_pol
, 1, &rid
, &names
, &types
, &result
);
914 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
919 if (!NT_STATUS_IS_OK(status
)) {
920 DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
924 if (!NT_STATUS_IS_OK(result
)) {
925 DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
931 domain_name
= domain
->name
;
932 name
= names
.names
[0].string
;
936 char *normalized
= NULL
;
937 NTSTATUS nstatus
= normalize_name_map(
938 tmp_ctx
, domain_name
, name
, &normalized
);
939 if (NT_STATUS_IS_OK(nstatus
) ||
940 NT_STATUS_EQUAL(nstatus
, NT_STATUS_FILE_RENAMED
)) {
951 *pname
= talloc_strdup(mem_ctx
, name
);
952 if (*pname
== NULL
) {
953 status
= NT_STATUS_NO_MEMORY
;
959 *pdomain_name
= talloc_strdup(mem_ctx
, domain_name
);
960 if (*pdomain_name
== NULL
) {
961 status
= NT_STATUS_NO_MEMORY
;
966 status
= NT_STATUS_OK
;
968 TALLOC_FREE(tmp_ctx
);
972 static NTSTATUS
sam_rids_to_names(struct winbindd_domain
*domain
,
974 const struct dom_sid
*domain_sid
,
979 enum lsa_SidType
**ptypes
)
981 struct rpc_pipe_client
*samr_pipe
= NULL
;
982 struct dcerpc_binding_handle
*h
= NULL
;
983 struct policy_handle dom_pol
= { .handle_type
= 0, };
984 enum lsa_SidType
*types
= NULL
;
986 const char *domain_name
= NULL
;
987 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
988 NTSTATUS status
= NT_STATUS_NO_MEMORY
;
993 DEBUG(3,("sam_rids_to_names for %s\n", domain
->name
));
995 types
= talloc_array(tmp_ctx
, enum lsa_SidType
, num_rids
);
1000 names
= talloc_array(tmp_ctx
, char *, num_rids
);
1001 if (names
== NULL
) {
1005 if (sid_check_is_unix_users(domain_sid
)) {
1006 domain_name
= unix_users_domain_name();
1007 domain_sid
= &global_sid_Unix_Users
;
1009 if (sid_check_is_unix_groups(domain_sid
)) {
1010 domain_name
= unix_groups_domain_name();
1011 domain_sid
= &global_sid_Unix_Groups
;
1014 /* Here we're only interested in the domain name being set */
1015 sid_check_is_wellknown_domain(domain_sid
, &domain_name
);
1017 if (domain_name
!= NULL
) {
1018 uint32_t num_mapped
= 0;
1021 * Do unix users/groups and wkn in a loop. There is no
1022 * getpwuids() call & friends anyway
1025 for (i
=0; i
<num_rids
; i
++) {
1029 sid_compose(&sid
, domain_sid
, rids
[i
]);
1031 types
[i
] = SID_NAME_UNKNOWN
;
1034 status
= sam_sid_to_name(
1041 if (NT_STATUS_IS_OK(status
)) {
1042 names
[i
] = talloc_move(names
, &name
);
1047 status
= NT_STATUS_NONE_MAPPED
;
1048 if (num_mapped
> 0) {
1049 status
= (num_mapped
== num_rids
) ?
1050 NT_STATUS_OK
: STATUS_SOME_UNMAPPED
;
1055 domain_name
= domain
->name
;
1058 status
= open_cached_internal_pipe_conn(
1059 domain
, &samr_pipe
, &dom_pol
, NULL
, NULL
);
1060 if (!NT_STATUS_IS_OK(status
)) {
1063 h
= samr_pipe
->binding_handle
;
1066 * Magic number 1000 comes from samr.idl
1069 for (i
= 0; i
< num_rids
; i
+= 1000) {
1070 uint32_t num_lookup_rids
= MIN(num_rids
- i
, 1000);
1071 struct lsa_Strings lsa_names
= {
1074 struct samr_Ids samr_types
= {
1079 status
= dcerpc_samr_LookupRids(h
,
1089 reset_connection_on_error(domain
, samr_pipe
, status
)) {
1094 if (!NT_STATUS_IS_OK(status
)) {
1095 DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
1099 if (!NT_STATUS_IS_OK(result
) &&
1100 !NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
)) {
1101 DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
1107 for (j
= 0; j
< num_lookup_rids
; j
++) {
1108 uint32_t dst
= i
+ j
;
1110 types
[dst
] = samr_types
.ids
[j
];
1111 names
[dst
] = talloc_move(
1113 discard_const_p(char *,
1114 &lsa_names
.names
[j
].string
));
1115 if (names
[dst
] != NULL
) {
1116 char *normalized
= NULL
;
1118 normalize_name_map(names
,
1122 if (NT_STATUS_IS_OK(nstatus
) ||
1123 NT_STATUS_EQUAL(nstatus
,
1124 NT_STATUS_FILE_RENAMED
)) {
1125 names
[dst
] = normalized
;
1130 TALLOC_FREE(samr_types
.ids
);
1131 TALLOC_FREE(lsa_names
.names
);
1136 *pdomain_name
= talloc_strdup(mem_ctx
, domain_name
);
1137 if (*pdomain_name
== NULL
) {
1138 status
= NT_STATUS_NO_MEMORY
;
1144 *ptypes
= talloc_move(mem_ctx
, &types
);
1148 *pnames
= talloc_move(mem_ctx
, &names
);
1152 TALLOC_FREE(tmp_ctx
);
1156 static NTSTATUS
sam_lockout_policy(struct winbindd_domain
*domain
,
1157 TALLOC_CTX
*mem_ctx
,
1158 struct samr_DomInfo12
*lockout_policy
)
1160 struct rpc_pipe_client
*samr_pipe
;
1161 struct policy_handle dom_pol
= { 0 };
1162 union samr_DomainInfo
*info
= NULL
;
1163 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1164 NTSTATUS status
, result
;
1165 struct dcerpc_binding_handle
*b
= NULL
;
1168 DEBUG(3,("sam_lockout_policy\n"));
1171 status
= open_cached_internal_pipe_conn(domain
,
1176 if (!NT_STATUS_IS_OK(status
)) {
1180 b
= samr_pipe
->binding_handle
;
1182 status
= dcerpc_samr_QueryDomainInfo(b
,
1185 DomainLockoutInformation
,
1189 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1194 if (!NT_STATUS_IS_OK(status
)) {
1197 if (!NT_STATUS_IS_OK(result
)) {
1202 *lockout_policy
= info
->info12
;
1205 TALLOC_FREE(tmp_ctx
);
1209 static NTSTATUS
sam_password_policy(struct winbindd_domain
*domain
,
1210 TALLOC_CTX
*mem_ctx
,
1211 struct samr_DomInfo1
*passwd_policy
)
1213 struct rpc_pipe_client
*samr_pipe
;
1214 struct policy_handle dom_pol
= { 0 };
1215 union samr_DomainInfo
*info
= NULL
;
1216 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1217 NTSTATUS status
, result
;
1218 struct dcerpc_binding_handle
*b
= NULL
;
1221 DEBUG(3,("sam_password_policy\n"));
1224 status
= open_cached_internal_pipe_conn(domain
,
1229 if (!NT_STATUS_IS_OK(status
)) {
1233 b
= samr_pipe
->binding_handle
;
1235 status
= dcerpc_samr_QueryDomainInfo(b
,
1238 DomainPasswordInformation
,
1242 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1247 if (!NT_STATUS_IS_OK(status
)) {
1250 if (!NT_STATUS_IS_OK(result
)) {
1255 *passwd_policy
= info
->info1
;
1258 TALLOC_FREE(tmp_ctx
);
1262 /* Lookup groups a user is a member of. */
1263 static NTSTATUS
sam_lookup_usergroups(struct winbindd_domain
*domain
,
1264 TALLOC_CTX
*mem_ctx
,
1265 const struct dom_sid
*user_sid
,
1266 uint32_t *pnum_groups
,
1267 struct dom_sid
**puser_grpsids
)
1269 struct rpc_pipe_client
*samr_pipe
;
1270 struct policy_handle dom_pol
;
1271 struct dom_sid
*user_grpsids
= NULL
;
1272 uint32_t num_groups
= 0;
1273 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1277 DEBUG(3,("sam_lookup_usergroups\n"));
1279 ZERO_STRUCT(dom_pol
);
1286 status
= open_cached_internal_pipe_conn(domain
,
1291 if (!NT_STATUS_IS_OK(status
)) {
1295 status
= rpc_lookup_usergroups(tmp_ctx
,
1303 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1308 if (!NT_STATUS_IS_OK(status
)) {
1313 *pnum_groups
= num_groups
;
1316 if (puser_grpsids
) {
1317 *puser_grpsids
= talloc_move(mem_ctx
, &user_grpsids
);
1322 TALLOC_FREE(tmp_ctx
);
1326 static NTSTATUS
sam_lookup_useraliases(struct winbindd_domain
*domain
,
1327 TALLOC_CTX
*mem_ctx
,
1329 const struct dom_sid
*sids
,
1330 uint32_t *pnum_aliases
,
1331 uint32_t **palias_rids
)
1333 struct rpc_pipe_client
*samr_pipe
;
1334 struct policy_handle dom_pol
= { 0 };
1335 uint32_t num_aliases
= 0;
1336 uint32_t *alias_rids
= NULL
;
1337 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1341 DEBUG(3,("sam_lookup_useraliases\n"));
1348 status
= open_cached_internal_pipe_conn(domain
,
1353 if (!NT_STATUS_IS_OK(status
)) {
1357 status
= rpc_lookup_useraliases(tmp_ctx
,
1365 if (!retry
&& reset_connection_on_error(domain
, samr_pipe
, status
)) {
1370 if (!NT_STATUS_IS_OK(status
)) {
1375 *pnum_aliases
= num_aliases
;
1379 *palias_rids
= talloc_move(mem_ctx
, &alias_rids
);
1384 TALLOC_FREE(tmp_ctx
);
1388 /* the rpc backend methods are exposed via this structure */
1389 struct winbindd_methods builtin_passdb_methods
= {
1390 .consistent
= false,
1392 .query_user_list
= builtin_query_user_list
,
1393 .enum_dom_groups
= builtin_enum_dom_groups
,
1394 .enum_local_groups
= sam_enum_local_groups
,
1395 .name_to_sid
= sam_name_to_sid
,
1396 .sid_to_name
= sam_sid_to_name
,
1397 .rids_to_names
= sam_rids_to_names
,
1398 .lookup_usergroups
= sam_lookup_usergroups
,
1399 .lookup_useraliases
= sam_lookup_useraliases
,
1400 .lookup_groupmem
= sam_lookup_groupmem
,
1401 .lookup_aliasmem
= sam_lookup_aliasmem
,
1402 .lockout_policy
= sam_lockout_policy
,
1403 .password_policy
= sam_password_policy
,
1404 .trusted_domains
= builtin_trusted_domains
1407 /* the rpc backend methods are exposed via this structure */
1408 struct winbindd_methods sam_passdb_methods
= {
1409 .consistent
= false,
1411 .query_user_list
= sam_query_user_list
,
1412 .enum_dom_groups
= sam_enum_dom_groups
,
1413 .enum_local_groups
= sam_enum_local_groups
,
1414 .name_to_sid
= sam_name_to_sid
,
1415 .sid_to_name
= sam_sid_to_name
,
1416 .rids_to_names
= sam_rids_to_names
,
1417 .lookup_usergroups
= sam_lookup_usergroups
,
1418 .lookup_useraliases
= sam_lookup_useraliases
,
1419 .lookup_groupmem
= sam_lookup_groupmem
,
1420 .lookup_aliasmem
= sam_lookup_aliasmem
,
1421 .lockout_policy
= sam_lockout_policy
,
1422 .password_policy
= sam_password_policy
,
1423 .trusted_domains
= sam_trusted_domains