2 * idmap_adex: Domain search interface
4 * Copyright (C) Gerald (Jerry) Carter 2007-2008
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "idmap_adex.h"
27 #define DBGC_CLASS DBGC_IDMAP
30 struct dc_info
*prev
, *next
;
32 struct likewise_cell
*domain_cell
;
35 static struct dc_info
*_dc_server_list
= NULL
;
38 /**********************************************************************
39 *********************************************************************/
41 static struct dc_info
*dc_list_head(void)
43 return _dc_server_list
;
46 /**********************************************************************
47 *********************************************************************/
49 static NTSTATUS
dc_add_domain(const char *domain
)
51 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
52 struct dc_info
*dc
= NULL
;
55 return NT_STATUS_INVALID_PARAMETER
;
58 DEBUG(10,("dc_add_domain: Attempting to add domain %s\n", domain
));
60 /* Check for duplicates */
64 if (strequal (dc
->dns_name
, domain
))
70 DEBUG(10,("dc_add_domain: %s already in list\n", domain
));
74 dc
= talloc_zero(NULL
, struct dc_info
);
75 BAIL_ON_PTR_ERROR(dc
, nt_status
);
77 dc
->dns_name
= talloc_strdup(dc
, domain
);
78 BAIL_ON_PTR_ERROR(dc
->dns_name
, nt_status
);
80 DLIST_ADD_END(_dc_server_list
, dc
, struct dc_info
*);
82 nt_status
= NT_STATUS_OK
;
84 DEBUG(5,("dc_add_domain: Successfully added %s\n", domain
));
87 if (!NT_STATUS_IS_OK(nt_status
)) {
89 DEBUG(0,("LWI: Failed to add new DC connection for %s (%s)\n",
90 domain
, nt_errstr(nt_status
)));
96 /**********************************************************************
97 *********************************************************************/
99 static void dc_server_list_destroy(void)
101 struct dc_info
*dc
= dc_list_head();
104 struct dc_info
*p
= dc
->next
;
106 cell_destroy(dc
->domain_cell
);
116 /**********************************************************************
117 *********************************************************************/
119 NTSTATUS
domain_init_list(void)
121 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
122 struct winbindd_tdc_domain
*domains
= NULL
;
123 size_t num_domains
= 0;
126 if (_dc_server_list
!= NULL
) {
127 dc_server_list_destroy();
132 nt_status
= dc_add_domain(lp_realm());
133 BAIL_ON_NTSTATUS_ERROR(nt_status
);
135 if (!wcache_tdc_fetch_list(&domains
, &num_domains
)) {
136 nt_status
= NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
137 BAIL_ON_NTSTATUS_ERROR(nt_status
);
140 /* Add all domains with an incoming trust path */
142 for (i
=0; i
<num_domains
; i
++) {
143 uint32_t flags
= (NETR_TRUST_FLAG_INBOUND
|NETR_TRUST_FLAG_IN_FOREST
);
145 /* We just require one of the flags to be set here */
147 if (domains
[i
].trust_flags
& flags
) {
148 nt_status
= dc_add_domain(domains
[i
].dns_name
);
149 BAIL_ON_NTSTATUS_ERROR(nt_status
);
153 nt_status
= NT_STATUS_OK
;
156 if (!NT_STATUS_IS_OK(nt_status
)) {
157 DEBUG(2,("LWI: Failed to initialize DC list (%s)\n",
158 nt_errstr(nt_status
)));
161 TALLOC_FREE(domains
);
166 /********************************************************************
167 *******************************************************************/
169 static NTSTATUS
dc_do_search(struct dc_info
*dc
,
170 const char *search_base
,
176 ADS_STATUS status
= ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL
);
177 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
179 status
= cell_do_search(dc
->domain_cell
, search_base
,
180 scope
, expr
, attrs
, msg
);
181 nt_status
= ads_ntstatus(status
);
186 /**********************************************************************
187 *********************************************************************/
189 static struct dc_info
*dc_find_domain(const char *dns_domain
)
191 struct dc_info
*dc
= dc_list_head();
197 if (strequal(dc
->dns_name
, dns_domain
)) {
207 /**********************************************************************
208 *********************************************************************/
210 NTSTATUS
dc_search_domains(struct likewise_cell
**cell
,
213 const struct dom_sid
*sid
)
215 NTSTATUS nt_status
= NT_STATUS_UNSUCCESSFUL
;
216 TALLOC_CTX
*frame
= talloc_stackframe();
218 const char *attrs
[] = { "*", NULL
};
219 struct dc_info
*dc
= NULL
;
220 const char *base
= NULL
;
223 nt_status
= NT_STATUS_INVALID_PARAMETER
;
224 BAIL_ON_NTSTATUS_ERROR(nt_status
);
227 dns_domain
= cell_dn_to_dns(dn
);
228 BAIL_ON_PTR_ERROR(dns_domain
, nt_status
);
230 if ((dc
= dc_find_domain(dns_domain
)) == NULL
) {
231 nt_status
= NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
232 BAIL_ON_NTSTATUS_ERROR(nt_status
);
235 /* Reparse the cell settings for the domain if necessary */
237 if (!dc
->domain_cell
) {
240 base_dn
= ads_build_dn(dc
->dns_name
);
241 BAIL_ON_PTR_ERROR(base_dn
, nt_status
);
243 nt_status
= cell_connect_dn(&dc
->domain_cell
, base_dn
);
245 BAIL_ON_NTSTATUS_ERROR(nt_status
);
247 nt_status
= cell_lookup_settings(dc
->domain_cell
);
248 BAIL_ON_NTSTATUS_ERROR(nt_status
);
250 /* By definition this is already part of a larger
251 forest-wide search scope */
253 cell_set_flags(dc
->domain_cell
, LWCELL_FLAG_SEARCH_FOREST
);
256 /* Check whether we are operating in non-schema or RFC2307
259 if (cell_flags(dc
->domain_cell
) & LWCELL_FLAG_USE_RFC2307_ATTRS
) {
260 nt_status
= dc_do_search(dc
, dn
, LDAP_SCOPE_BASE
,
261 "(objectclass=*)", attrs
, msg
);
263 const char *sid_str
= NULL
;
266 sid_str
= sid_string_talloc(frame
, sid
);
267 BAIL_ON_PTR_ERROR(sid_str
, nt_status
);
269 filter
= talloc_asprintf(frame
, "(keywords=backLink=%s)",
271 BAIL_ON_PTR_ERROR(filter
, nt_status
);
273 base
= cell_search_base(dc
->domain_cell
);
274 BAIL_ON_PTR_ERROR(base
, nt_status
);
276 nt_status
= dc_do_search(dc
, base
, LDAP_SCOPE_SUBTREE
,
279 BAIL_ON_NTSTATUS_ERROR(nt_status
);
281 *cell
= dc
->domain_cell
;
284 talloc_destroy(discard_const_p(char, base
));
285 talloc_destroy(frame
);