]> andersk Git - mod-vhost-ldap.git/blame - mod_vhost_ldap.c
mod_vhost_ldap: Copy the server_rec instead of corrupting it in place.
[mod-vhost-ldap.git] / mod_vhost_ldap.c
CommitLineData
7f9875bb
OS
1/* ============================================================
2 * Copyright (c) 2003-2004, Ondrej Sury
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19/*
20 * mod_vhost_ldap.c --- read virtual host config from LDAP directory
21 */
22
9ee2dda1 23#define CORE_PRIVATE
9ee2dda1 24
7f9875bb
OS
25#include <unistd.h>
26
27#include "httpd.h"
28#include "http_config.h"
29#include "http_core.h"
30#include "http_log.h"
31#include "http_request.h"
8503d00b 32#include "apr_version.h"
7f9875bb
OS
33#include "apr_ldap.h"
34#include "apr_strings.h"
35#include "apr_reslist.h"
36#include "util_ldap.h"
37
3b8a47e0 38#if !defined(APU_HAS_LDAP) && !defined(APR_HAS_LDAP)
7f9875bb
OS
39#error mod_vhost_ldap requires APR-util to have LDAP support built in
40#endif
41
42#if !defined(WIN32) && !defined(OS2) && !defined(BEOS) && !defined(NETWARE)
43#define HAVE_UNIX_SUEXEC
44#endif
45
46#ifdef HAVE_UNIX_SUEXEC
47#include "unixd.h" /* Contains the suexec_identity hook used on Unix */
48#endif
49
d129bb81
OS
50#define MIN_UID 100
51#define MIN_GID 100
7f9875bb
OS
52
53module AP_MODULE_DECLARE_DATA vhost_ldap_module;
54
8196fae3
OS
55typedef enum {
56 MVL_UNSET, MVL_DISABLED, MVL_ENABLED
57} mod_vhost_ldap_status_e;
58
7f9875bb 59typedef struct mod_vhost_ldap_config_t {
8196fae3 60 mod_vhost_ldap_status_e enabled; /* Is vhost_ldap enabled? */
7f9875bb
OS
61
62 /* These parameters are all derived from the VhostLDAPURL directive */
63 char *url; /* String representation of LDAP URL */
64
65 char *host; /* Name of the LDAP server (or space separated list) */
66 int port; /* Port of the LDAP server */
67 char *basedn; /* Base DN to do all searches from */
68 int scope; /* Scope of the search */
69 char *filter; /* Filter to further limit the search */
70 deref_options deref; /* how to handle alias dereferening */
71
72 char *binddn; /* DN to bind to server (can be NULL) */
73 char *bindpw; /* Password to bind to server (can be NULL) */
74
8196fae3 75 int have_deref; /* Set if we have found an Deref option */
7f9875bb
OS
76 int have_ldap_url; /* Set if we have found an LDAP url */
77
78 int secure; /* True if SSL connections are requested */
6056cddb
OS
79
80 char *fallback; /* Fallback virtual host */
81
7f9875bb
OS
82} mod_vhost_ldap_config_t;
83
84typedef struct mod_vhost_ldap_request_t {
85 char *dn; /* The saved dn from a successful search */
86 char *name; /* ServerName */
87 char *admin; /* ServerAdmin */
88 char *docroot; /* DocumentRoot */
9ee2dda1 89 char *cgiroot; /* ScriptAlias */
7f9875bb
OS
90 char *uid; /* Suexec Uid */
91 char *gid; /* Suexec Gid */
92} mod_vhost_ldap_request_t;
93
94char *attributes[] =
6f705808 95 { "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 };
7f9875bb 96
9965ff97
AK
97static int total_modules;
98
8503d00b 99#if (APR_MAJOR_VERSION >= 1)
3b8a47e0
OS
100static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
101static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
102static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
103static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
104static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid;
105static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn;
106static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported;
107
108static void ImportULDAPOptFn(void)
109{
110 util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
111 util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find);
112 util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
113 util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
114 util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
115 util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
116 util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
117}
118#endif
119
7f9875bb
OS
120static int mod_vhost_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
121{
9965ff97
AK
122 module **m;
123
124 /* Stolen from modules/generators/mod_cgid.c */
125 total_modules = 0;
126 for (m = ap_preloaded_modules; *m != NULL; m++)
127 total_modules++;
128
7f9875bb
OS
129 /* make sure that mod_ldap (util_ldap) is loaded */
130 if (ap_find_linked_module("util_ldap.c") == NULL) {
131 ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s,
132 "Module mod_ldap missing. Mod_ldap (aka. util_ldap) "
133 "must be loaded in order for mod_vhost_ldap to function properly");
134 return HTTP_INTERNAL_SERVER_ERROR;
135
136 }
137
9ee2dda1 138 ap_add_version_component(p, MOD_VHOST_LDAP_VERSION);
7f9875bb
OS
139
140 return OK;
141}
142
143static void *
144mod_vhost_ldap_create_server_config (apr_pool_t *p, server_rec *s)
145{
8196fae3 146 mod_vhost_ldap_config_t *conf =
7f9875bb
OS
147 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof (mod_vhost_ldap_config_t));
148
8196fae3
OS
149 conf->enabled = MVL_UNSET;
150 conf->have_ldap_url = 0;
151 conf->have_deref = 0;
152 conf->binddn = NULL;
153 conf->bindpw = NULL;
154 conf->deref = always;
6056cddb 155 conf->fallback = NULL;
8196fae3
OS
156
157 return conf;
158}
159
160static void *
161mod_vhost_ldap_merge_server_config(apr_pool_t *p, void *parentv, void *childv)
162{
163 mod_vhost_ldap_config_t *parent = (mod_vhost_ldap_config_t *) parentv;
164 mod_vhost_ldap_config_t *child = (mod_vhost_ldap_config_t *) childv;
165 mod_vhost_ldap_config_t *conf =
166 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof(mod_vhost_ldap_config_t));
7f9875bb 167
8196fae3
OS
168 if (child->enabled == MVL_UNSET) {
169 conf->enabled = parent->enabled;
170 } else {
171 conf->enabled = child->enabled;
172 }
7f9875bb 173
8196fae3
OS
174 if (child->have_ldap_url) {
175 conf->have_ldap_url = child->have_ldap_url;
176 conf->url = child->url;
177 conf->host = child->host;
178 conf->port = child->port;
179 conf->basedn = child->basedn;
180 conf->scope = child->scope;
181 conf->filter = child->filter;
182 conf->secure = child->secure;
183 } else {
184 conf->have_ldap_url = parent->have_ldap_url;
185 conf->url = parent->url;
186 conf->host = parent->host;
187 conf->port = parent->port;
188 conf->basedn = parent->basedn;
189 conf->scope = parent->scope;
190 conf->filter = parent->filter;
191 conf->secure = parent->secure;
192 }
193 if (child->have_deref) {
194 conf->have_deref = child->have_deref;
195 conf->deref = child->deref;
196 } else {
197 conf->have_deref = parent->have_deref;
198 conf->deref = parent->deref;
199 }
200
201 conf->binddn = (child->binddn ? child->binddn : parent->binddn);
202 conf->bindpw = (child->bindpw ? child->bindpw : parent->bindpw);
203
6056cddb
OS
204 conf->fallback = (child->fallback ? child->fallback : parent->fallback);
205
8196fae3 206 return conf;
7f9875bb
OS
207}
208
209/*
210 * Use the ldap url parsing routines to break up the ldap url into
211 * host and port.
212 */
213static const char *mod_vhost_ldap_parse_url(cmd_parms *cmd,
214 void *dummy,
215 const char *url)
216{
217 int result;
218 apr_ldap_url_desc_t *urld;
8503d00b 219#if (APR_MAJOR_VERSION >= 1)
3b8a47e0 220 apr_ldap_err_t *result_err;
8503d00b 221#endif
7f9875bb 222
8196fae3 223 mod_vhost_ldap_config_t *conf =
7f9875bb
OS
224 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
225 &vhost_ldap_module);
226
227 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
228 cmd->server, "[mod_vhost_ldap.c] url parse: `%s'",
229 url);
8503d00b
OS
230
231#if (APR_MAJOR_VERSION >= 1) /* for apache >= 2.2 */
3b8a47e0
OS
232 result = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result_err));
233 if (result != LDAP_SUCCESS) {
234 return result_err->reason;
235 }
236#else
7f9875bb
OS
237 result = apr_ldap_url_parse(url, &(urld));
238 if (result != LDAP_SUCCESS) {
239 switch (result) {
3b8a47e0
OS
240 case LDAP_URL_ERR_NOTLDAP:
241 return "LDAP URL does not begin with ldap://";
242 case LDAP_URL_ERR_NODN:
243 return "LDAP URL does not have a DN";
244 case LDAP_URL_ERR_BADSCOPE:
245 return "LDAP URL has an invalid scope";
246 case LDAP_URL_ERR_MEM:
247 return "Out of memory parsing LDAP URL";
248 default:
249 return "Could not parse LDAP URL";
7f9875bb
OS
250 }
251 }
3b8a47e0 252#endif
8196fae3 253 conf->url = apr_pstrdup(cmd->pool, url);
7f9875bb
OS
254
255 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
256 cmd->server, "[mod_vhost_ldap.c] url parse: Host: %s", urld->lud_host);
257 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
258 cmd->server, "[mod_vhost_ldap.c] url parse: Port: %d", urld->lud_port);
259 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
260 cmd->server, "[mod_vhost_ldap.c] url parse: DN: %s", urld->lud_dn);
261 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
262 cmd->server, "[mod_vhost_ldap.c] url parse: attrib: %s", urld->lud_attrs? urld->lud_attrs[0] : "(null)");
263 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
264 cmd->server, "[mod_vhost_ldap.c] url parse: scope: %s",
265 (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" :
266 urld->lud_scope == LDAP_SCOPE_BASE? "base" :
267 urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown"));
268 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
269 cmd->server, "[mod_vhost_ldap.c] url parse: filter: %s", urld->lud_filter);
270
271 /* Set all the values, or at least some sane defaults */
8196fae3
OS
272 if (conf->host) {
273 char *p = apr_palloc(cmd->pool, strlen(conf->host) + strlen(urld->lud_host) + 2);
7f9875bb
OS
274 strcpy(p, urld->lud_host);
275 strcat(p, " ");
8196fae3
OS
276 strcat(p, conf->host);
277 conf->host = p;
7f9875bb
OS
278 }
279 else {
8196fae3 280 conf->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost";
7f9875bb 281 }
8196fae3 282 conf->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
7f9875bb 283
8196fae3 284 conf->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ?
7f9875bb
OS
285 LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE;
286
287 if (urld->lud_filter) {
288 if (urld->lud_filter[0] == '(') {
289 /*
290 * Get rid of the surrounding parens; later on when generating the
291 * filter, they'll be put back.
292 */
8196fae3
OS
293 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1);
294 conf->filter[strlen(conf->filter)-1] = '\0';
7f9875bb
OS
295 }
296 else {
8196fae3 297 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter);
7f9875bb
OS
298 }
299 }
300 else {
8196fae3 301 conf->filter = "objectClass=apacheConfig";
7f9875bb
OS
302 }
303
304 /* "ldaps" indicates secure ldap connections desired
305 */
306 if (strncasecmp(url, "ldaps", 5) == 0)
307 {
8196fae3
OS
308 conf->secure = 1;
309 conf->port = urld->lud_port? urld->lud_port : LDAPS_PORT;
7f9875bb
OS
310 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
311 "LDAP: vhost_ldap using SSL connections");
312 }
313 else
314 {
8196fae3
OS
315 conf->secure = 0;
316 conf->port = urld->lud_port? urld->lud_port : LDAP_PORT;
fb323462 317 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
7f9875bb
OS
318 "LDAP: vhost_ldap not using SSL connections");
319 }
320
8196fae3 321 conf->have_ldap_url = 1;
8503d00b 322#if (APR_MAJOR_VERSION < 1) /* free only required for older apr */
7f9875bb 323 apr_ldap_free_urldesc(urld);
3b8a47e0 324#endif
7f9875bb
OS
325 return NULL;
326}
327
328static const char *mod_vhost_ldap_set_enabled(cmd_parms *cmd, void *dummy, int enabled)
329{
8196fae3 330 mod_vhost_ldap_config_t *conf =
7f9875bb 331 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
6056cddb 332 &vhost_ldap_module);
7f9875bb 333
8196fae3
OS
334 conf->enabled = (enabled) ? MVL_ENABLED : MVL_DISABLED;
335
7f9875bb
OS
336 return NULL;
337}
338
339static const char *mod_vhost_ldap_set_binddn(cmd_parms *cmd, void *dummy, const char *binddn)
340{
8196fae3 341 mod_vhost_ldap_config_t *conf =
7f9875bb 342 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
6056cddb 343 &vhost_ldap_module);
7f9875bb 344
8196fae3 345 conf->binddn = apr_pstrdup(cmd->pool, binddn);
7f9875bb
OS
346 return NULL;
347}
348
349static const char *mod_vhost_ldap_set_bindpw(cmd_parms *cmd, void *dummy, const char *bindpw)
350{
8196fae3 351 mod_vhost_ldap_config_t *conf =
7f9875bb 352 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
6056cddb 353 &vhost_ldap_module);
7f9875bb 354
8196fae3 355 conf->bindpw = apr_pstrdup(cmd->pool, bindpw);
7f9875bb
OS
356 return NULL;
357}
358
359static const char *mod_vhost_ldap_set_deref(cmd_parms *cmd, void *dummy, const char *deref)
360{
8196fae3 361 mod_vhost_ldap_config_t *conf =
7f9875bb
OS
362 (mod_vhost_ldap_config_t *)ap_get_module_config (cmd->server->module_config,
363 &vhost_ldap_module);
364
365 if (strcmp(deref, "never") == 0 || strcasecmp(deref, "off") == 0) {
8196fae3
OS
366 conf->deref = never;
367 conf->have_deref = 1;
7f9875bb
OS
368 }
369 else if (strcmp(deref, "searching") == 0) {
8196fae3
OS
370 conf->deref = searching;
371 conf->have_deref = 1;
7f9875bb
OS
372 }
373 else if (strcmp(deref, "finding") == 0) {
8196fae3
OS
374 conf->deref = finding;
375 conf->have_deref = 1;
7f9875bb
OS
376 }
377 else if (strcmp(deref, "always") == 0 || strcasecmp(deref, "on") == 0) {
8196fae3
OS
378 conf->deref = always;
379 conf->have_deref = 1;
7f9875bb
OS
380 }
381 else {
382 return "Unrecognized value for VhostLDAPAliasDereference directive";
383 }
384 return NULL;
385}
386
6056cddb
OS
387static const char *mod_vhost_ldap_set_fallback(cmd_parms *cmd, void *dummy, const char *fallback)
388{
389 mod_vhost_ldap_config_t *conf =
390 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
391 &vhost_ldap_module);
392
393 conf->fallback = apr_pstrdup(cmd->pool, fallback);
394 return NULL;
395}
396
7f9875bb
OS
397command_rec mod_vhost_ldap_cmds[] = {
398 AP_INIT_TAKE1("VhostLDAPURL", mod_vhost_ldap_parse_url, NULL, RSRC_CONF,
a940f969 399 "URL to define LDAP connection. This should be an RFC 2255 compliant\n"
7f9875bb
OS
400 "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n"
401 "<ul>\n"
402 "<li>Host is the name of the LDAP server. Use a space separated list of hosts \n"
403 "to specify redundant servers.\n"
404 "<li>Port is optional, and specifies the port to connect to.\n"
405 "<li>basedn specifies the base DN to start searches from\n"
406 "</ul>\n"),
407
408 AP_INIT_TAKE1 ("VhostLDAPBindDN", mod_vhost_ldap_set_binddn, NULL, RSRC_CONF,
409 "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."),
410
411 AP_INIT_TAKE1("VhostLDAPBindPassword", mod_vhost_ldap_set_bindpw, NULL, RSRC_CONF,
412 "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."),
413
414 AP_INIT_FLAG("VhostLDAPEnabled", mod_vhost_ldap_set_enabled, NULL, RSRC_CONF,
415 "Set to off to disable vhost_ldap, even if it's been enabled in a higher tree"),
416
417 AP_INIT_TAKE1("VhostLDAPDereferenceAliases", mod_vhost_ldap_set_deref, NULL, RSRC_CONF,
a940f969 418 "Determines how aliases are handled during a search. Can be one of the"
7f9875bb
OS
419 "values \"never\", \"searching\", \"finding\", or \"always\". "
420 "Defaults to always."),
421
6056cddb
OS
422 AP_INIT_TAKE1("VhostLDAPFallback", mod_vhost_ldap_set_fallback, NULL, RSRC_CONF,
423 "Set default virtual host which will be used when requested hostname"
424 "is not found in LDAP database. This option can be used to display"
425 "\"virtual host not found\" type of page."),
426
7f9875bb
OS
427 {NULL}
428};
429
430#define FILTER_LENGTH MAX_STRING_LEN
b5043ccb 431static int mod_vhost_ldap_translate_name(request_rec *r)
7f9875bb 432{
b5043ccb 433 mod_vhost_ldap_request_t *reqc;
7f9875bb
OS
434 apr_table_t *e;
435 int failures = 0;
436 const char **vals = NULL;
437 char filtbuf[FILTER_LENGTH];
8196fae3 438 mod_vhost_ldap_config_t *conf =
7f9875bb 439 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_module);
9ee2dda1
OS
440 core_server_config * core =
441 (core_server_config *) ap_get_module_config(r->server->module_config, &core_module);
7f9875bb
OS
442 util_ldap_connection_t *ldc = NULL;
443 int result = 0;
444 const char *dn = NULL;
445 char *cgi;
6056cddb
OS
446 const char *hostname = NULL;
447 int is_fallback = 0;
7f9875bb 448
b5043ccb 449 reqc =
7f9875bb 450 (mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t));
8503d00b 451 memset(reqc, 0, sizeof(mod_vhost_ldap_request_t));
b5043ccb
OS
452
453 ap_set_module_config(r->request_config, &vhost_ldap_module, reqc);
7f9875bb 454
8196fae3
OS
455 // mod_vhost_ldap is disabled or we don't have LDAP Url
456 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
7f9875bb
OS
457 return DECLINED;
458 }
459
460start_over:
461
8196fae3
OS
462 if (conf->host) {
463 ldc = util_ldap_connection_find(r, conf->host, conf->port,
464 conf->binddn, conf->bindpw, conf->deref,
465 conf->secure);
7f9875bb
OS
466 }
467 else {
468 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
fb323462 469 "[mod_vhost_ldap.c] translate: no conf->host - weird...?");
7f9875bb
OS
470 return DECLINED;
471 }
472
6056cddb 473 hostname = r->hostname;
cb70a058
AK
474 if (hostname == NULL || hostname[0] == '\0')
475 goto null;
6056cddb
OS
476
477fallback:
478
fb323462 479 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
6f705808 480 "[mod_vhost_ldap.c]: translating %s", r->uri);
7f9875bb 481
83c0f57d
AK
482 struct berval hostnamebv, shostnamebv;
483 ber_str2bv(hostname, 0, 0, &hostnamebv);
484 if (ldap_bv2escaped_filter_value(&hostnamebv, &shostnamebv) != 0)
485 goto null;
486 apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, shostnamebv.bv_val, shostnamebv.bv_val);
487 ber_memfree(shostnamebv.bv_val);
7f9875bb 488
8196fae3 489 result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope,
7f9875bb
OS
490 attributes, filtbuf, &dn, &vals);
491
492 util_ldap_connection_close(ldc);
493
494 /* sanity check - if server is down, retry it up to 5 times */
495 if (result == LDAP_SERVER_DOWN) {
496 if (failures++ <= 5) {
497 goto start_over;
498 }
499 }
500
6056cddb 501 if ((result == LDAP_NO_SUCH_OBJECT)) {
cb70a058 502 null:
6056cddb
OS
503 if (conf->fallback && (is_fallback++ <= 0)) {
504 ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r,
505 "[mod_vhost_ldap.c] translate: "
506 "virtual host %s not found, trying fallback %s",
507 hostname, conf->fallback);
508 hostname = conf->fallback;
509 goto fallback;
510 }
511
512 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
513 "[mod_vhost_ldap.c] translate: "
514 "virtual host %s not found",
515 hostname);
516
517 return DECLINED;
518 }
519
7f9875bb
OS
520 /* handle bind failure */
521 if (result != LDAP_SUCCESS) {
cbd5c5f5 522 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
7f9875bb 523 "[mod_vhost_ldap.c] translate: "
6056cddb
OS
524 "translate failed; virtual host %s; URI %s [%s]",
525 hostname, r->uri, ldap_err2string(result));
7f9875bb
OS
526 return DECLINED;
527 }
528
529 /* mark the user and DN */
b5043ccb 530 reqc->dn = apr_pstrdup(r->pool, dn);
7f9875bb
OS
531
532 /* Optimize */
533 if (vals) {
534 int i = 0;
535 while (attributes[i]) {
536
537 if (strcasecmp (attributes[i], "apacheServerName") == 0) {
b5043ccb 538 reqc->name = apr_pstrdup (r->pool, vals[i]);
7f9875bb
OS
539 }
540 else if (strcasecmp (attributes[i], "apacheServerAdmin") == 0) {
b5043ccb 541 reqc->admin = apr_pstrdup (r->pool, vals[i]);
7f9875bb
OS
542 }
543 else if (strcasecmp (attributes[i], "apacheDocumentRoot") == 0) {
b5043ccb 544 reqc->docroot = apr_pstrdup (r->pool, vals[i]);
7f9875bb
OS
545 }
546 else if (strcasecmp (attributes[i], "apacheScriptAlias") == 0) {
b5043ccb 547 reqc->cgiroot = apr_pstrdup (r->pool, vals[i]);
7f9875bb
OS
548 }
549 else if (strcasecmp (attributes[i], "apacheSuexecUid") == 0) {
b5043ccb 550 reqc->uid = apr_pstrdup(r->pool, vals[i]);
7f9875bb
OS
551 }
552 else if (strcasecmp (attributes[i], "apacheSuexecGid") == 0) {
b5043ccb 553 reqc->gid = apr_pstrdup(r->pool, vals[i]);
7f9875bb
OS
554 }
555 i++;
556 }
557 }
558
6f705808
OS
559 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
560 "[mod_vhost_ldap.c]: loaded from ldap: "
561 "apacheServerName: %s, "
562 "apacheServerAdmin: %s, "
563 "apacheDocumentRoot: %s, "
564 "apacheScriptAlias: %s, "
565 "apacheSuexecUid: %s, "
b5043ccb
OS
566 "apacheSuexecGid: %s",
567 reqc->name, reqc->admin, reqc->docroot, reqc->cgiroot, reqc->uid, reqc->gid);
6f705808 568
b5043ccb 569 if ((reqc->name == NULL)||(reqc->docroot == NULL)) {
7f9875bb
OS
570 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
571 "[mod_vhost_ldap.c] translate: "
572 "translate failed; ServerName or DocumentRoot not defined");
573 return DECLINED;
574 }
575
576 cgi = NULL;
577
b5043ccb 578 if (reqc->cgiroot) {
6f705808
OS
579 cgi = strstr(r->uri, "cgi-bin/");
580 if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
7f9875bb
OS
581 cgi = NULL;
582 }
9ee2dda1 583 }
9ee2dda1 584 if (cgi) {
b5043ccb 585 r->filename = apr_pstrcat (r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL);
9ee2dda1
OS
586 r->handler = "cgi-script";
587 apr_table_setn(r->notes, "alias-forced-type", r->handler);
6f705808 588 } else if (r->uri[0] == '/') {
b5043ccb 589 r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL);
9ee2dda1 590 } else {
6f705808 591 return DECLINED;
7f9875bb
OS
592 }
593
9965ff97
AK
594 if ((r->server = apr_pmemdup(r->pool, r->server,
595 sizeof(*r->server))) == NULL)
596 return HTTP_INTERNAL_SERVER_ERROR;
597
598 r->server->server_hostname = reqc->name;
7f9875bb 599
b5043ccb 600 if (reqc->admin) {
9965ff97 601 r->server->server_admin = reqc->admin;
7f9875bb
OS
602 }
603
604 // set environment variables
9965ff97 605 e = r->subprocess_env;
b5043ccb 606 apr_table_addn (e, "SERVER_ROOT", reqc->docroot);
7f9875bb 607
9965ff97
AK
608 if ((r->server->module_config =
609 apr_pmemdup(r->pool, r->server->module_config,
610 sizeof(void *) *
611 (total_modules + DYNAMIC_MODULE_LIMIT))) == NULL)
612 return HTTP_INTERNAL_SERVER_ERROR;
613
614 if ((core = apr_pmemdup(r->pool, core, sizeof(*core))) == NULL)
615 return HTTP_INTERNAL_SERVER_ERROR;
616 ap_set_module_config(r->server->module_config, &core_module, core);
617
618 core->ap_document_root = reqc->docroot;
9ee2dda1 619
7f9875bb
OS
620 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
621 "[mod_vhost_ldap.c]: translated to %s", r->filename);
622
623 return OK;
624}
625
626#ifdef HAVE_UNIX_SUEXEC
627static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r)
628{
629 ap_unix_identity_t *ugid = NULL;
8196fae3 630 mod_vhost_ldap_config_t *conf =
7f9875bb
OS
631 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config,
632 &vhost_ldap_module);
633 mod_vhost_ldap_request_t *req =
634 (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config,
635 &vhost_ldap_module);
636
637 uid_t uid = -1;
638 gid_t gid = -1;
639
8196fae3
OS
640 // mod_vhost_ldap is disabled or we don't have LDAP Url
641 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
7f9875bb
OS
642 return NULL;
643 }
644
645 if ((req == NULL)||(req->uid == NULL)||(req->gid == NULL)) {
646 return NULL;
647 }
648
649 if ((ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL) {
650 return NULL;
651 }
652
653 uid = (uid_t)atoll(req->uid);
654 gid = (gid_t)atoll(req->gid);
655
eea38f6d 656 if ((uid < MIN_UID)||(gid < MIN_GID)) {
7f9875bb
OS
657 return NULL;
658 }
659
660 ugid->uid = uid;
661 ugid->gid = gid;
662 ugid->userdir = 0;
663
664 return ugid;
665}
666#endif
667
668static void
669mod_vhost_ldap_register_hooks (apr_pool_t * p)
670{
671 ap_hook_post_config(mod_vhost_ldap_post_config, NULL, NULL, APR_HOOK_MIDDLE);
672 ap_hook_translate_name(mod_vhost_ldap_translate_name, NULL, NULL, APR_HOOK_MIDDLE);
673#ifdef HAVE_UNIX_SUEXEC
674 ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE);
675#endif
8503d00b 676#if (APR_MAJOR_VERSION >= 1)
3b8a47e0
OS
677 ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
678#endif
7f9875bb
OS
679}
680
681module AP_MODULE_DECLARE_DATA vhost_ldap_module = {
682 STANDARD20_MODULE_STUFF,
683 NULL,
684 NULL,
685 mod_vhost_ldap_create_server_config,
8196fae3 686 mod_vhost_ldap_merge_server_config,
7f9875bb
OS
687 mod_vhost_ldap_cmds,
688 mod_vhost_ldap_register_hooks,
689};
This page took 0.172436 seconds and 5 git commands to generate.