1 /* ============================================================
2 * Copyright (c) 2003-2004, Ondrej Sury
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * mod_vhost_ldap.c --- read virtual host config from LDAP directory
28 #include "http_config.h"
29 #include "http_core.h"
31 #include "http_request.h"
32 #include "apr_version.h"
34 #include "apr_strings.h"
35 #include "apr_reslist.h"
36 #include "util_ldap.h"
38 #if !defined(APU_HAS_LDAP) && !defined(APR_HAS_LDAP)
39 #error mod_vhost_ldap requires APR-util to have LDAP support built in
42 #if !defined(WIN32) && !defined(OS2) && !defined(BEOS) && !defined(NETWARE)
43 #define HAVE_UNIX_SUEXEC
46 #ifdef HAVE_UNIX_SUEXEC
47 #include "unixd.h" /* Contains the suexec_identity hook used on Unix */
53 module AP_MODULE_DECLARE_DATA vhost_ldap_module;
56 MVL_UNSET, MVL_DISABLED, MVL_ENABLED
57 } mod_vhost_ldap_status_e;
59 typedef struct mod_vhost_ldap_config_t {
60 mod_vhost_ldap_status_e enabled; /* Is vhost_ldap enabled? */
62 /* These parameters are all derived from the VhostLDAPURL directive */
63 char *url; /* String representation of LDAP URL */
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 */
72 char *binddn; /* DN to bind to server (can be NULL) */
73 char *bindpw; /* Password to bind to server (can be NULL) */
75 int have_deref; /* Set if we have found an Deref option */
76 int have_ldap_url; /* Set if we have found an LDAP url */
78 int secure; /* True if SSL connections are requested */
80 char *fallback; /* Fallback virtual host */
82 } mod_vhost_ldap_config_t;
84 typedef 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 */
89 char *cgiroot; /* ScriptAlias */
90 char *uid; /* Suexec Uid */
91 char *gid; /* Suexec Gid */
92 char *saved_docroot; /* Saved DocumentRoot */
93 } mod_vhost_ldap_request_t;
96 { "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 };
98 #if (APR_MAJOR_VERSION >= 1)
99 static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
100 static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
101 static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
102 static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
103 static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid;
104 static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn;
105 static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported;
107 static void ImportULDAPOptFn(void)
109 util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
110 util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find);
111 util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
112 util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
113 util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
114 util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
115 util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
119 /* Taken from server/core.c */
120 static int set_document_root(request_rec *r, const char *arg)
122 void *sconf = r->server->module_config;
123 core_server_config *conf = ap_get_module_config(sconf, &core_module);
125 /* Make it absolute, relative to ServerRoot */
126 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
127 "[mod_vhost_ldap.c] set_document_root: translating DocumentRoot [%s]",
129 arg = ap_server_root_relative(r->pool, arg);
130 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
131 "[mod_vhost_ldap.c] set_document_root: relative DocumentRoot [%s]",
134 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
135 "[mod_vhost_ldap.c] set_document_root: DocumentRoot [%s] must be a directory",
138 return HTTP_INTERNAL_SERVER_ERROR;
141 /* TODO: ap_configtestonly && ap_docrootcheck && */
142 if (apr_filepath_merge((char**)&conf->ap_document_root, NULL, arg,
143 APR_FILEPATH_TRUENAME, r->pool) != APR_SUCCESS
144 || !ap_is_directory(r->pool, arg)) {
146 ap_log_rerror(APLOG_MARK, APLOG_STARTUP, 0,
148 "[mod_vhost_ldap.c] set_document_root: Warning: DocumentRoot [%s] does not exist",
150 conf->ap_document_root = arg;
156 static int mod_vhost_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
158 /* make sure that mod_ldap (util_ldap) is loaded */
159 if (ap_find_linked_module("util_ldap.c") == NULL) {
160 ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s,
161 "Module mod_ldap missing. Mod_ldap (aka. util_ldap) "
162 "must be loaded in order for mod_vhost_ldap to function properly");
163 return HTTP_INTERNAL_SERVER_ERROR;
167 ap_add_version_component(p, MOD_VHOST_LDAP_VERSION);
173 mod_vhost_ldap_create_server_config (apr_pool_t *p, server_rec *s)
175 mod_vhost_ldap_config_t *conf =
176 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof (mod_vhost_ldap_config_t));
178 conf->enabled = MVL_UNSET;
179 conf->have_ldap_url = 0;
180 conf->have_deref = 0;
183 conf->deref = always;
184 conf->fallback = NULL;
190 mod_vhost_ldap_merge_server_config(apr_pool_t *p, void *parentv, void *childv)
192 mod_vhost_ldap_config_t *parent = (mod_vhost_ldap_config_t *) parentv;
193 mod_vhost_ldap_config_t *child = (mod_vhost_ldap_config_t *) childv;
194 mod_vhost_ldap_config_t *conf =
195 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof(mod_vhost_ldap_config_t));
197 if (child->enabled == MVL_UNSET) {
198 conf->enabled = parent->enabled;
200 conf->enabled = child->enabled;
203 if (child->have_ldap_url) {
204 conf->have_ldap_url = child->have_ldap_url;
205 conf->url = child->url;
206 conf->host = child->host;
207 conf->port = child->port;
208 conf->basedn = child->basedn;
209 conf->scope = child->scope;
210 conf->filter = child->filter;
211 conf->secure = child->secure;
213 conf->have_ldap_url = parent->have_ldap_url;
214 conf->url = parent->url;
215 conf->host = parent->host;
216 conf->port = parent->port;
217 conf->basedn = parent->basedn;
218 conf->scope = parent->scope;
219 conf->filter = parent->filter;
220 conf->secure = parent->secure;
222 if (child->have_deref) {
223 conf->have_deref = child->have_deref;
224 conf->deref = child->deref;
226 conf->have_deref = parent->have_deref;
227 conf->deref = parent->deref;
230 conf->binddn = (child->binddn ? child->binddn : parent->binddn);
231 conf->bindpw = (child->bindpw ? child->bindpw : parent->bindpw);
233 conf->fallback = (child->fallback ? child->fallback : parent->fallback);
239 * Use the ldap url parsing routines to break up the ldap url into
242 static const char *mod_vhost_ldap_parse_url(cmd_parms *cmd,
247 apr_ldap_url_desc_t *urld;
248 #if (APR_MAJOR_VERSION >= 1)
249 apr_ldap_err_t *result_err;
252 mod_vhost_ldap_config_t *conf =
253 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
256 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
257 cmd->server, "[mod_vhost_ldap.c] url parse: `%s'",
260 #if (APR_MAJOR_VERSION >= 1) /* for apache >= 2.2 */
261 result = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result_err));
262 if (result != LDAP_SUCCESS) {
263 return result_err->reason;
266 result = apr_ldap_url_parse(url, &(urld));
267 if (result != LDAP_SUCCESS) {
269 case LDAP_URL_ERR_NOTLDAP:
270 return "LDAP URL does not begin with ldap://";
271 case LDAP_URL_ERR_NODN:
272 return "LDAP URL does not have a DN";
273 case LDAP_URL_ERR_BADSCOPE:
274 return "LDAP URL has an invalid scope";
275 case LDAP_URL_ERR_MEM:
276 return "Out of memory parsing LDAP URL";
278 return "Could not parse LDAP URL";
282 conf->url = apr_pstrdup(cmd->pool, url);
284 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
285 cmd->server, "[mod_vhost_ldap.c] url parse: Host: %s", urld->lud_host);
286 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
287 cmd->server, "[mod_vhost_ldap.c] url parse: Port: %d", urld->lud_port);
288 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
289 cmd->server, "[mod_vhost_ldap.c] url parse: DN: %s", urld->lud_dn);
290 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
291 cmd->server, "[mod_vhost_ldap.c] url parse: attrib: %s", urld->lud_attrs? urld->lud_attrs[0] : "(null)");
292 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
293 cmd->server, "[mod_vhost_ldap.c] url parse: scope: %s",
294 (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" :
295 urld->lud_scope == LDAP_SCOPE_BASE? "base" :
296 urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown"));
297 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
298 cmd->server, "[mod_vhost_ldap.c] url parse: filter: %s", urld->lud_filter);
300 /* Set all the values, or at least some sane defaults */
302 char *p = apr_palloc(cmd->pool, strlen(conf->host) + strlen(urld->lud_host) + 2);
303 strcpy(p, urld->lud_host);
305 strcat(p, conf->host);
309 conf->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost";
311 conf->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
313 conf->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ?
314 LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE;
316 if (urld->lud_filter) {
317 if (urld->lud_filter[0] == '(') {
319 * Get rid of the surrounding parens; later on when generating the
320 * filter, they'll be put back.
322 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1);
323 conf->filter[strlen(conf->filter)-1] = '\0';
326 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter);
330 conf->filter = "objectClass=apacheConfig";
333 /* "ldaps" indicates secure ldap connections desired
335 if (strncasecmp(url, "ldaps", 5) == 0)
338 conf->port = urld->lud_port? urld->lud_port : LDAPS_PORT;
339 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
340 "LDAP: vhost_ldap using SSL connections");
345 conf->port = urld->lud_port? urld->lud_port : LDAP_PORT;
346 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
347 "LDAP: vhost_ldap not using SSL connections");
350 conf->have_ldap_url = 1;
351 #if (APR_MAJOR_VERSION < 1) /* free only required for older apr */
352 apr_ldap_free_urldesc(urld);
357 static const char *mod_vhost_ldap_set_enabled(cmd_parms *cmd, void *dummy, int enabled)
359 mod_vhost_ldap_config_t *conf =
360 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
363 conf->enabled = (enabled) ? MVL_ENABLED : MVL_DISABLED;
368 static const char *mod_vhost_ldap_set_binddn(cmd_parms *cmd, void *dummy, const char *binddn)
370 mod_vhost_ldap_config_t *conf =
371 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
374 conf->binddn = apr_pstrdup(cmd->pool, binddn);
378 static const char *mod_vhost_ldap_set_bindpw(cmd_parms *cmd, void *dummy, const char *bindpw)
380 mod_vhost_ldap_config_t *conf =
381 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
384 conf->bindpw = apr_pstrdup(cmd->pool, bindpw);
388 static const char *mod_vhost_ldap_set_deref(cmd_parms *cmd, void *dummy, const char *deref)
390 mod_vhost_ldap_config_t *conf =
391 (mod_vhost_ldap_config_t *)ap_get_module_config (cmd->server->module_config,
394 if (strcmp(deref, "never") == 0 || strcasecmp(deref, "off") == 0) {
396 conf->have_deref = 1;
398 else if (strcmp(deref, "searching") == 0) {
399 conf->deref = searching;
400 conf->have_deref = 1;
402 else if (strcmp(deref, "finding") == 0) {
403 conf->deref = finding;
404 conf->have_deref = 1;
406 else if (strcmp(deref, "always") == 0 || strcasecmp(deref, "on") == 0) {
407 conf->deref = always;
408 conf->have_deref = 1;
411 return "Unrecognized value for VhostLDAPAliasDereference directive";
416 static const char *mod_vhost_ldap_set_fallback(cmd_parms *cmd, void *dummy, const char *fallback)
418 mod_vhost_ldap_config_t *conf =
419 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
422 conf->fallback = apr_pstrdup(cmd->pool, fallback);
426 command_rec mod_vhost_ldap_cmds[] = {
427 AP_INIT_TAKE1("VhostLDAPURL", mod_vhost_ldap_parse_url, NULL, RSRC_CONF,
428 "URL to define LDAP connection. This should be an RFC 2255 compliant\n"
429 "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n"
431 "<li>Host is the name of the LDAP server. Use a space separated list of hosts \n"
432 "to specify redundant servers.\n"
433 "<li>Port is optional, and specifies the port to connect to.\n"
434 "<li>basedn specifies the base DN to start searches from\n"
437 AP_INIT_TAKE1 ("VhostLDAPBindDN", mod_vhost_ldap_set_binddn, NULL, RSRC_CONF,
438 "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."),
440 AP_INIT_TAKE1("VhostLDAPBindPassword", mod_vhost_ldap_set_bindpw, NULL, RSRC_CONF,
441 "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."),
443 AP_INIT_FLAG("VhostLDAPEnabled", mod_vhost_ldap_set_enabled, NULL, RSRC_CONF,
444 "Set to off to disable vhost_ldap, even if it's been enabled in a higher tree"),
446 AP_INIT_TAKE1("VhostLDAPDereferenceAliases", mod_vhost_ldap_set_deref, NULL, RSRC_CONF,
447 "Determines how aliases are handled during a search. Can be one of the"
448 "values \"never\", \"searching\", \"finding\", or \"always\". "
449 "Defaults to always."),
451 AP_INIT_TAKE1("VhostLDAPFallback", mod_vhost_ldap_set_fallback, NULL, RSRC_CONF,
452 "Set default virtual host which will be used when requested hostname"
453 "is not found in LDAP database. This option can be used to display"
454 "\"virtual host not found\" type of page."),
459 #define FILTER_LENGTH MAX_STRING_LEN
460 static int mod_vhost_ldap_translate_name(request_rec *r)
462 request_rec *top = (r->main)?r->main:r;
463 mod_vhost_ldap_request_t *reqc;
466 const char **vals = NULL;
467 char filtbuf[FILTER_LENGTH];
468 mod_vhost_ldap_config_t *conf =
469 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_module);
470 util_ldap_connection_t *ldc = NULL;
472 const char *dn = NULL;
474 const char *hostname = NULL;
478 (mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t));
479 memset(reqc, 0, sizeof(mod_vhost_ldap_request_t));
481 ap_set_module_config(r->request_config, &vhost_ldap_module, reqc);
483 // mod_vhost_ldap is disabled or we don't have LDAP Url
484 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
491 ldc = util_ldap_connection_find(r, conf->host, conf->port,
492 conf->binddn, conf->bindpw, conf->deref,
496 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
497 "[mod_vhost_ldap.c] translate: no conf->host - weird...?");
498 return HTTP_INTERNAL_SERVER_ERROR;
501 hostname = r->hostname;
505 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
506 "[mod_vhost_ldap.c]: translating %s", r->uri);
508 apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname);
510 result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope,
511 attributes, filtbuf, &dn, &vals);
513 util_ldap_connection_close(ldc);
515 /* sanity check - if server is down, retry it up to 5 times */
516 if (result == LDAP_SERVER_DOWN) {
517 if (failures++ <= 5) {
520 return HTTP_GATEWAY_TIME_OUT;
524 if (result == LDAP_NO_SUCH_OBJECT) {
525 if (conf->fallback && (is_fallback++ <= 0)) {
526 ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r,
527 "[mod_vhost_ldap.c] translate: "
528 "virtual host %s not found, trying fallback %s",
529 hostname, conf->fallback);
530 hostname = conf->fallback;
534 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
535 "[mod_vhost_ldap.c] translate: "
536 "virtual host %s not found",
539 return HTTP_BAD_REQUEST;
542 /* handle bind failure */
543 if (result != LDAP_SUCCESS) {
544 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
545 "[mod_vhost_ldap.c] translate: "
546 "translate failed; virtual host %s; URI %s [%s]",
547 hostname, r->uri, ldap_err2string(result));
548 return HTTP_INTERNAL_SERVER_ERROR;
551 /* mark the user and DN */
552 reqc->dn = apr_pstrdup(r->pool, dn);
557 while (attributes[i]) {
559 if (strcasecmp (attributes[i], "apacheServerName") == 0) {
560 reqc->name = apr_pstrdup (r->pool, vals[i]);
562 else if (strcasecmp (attributes[i], "apacheServerAdmin") == 0) {
563 reqc->admin = apr_pstrdup (r->pool, vals[i]);
565 else if (strcasecmp (attributes[i], "apacheDocumentRoot") == 0) {
566 reqc->docroot = apr_pstrdup (r->pool, vals[i]);
568 else if (strcasecmp (attributes[i], "apacheScriptAlias") == 0) {
569 reqc->cgiroot = apr_pstrdup (r->pool, vals[i]);
571 else if (strcasecmp (attributes[i], "apacheSuexecUid") == 0) {
572 reqc->uid = apr_pstrdup(r->pool, vals[i]);
574 else if (strcasecmp (attributes[i], "apacheSuexecGid") == 0) {
575 reqc->gid = apr_pstrdup(r->pool, vals[i]);
581 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
582 "[mod_vhost_ldap.c]: loaded from ldap: "
583 "apacheServerName: %s, "
584 "apacheServerAdmin: %s, "
585 "apacheDocumentRoot: %s, "
586 "apacheScriptAlias: %s, "
587 "apacheSuexecUid: %s, "
588 "apacheSuexecGid: %s",
589 reqc->name, reqc->admin, reqc->docroot, reqc->cgiroot, reqc->uid, reqc->gid);
591 if ((reqc->name == NULL)||(reqc->docroot == NULL)) {
592 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
593 "[mod_vhost_ldap.c] translate: "
594 "translate failed; ServerName or DocumentRoot not defined");
595 return HTTP_INTERNAL_SERVER_ERROR;
601 cgi = strstr(r->uri, "cgi-bin/");
602 if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
607 cgi = apr_pstrcat (r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL);
608 if ((cgi = ap_server_root_relative(r->pool, cgi))) {
609 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
610 "[mod_vhost_ldap.c]: ap_document_root is: %s", ap_document_root(r));
612 r->handler = "cgi-script";
613 apr_table_setn(r->notes, "alias-forced-type", r->handler);
615 } else if (r->uri[0] == '/') {
616 /* r->filename = apr_pstrdup(r->pool, r->uri); */
617 /* r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL); */
622 top->server->server_hostname = apr_pstrdup (top->pool, reqc->name);
625 top->server->server_admin = apr_pstrdup (top->pool, reqc->admin);
628 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
629 "[mod_vhost_ldap.c]: ap_server_root_relative(%s) is: %s", apr_pstrcat(r->pool, reqc->docroot, r->uri), ap_server_root_relative(r->pool, r->filename));
631 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
632 "[mod_vhost_ldap.c]: ap_document_root is: %s", ap_document_root(r));
634 reqc->saved_docroot = apr_pstrdup(top->pool, ap_document_root(r));
636 if (set_document_root(r, reqc->docroot) != OK)
637 return HTTP_INTERNAL_SERVER_ERROR;
639 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
640 "[mod_vhost_ldap.c]: ap_document_root set to: %s", ap_document_root(r));
642 // set environment variables
643 e = top->subprocess_env;
644 apr_table_addn (e, "SERVER_ROOT", reqc->docroot);
645 apr_table_addn (e, "DOCUMENT_ROOT", reqc->docroot);
647 /* Hack to allow post-processing by other modules (mod_rewrite, mod_alias) */
651 static int mod_vhost_ldap_cleanup(request_rec * r)
653 mod_vhost_ldap_request_t *reqc =
654 (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config,
657 if (set_document_root(r, reqc->saved_docroot) != OK)
658 return HTTP_INTERNAL_SERVER_ERROR;
660 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
661 "[mod_vhost_ldap.c]: ap_document_root restored to: %s", ap_document_root(r));
666 #ifdef HAVE_UNIX_SUEXEC
667 static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r)
669 ap_unix_identity_t *ugid = NULL;
670 mod_vhost_ldap_config_t *conf =
671 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config,
673 mod_vhost_ldap_request_t *req =
674 (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config,
680 // mod_vhost_ldap is disabled or we don't have LDAP Url
681 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
685 if ((req == NULL)||(req->uid == NULL)||(req->gid == NULL)) {
689 if ((ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL) {
693 uid = (uid_t)atoll(req->uid);
694 gid = (gid_t)atoll(req->gid);
696 if ((uid < MIN_UID)||(gid < MIN_GID)) {
709 mod_vhost_ldap_register_hooks (apr_pool_t * p)
713 * Run before mod_rewrite
715 static const char * const aszRewrite[]={ "mod_rewrite.c", NULL };
717 ap_hook_post_config(mod_vhost_ldap_post_config, NULL, NULL, APR_HOOK_MIDDLE);
718 ap_hook_translate_name(mod_vhost_ldap_translate_name, NULL, aszRewrite, APR_HOOK_FIRST);
719 ap_hook_fixups(mod_vhost_ldap_cleanup, aszRewrite, NULL, APR_HOOK_MIDDLE);
720 #ifdef HAVE_UNIX_SUEXEC
721 ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE);
723 #if (APR_MAJOR_VERSION >= 1)
724 ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
728 module AP_MODULE_DECLARE_DATA vhost_ldap_module = {
729 STANDARD20_MODULE_STUFF,
732 mod_vhost_ldap_create_server_config,
733 mod_vhost_ldap_merge_server_config,
735 mod_vhost_ldap_register_hooks,