s3/packaging: pam_winbind has been moved to section 8.
[Samba/gebeck_regimport.git] / source3 / winbindd / idmap_adex / domain_util.c
blob6851503cc8b7c647d5ea9625647a276e21d44bf1
1 /*
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.
21 #include "includes.h"
22 #include "idmap_adex.h"
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_IDMAP
27 struct dc_info {
28 struct dc_info *prev, *next;
29 char *dns_name;
30 struct likewise_cell *domain_cell;
33 static struct dc_info *_dc_server_list = NULL;
36 /**********************************************************************
37 *********************************************************************/
39 static struct dc_info *dc_list_head(void)
41 return _dc_server_list;
44 /**********************************************************************
45 *********************************************************************/
47 static NTSTATUS dc_add_domain(const char *domain)
49 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
50 struct dc_info *dc = NULL;
52 if (!domain) {
53 return NT_STATUS_INVALID_PARAMETER;
56 DEBUG(10,("dc_add_domain: Attempting to add domain %s\n", domain));
58 /* Check for duplicates */
60 dc = dc_list_head();
61 while (dc) {
62 if (strequal (dc->dns_name, domain))
63 break;
64 dc = dc->next;
67 if (dc) {
68 DEBUG(10,("dc_add_domain: %s already in list\n", domain));
69 return NT_STATUS_OK;
72 dc = TALLOC_ZERO_P(NULL, struct dc_info);
73 BAIL_ON_PTR_ERROR(dc, nt_status);
75 dc->dns_name = talloc_strdup(dc, domain);
76 BAIL_ON_PTR_ERROR(dc->dns_name, nt_status);
78 DLIST_ADD_END(_dc_server_list, dc, struct dc_info*);
80 nt_status = NT_STATUS_OK;
82 DEBUG(5,("dc_add_domain: Successfully added %s\n", domain));
84 done:
85 if (!NT_STATUS_IS_OK(nt_status)) {
86 talloc_destroy(dc);
87 DEBUG(0,("LWI: Failed to add new DC connection for %s (%s)\n",
88 domain, nt_errstr(nt_status)));
91 return nt_status;
94 /**********************************************************************
95 *********************************************************************/
97 static void dc_server_list_destroy(void)
99 struct dc_info *dc = dc_list_head();
101 while (dc) {
102 struct dc_info *p = dc->next;
104 cell_destroy(dc->domain_cell);
105 talloc_destroy(dc);
107 dc = p;
110 return;
114 /**********************************************************************
115 *********************************************************************/
117 NTSTATUS domain_init_list(void)
119 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
120 struct winbindd_tdc_domain *domains = NULL;
121 size_t num_domains = 0;
122 int i;
124 if (_dc_server_list != NULL) {
125 dc_server_list_destroy();
128 /* Add our domain */
130 nt_status = dc_add_domain(lp_realm());
131 BAIL_ON_NTSTATUS_ERROR(nt_status);
133 if (!wcache_tdc_fetch_list(&domains, &num_domains)) {
134 nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
135 BAIL_ON_NTSTATUS_ERROR(nt_status);
138 /* Add all domains with an incoming trust path */
140 for (i=0; i<num_domains; i++) {
141 uint32_t flags = (NETR_TRUST_FLAG_INBOUND|NETR_TRUST_FLAG_IN_FOREST);
143 /* We just require one of the flags to be set here */
145 if (domains[i].trust_flags & flags) {
146 nt_status = dc_add_domain(domains[i].dns_name);
147 BAIL_ON_NTSTATUS_ERROR(nt_status);
151 nt_status = NT_STATUS_OK;
153 done:
154 if (!NT_STATUS_IS_OK(nt_status)) {
155 DEBUG(2,("LWI: Failed to initialize DC list (%s)\n",
156 nt_errstr(nt_status)));
159 TALLOC_FREE(domains);
161 return nt_status;
164 /********************************************************************
165 *******************************************************************/
167 static NTSTATUS dc_do_search(struct dc_info *dc,
168 const char *search_base,
169 int scope,
170 const char *expr,
171 const char **attrs,
172 LDAPMessage ** msg)
174 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
175 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
177 status = cell_do_search(dc->domain_cell, search_base,
178 scope, expr, attrs, msg);
179 nt_status = ads_ntstatus(status);
181 return nt_status;
184 /**********************************************************************
185 *********************************************************************/
187 static struct dc_info *dc_find_domain(const char *dns_domain)
189 struct dc_info *dc = dc_list_head();
191 if (!dc)
192 return NULL;
194 while (dc) {
195 if (strequal(dc->dns_name, dns_domain)) {
196 return dc;
199 dc = dc->next;
202 return NULL;
205 /**********************************************************************
206 *********************************************************************/
208 NTSTATUS dc_search_domains(struct likewise_cell **cell,
209 LDAPMessage **msg,
210 const char *dn,
211 const DOM_SID *sid)
213 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
214 TALLOC_CTX *frame = talloc_stackframe();
215 char *dns_domain;
216 const char *attrs[] = { "*", NULL };
217 struct dc_info *dc = NULL;
218 const char *base = NULL;
220 if (!dn || !*dn) {
221 nt_status = NT_STATUS_INVALID_PARAMETER;
222 BAIL_ON_NTSTATUS_ERROR(nt_status);
225 dns_domain = cell_dn_to_dns(dn);
226 BAIL_ON_PTR_ERROR(dns_domain, nt_status);
228 if ((dc = dc_find_domain(dns_domain)) == NULL) {
229 nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
230 BAIL_ON_NTSTATUS_ERROR(nt_status);
233 /* Reparse the cell settings for the domain if necessary */
235 if (!dc->domain_cell) {
236 char *base_dn;
238 base_dn = ads_build_dn(dc->dns_name);
239 BAIL_ON_PTR_ERROR(base_dn, nt_status);
241 nt_status = cell_connect_dn(&dc->domain_cell, base_dn);
242 SAFE_FREE(base_dn);
243 BAIL_ON_NTSTATUS_ERROR(nt_status);
245 nt_status = cell_lookup_settings(dc->domain_cell);
246 BAIL_ON_NTSTATUS_ERROR(nt_status);
248 /* By definition this is already part of a larger
249 forest-wide search scope */
251 cell_set_flags(dc->domain_cell, LWCELL_FLAG_SEARCH_FOREST);
254 /* Check whether we are operating in non-schema or RFC2307
255 mode */
257 if (cell_flags(dc->domain_cell) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
258 nt_status = dc_do_search(dc, dn, LDAP_SCOPE_BASE,
259 "(objectclass=*)", attrs, msg);
260 } else {
261 const char *sid_str = NULL;
262 char *filter = NULL;
264 sid_str = sid_string_talloc(frame, sid);
265 BAIL_ON_PTR_ERROR(sid_str, nt_status);
267 filter = talloc_asprintf(frame, "(keywords=backLink=%s)",
268 sid_str);
269 BAIL_ON_PTR_ERROR(filter, nt_status);
271 base = cell_search_base(dc->domain_cell);
272 BAIL_ON_PTR_ERROR(base, nt_status);
274 nt_status = dc_do_search(dc, base, LDAP_SCOPE_SUBTREE,
275 filter, attrs, msg);
277 BAIL_ON_NTSTATUS_ERROR(nt_status);
279 *cell = dc->domain_cell;
281 done:
282 talloc_destroy(CONST_DISCARD(char*, base));
283 talloc_destroy(frame);
285 return nt_status;