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_reslist.h"
35 #include "apr_strings.h"
36 #include "apr_tables.h"
37 #include "util_ldap.h"
38 #include "util_script.h"
40 #if !defined(APU_HAS_LDAP) && !defined(APR_HAS_LDAP)
41 #error mod_vhost_ldap requires APR-util to have LDAP support built in
44 #if !defined(WIN32) && !defined(OS2) && !defined(BEOS) && !defined(NETWARE)
45 #define HAVE_UNIX_SUEXEC
48 #ifdef HAVE_UNIX_SUEXEC
49 #include "unixd.h" /* Contains the suexec_identity hook used on Unix */
55 #define MAX_FAILURES 5
57 module AP_MODULE_DECLARE_DATA vhost_ldap_module;
60 MVL_UNSET, MVL_DISABLED, MVL_ENABLED
61 } mod_vhost_ldap_status_e;
63 typedef struct mod_vhost_ldap_config_t {
64 mod_vhost_ldap_status_e enabled; /* Is vhost_ldap enabled? */
66 /* These parameters are all derived from the VhostLDAPURL directive */
67 char *url; /* String representation of LDAP URL */
69 char *host; /* Name of the LDAP server (or space separated list) */
70 int port; /* Port of the LDAP server */
71 char *basedn; /* Base DN to do all searches from */
72 int scope; /* Scope of the search */
73 char *filter; /* Filter to further limit the search */
74 deref_options deref; /* how to handle alias dereferening */
76 char *binddn; /* DN to bind to server (can be NULL) */
77 char *bindpw; /* Password to bind to server (can be NULL) */
79 int have_deref; /* Set if we have found an Deref option */
80 int have_ldap_url; /* Set if we have found an LDAP url */
82 int secure; /* True if SSL connections are requested */
84 char *fallback; /* Fallback virtual host */
86 } mod_vhost_ldap_config_t;
88 typedef struct mod_vhost_ldap_request_t {
89 char *dn; /* The saved dn from a successful search */
90 char *name; /* ServerName */
91 char *admin; /* ServerAdmin */
92 char *docroot; /* DocumentRoot */
93 char *cgiroot; /* ScriptAlias */
94 char *uid; /* Suexec Uid */
95 char *gid; /* Suexec Gid */
96 } mod_vhost_ldap_request_t;
99 { "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 };
101 static int total_modules;
103 #if (APR_MAJOR_VERSION >= 1)
104 static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
105 static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
106 static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
107 static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
108 static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid;
109 static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn;
110 static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported;
112 static void ImportULDAPOptFn(void)
114 util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
115 util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find);
116 util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
117 util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
118 util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
119 util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
120 util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
124 static int mod_vhost_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
128 /* Stolen from modules/generators/mod_cgid.c */
130 for (m = ap_preloaded_modules; *m != NULL; m++)
133 /* make sure that mod_ldap (util_ldap) is loaded */
134 if (ap_find_linked_module("util_ldap.c") == NULL) {
135 ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s,
136 "Module mod_ldap missing. Mod_ldap (aka. util_ldap) "
137 "must be loaded in order for mod_vhost_ldap to function properly");
138 return HTTP_INTERNAL_SERVER_ERROR;
142 ap_add_version_component(p, MOD_VHOST_LDAP_VERSION);
148 mod_vhost_ldap_create_server_config (apr_pool_t *p, server_rec *s)
150 mod_vhost_ldap_config_t *conf =
151 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof (mod_vhost_ldap_config_t));
153 conf->enabled = MVL_UNSET;
154 conf->have_ldap_url = 0;
155 conf->have_deref = 0;
158 conf->deref = always;
159 conf->fallback = NULL;
165 mod_vhost_ldap_merge_server_config(apr_pool_t *p, void *parentv, void *childv)
167 mod_vhost_ldap_config_t *parent = (mod_vhost_ldap_config_t *) parentv;
168 mod_vhost_ldap_config_t *child = (mod_vhost_ldap_config_t *) childv;
169 mod_vhost_ldap_config_t *conf =
170 (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof(mod_vhost_ldap_config_t));
172 if (child->enabled == MVL_UNSET) {
173 conf->enabled = parent->enabled;
175 conf->enabled = child->enabled;
178 if (child->have_ldap_url) {
179 conf->have_ldap_url = child->have_ldap_url;
180 conf->url = child->url;
181 conf->host = child->host;
182 conf->port = child->port;
183 conf->basedn = child->basedn;
184 conf->scope = child->scope;
185 conf->filter = child->filter;
186 conf->secure = child->secure;
188 conf->have_ldap_url = parent->have_ldap_url;
189 conf->url = parent->url;
190 conf->host = parent->host;
191 conf->port = parent->port;
192 conf->basedn = parent->basedn;
193 conf->scope = parent->scope;
194 conf->filter = parent->filter;
195 conf->secure = parent->secure;
197 if (child->have_deref) {
198 conf->have_deref = child->have_deref;
199 conf->deref = child->deref;
201 conf->have_deref = parent->have_deref;
202 conf->deref = parent->deref;
205 conf->binddn = (child->binddn ? child->binddn : parent->binddn);
206 conf->bindpw = (child->bindpw ? child->bindpw : parent->bindpw);
208 conf->fallback = (child->fallback ? child->fallback : parent->fallback);
214 * Use the ldap url parsing routines to break up the ldap url into
217 static const char *mod_vhost_ldap_parse_url(cmd_parms *cmd,
222 apr_ldap_url_desc_t *urld;
223 #if (APR_MAJOR_VERSION >= 1)
224 apr_ldap_err_t *result_err;
227 mod_vhost_ldap_config_t *conf =
228 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
231 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
232 cmd->server, "[mod_vhost_ldap.c] url parse: `%s'",
235 #if (APR_MAJOR_VERSION >= 1) /* for apache >= 2.2 */
236 result = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result_err));
237 if (result != LDAP_SUCCESS) {
238 return result_err->reason;
241 result = apr_ldap_url_parse(url, &(urld));
242 if (result != LDAP_SUCCESS) {
244 case LDAP_URL_ERR_NOTLDAP:
245 return "LDAP URL does not begin with ldap://";
246 case LDAP_URL_ERR_NODN:
247 return "LDAP URL does not have a DN";
248 case LDAP_URL_ERR_BADSCOPE:
249 return "LDAP URL has an invalid scope";
250 case LDAP_URL_ERR_MEM:
251 return "Out of memory parsing LDAP URL";
253 return "Could not parse LDAP URL";
257 conf->url = apr_pstrdup(cmd->pool, url);
259 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
260 cmd->server, "[mod_vhost_ldap.c] url parse: Host: %s", urld->lud_host);
261 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
262 cmd->server, "[mod_vhost_ldap.c] url parse: Port: %d", urld->lud_port);
263 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
264 cmd->server, "[mod_vhost_ldap.c] url parse: DN: %s", urld->lud_dn);
265 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
266 cmd->server, "[mod_vhost_ldap.c] url parse: attrib: %s", urld->lud_attrs? urld->lud_attrs[0] : "(null)");
267 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
268 cmd->server, "[mod_vhost_ldap.c] url parse: scope: %s",
269 (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" :
270 urld->lud_scope == LDAP_SCOPE_BASE? "base" :
271 urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown"));
272 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0,
273 cmd->server, "[mod_vhost_ldap.c] url parse: filter: %s", urld->lud_filter);
275 /* Set all the values, or at least some sane defaults */
277 char *p = apr_palloc(cmd->pool, strlen(conf->host) + strlen(urld->lud_host) + 2);
278 strcpy(p, urld->lud_host);
280 strcat(p, conf->host);
284 conf->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost";
286 conf->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
288 conf->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ?
289 LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE;
291 if (urld->lud_filter) {
292 if (urld->lud_filter[0] == '(') {
294 * Get rid of the surrounding parens; later on when generating the
295 * filter, they'll be put back.
297 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1);
298 conf->filter[strlen(conf->filter)-1] = '\0';
301 conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter);
305 conf->filter = "objectClass=apacheConfig";
308 /* "ldaps" indicates secure ldap connections desired
310 if (strncasecmp(url, "ldaps", 5) == 0)
313 conf->port = urld->lud_port? urld->lud_port : LDAPS_PORT;
314 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
315 "LDAP: vhost_ldap using SSL connections");
320 conf->port = urld->lud_port? urld->lud_port : LDAP_PORT;
321 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server,
322 "LDAP: vhost_ldap not using SSL connections");
325 conf->have_ldap_url = 1;
326 #if (APR_MAJOR_VERSION < 1) /* free only required for older apr */
327 apr_ldap_free_urldesc(urld);
332 static const char *mod_vhost_ldap_set_enabled(cmd_parms *cmd, void *dummy, int enabled)
334 mod_vhost_ldap_config_t *conf =
335 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
338 conf->enabled = (enabled) ? MVL_ENABLED : MVL_DISABLED;
343 static const char *mod_vhost_ldap_set_binddn(cmd_parms *cmd, void *dummy, const char *binddn)
345 mod_vhost_ldap_config_t *conf =
346 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
349 conf->binddn = apr_pstrdup(cmd->pool, binddn);
353 static const char *mod_vhost_ldap_set_bindpw(cmd_parms *cmd, void *dummy, const char *bindpw)
355 mod_vhost_ldap_config_t *conf =
356 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
359 conf->bindpw = apr_pstrdup(cmd->pool, bindpw);
363 static const char *mod_vhost_ldap_set_deref(cmd_parms *cmd, void *dummy, const char *deref)
365 mod_vhost_ldap_config_t *conf =
366 (mod_vhost_ldap_config_t *)ap_get_module_config (cmd->server->module_config,
369 if (strcmp(deref, "never") == 0 || strcasecmp(deref, "off") == 0) {
371 conf->have_deref = 1;
373 else if (strcmp(deref, "searching") == 0) {
374 conf->deref = searching;
375 conf->have_deref = 1;
377 else if (strcmp(deref, "finding") == 0) {
378 conf->deref = finding;
379 conf->have_deref = 1;
381 else if (strcmp(deref, "always") == 0 || strcasecmp(deref, "on") == 0) {
382 conf->deref = always;
383 conf->have_deref = 1;
386 return "Unrecognized value for VhostLDAPAliasDereference directive";
391 static const char *mod_vhost_ldap_set_fallback(cmd_parms *cmd, void *dummy, const char *fallback)
393 mod_vhost_ldap_config_t *conf =
394 (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config,
397 conf->fallback = apr_pstrdup(cmd->pool, fallback);
401 command_rec mod_vhost_ldap_cmds[] = {
402 AP_INIT_TAKE1("VhostLDAPURL", mod_vhost_ldap_parse_url, NULL, RSRC_CONF,
403 "URL to define LDAP connection. This should be an RFC 2255 compliant\n"
404 "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n"
406 "<li>Host is the name of the LDAP server. Use a space separated list of hosts \n"
407 "to specify redundant servers.\n"
408 "<li>Port is optional, and specifies the port to connect to.\n"
409 "<li>basedn specifies the base DN to start searches from\n"
412 AP_INIT_TAKE1 ("VhostLDAPBindDN", mod_vhost_ldap_set_binddn, NULL, RSRC_CONF,
413 "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."),
415 AP_INIT_TAKE1("VhostLDAPBindPassword", mod_vhost_ldap_set_bindpw, NULL, RSRC_CONF,
416 "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."),
418 AP_INIT_FLAG("VhostLDAPEnabled", mod_vhost_ldap_set_enabled, NULL, RSRC_CONF,
419 "Set to off to disable vhost_ldap, even if it's been enabled in a higher tree"),
421 AP_INIT_TAKE1("VhostLDAPDereferenceAliases", mod_vhost_ldap_set_deref, NULL, RSRC_CONF,
422 "Determines how aliases are handled during a search. Can be one of the"
423 "values \"never\", \"searching\", \"finding\", or \"always\". "
424 "Defaults to always."),
426 AP_INIT_TAKE1("VhostLDAPFallback", mod_vhost_ldap_set_fallback, NULL, RSRC_CONF,
427 "Set default virtual host which will be used when requested hostname"
428 "is not found in LDAP database. This option can be used to display"
429 "\"virtual host not found\" type of page."),
434 #define FILTER_LENGTH MAX_STRING_LEN
435 static int mod_vhost_ldap_translate_name(request_rec *r)
437 mod_vhost_ldap_request_t *reqc;
439 const char **vals = NULL;
440 char filtbuf[FILTER_LENGTH];
441 mod_vhost_ldap_config_t *conf =
442 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_module);
443 core_server_config *core =
444 (core_server_config *)ap_get_module_config(r->server->module_config, &core_module);
445 util_ldap_connection_t *ldc = NULL;
447 const char *dn = NULL;
449 const char *hostname = NULL;
454 struct berval hostnamebv, shostnamebv;
457 (mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t));
458 memset(reqc, 0, sizeof(mod_vhost_ldap_request_t));
460 ap_set_module_config(r->request_config, &vhost_ldap_module, reqc);
462 // mod_vhost_ldap is disabled or we don't have LDAP Url
463 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
470 ldc = util_ldap_connection_find(r, conf->host, conf->port,
471 conf->binddn, conf->bindpw, conf->deref,
475 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
476 "[mod_vhost_ldap.c] translate: no conf->host - weird...?");
477 return HTTP_INTERNAL_SERVER_ERROR;
480 hostname = r->hostname;
481 if (hostname == NULL || hostname[0] == '\0')
486 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
487 "[mod_vhost_ldap.c]: translating hostname [%s], uri [%s]",
490 ber_str2bv(hostname, 0, 0, &hostnamebv);
491 if (ldap_bv2escaped_filter_value(&hostnamebv, &shostnamebv) != 0)
493 apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, shostnamebv.bv_val, shostnamebv.bv_val);
494 ber_memfree(shostnamebv.bv_val);
496 result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope,
497 attributes, filtbuf, &dn, &vals);
499 util_ldap_connection_close(ldc);
501 /* sanity check - if server is down, retry it up to 5 times */
502 if (AP_LDAP_IS_SERVER_DOWN(result) ||
503 (result == LDAP_TIMEOUT) ||
504 (result == LDAP_CONNECT_ERROR)) {
505 sleep = sleep0 + sleep1;
506 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
507 "[mod_vhost_ldap.c]: lookup failure, retry number #[%d], sleeping for [%d] seconds",
509 if (failures++ < MAX_FAILURES) {
510 /* Back-off exponentially */
511 apr_sleep(apr_time_from_sec(sleep));
516 return HTTP_GATEWAY_TIME_OUT;
520 if (result == LDAP_NO_SUCH_OBJECT) {
521 if (strcmp(hostname, "*") != 0) {
522 if (strncmp(hostname, "*.", 2) == 0)
524 hostname += strcspn(hostname, ".");
525 hostname = apr_pstrcat(r->pool, "*", hostname, NULL);
526 ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r,
527 "[mod_vhost_ldap.c] translate: "
528 "virtual host not found, trying wildcard %s",
534 if (conf->fallback && (is_fallback++ <= 0)) {
535 ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r,
536 "[mod_vhost_ldap.c] translate: "
537 "virtual host %s not found, trying fallback %s",
538 hostname, conf->fallback);
539 hostname = conf->fallback;
543 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
544 "[mod_vhost_ldap.c] translate: "
545 "virtual host %s not found",
548 return HTTP_BAD_REQUEST;
551 /* handle bind failure */
552 if (result != LDAP_SUCCESS) {
553 ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,
554 "[mod_vhost_ldap.c] translate: "
555 "translate failed; virtual host %s; URI %s [%s]",
556 hostname, r->uri, ldap_err2string(result));
557 return HTTP_INTERNAL_SERVER_ERROR;
560 /* mark the user and DN */
561 reqc->dn = apr_pstrdup(r->pool, dn);
566 while (attributes[i]) {
568 if (strcasecmp (attributes[i], "apacheServerName") == 0) {
569 reqc->name = apr_pstrdup (r->pool, vals[i]);
571 else if (strcasecmp (attributes[i], "apacheServerAdmin") == 0) {
572 reqc->admin = apr_pstrdup (r->pool, vals[i]);
574 else if (strcasecmp (attributes[i], "apacheDocumentRoot") == 0) {
575 reqc->docroot = apr_pstrdup (r->pool, vals[i]);
577 else if (strcasecmp (attributes[i], "apacheScriptAlias") == 0) {
578 reqc->cgiroot = apr_pstrdup (r->pool, vals[i]);
580 else if (strcasecmp (attributes[i], "apacheSuexecUid") == 0) {
581 reqc->uid = apr_pstrdup(r->pool, vals[i]);
583 else if (strcasecmp (attributes[i], "apacheSuexecGid") == 0) {
584 reqc->gid = apr_pstrdup(r->pool, vals[i]);
590 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
591 "[mod_vhost_ldap.c]: loaded from ldap: "
592 "apacheServerName: %s, "
593 "apacheServerAdmin: %s, "
594 "apacheDocumentRoot: %s, "
595 "apacheScriptAlias: %s, "
596 "apacheSuexecUid: %s, "
597 "apacheSuexecGid: %s",
598 reqc->name, reqc->admin, reqc->docroot, reqc->cgiroot, reqc->uid, reqc->gid);
600 if ((reqc->name == NULL)||(reqc->docroot == NULL)) {
601 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
602 "[mod_vhost_ldap.c] translate: "
603 "translate failed; ServerName or DocumentRoot not defined");
604 return HTTP_INTERNAL_SERVER_ERROR;
610 cgi = strstr(r->uri, "cgi-bin/");
611 if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) {
616 /* Set exact filename for CGI script */
617 cgi = apr_pstrcat(r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL);
618 if ((cgi = ap_server_root_relative(r->pool, cgi))) {
619 ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
620 "[mod_vhost_ldap.c]: ap_document_root is: %s",
621 ap_document_root(r));
623 r->handler = "cgi-script";
624 apr_table_setn(r->notes, "alias-forced-type", r->handler);
626 } else if (r->uri[0] == '/') {
627 /* we don't set r->filename here, and let other modules do it
628 * this allows other modules (mod_rewrite.c) to work as usual
630 /* r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL); */
632 /* We don't handle non-file requests here */
636 if ((r->server = apr_pmemdup(r->pool, r->server, sizeof(*r->server))) == NULL) {
637 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
638 "[mod_vhost_ldap.c] translate: "
639 "translate failed; Unable to copy r->server structure");
640 return HTTP_INTERNAL_SERVER_ERROR;
643 r->server->server_hostname = reqc->name;
646 r->server->server_admin = reqc->admin;
649 if ((r->server->module_config = apr_pmemdup(r->pool, r->server->module_config,
651 (total_modules + DYNAMIC_MODULE_LIMIT))) == NULL) {
652 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
653 "[mod_vhost_ldap.c] translate: "
654 "translate failed; Unable to copy r->server->module_config structure");
655 return HTTP_INTERNAL_SERVER_ERROR;
658 if ((core = apr_pmemdup(r->pool, core, sizeof(*core))) == NULL) {
659 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
660 "[mod_vhost_ldap.c] translate: "
661 "translate failed; Unable to copy r->core structure");
662 return HTTP_INTERNAL_SERVER_ERROR;
664 ap_set_module_config(r->server->module_config, &core_module, core);
666 /* Stolen from server/core.c */
668 /* Make it absolute, relative to ServerRoot */
669 reqc->docroot = ap_server_root_relative(r->pool, reqc->docroot);
671 if (reqc->docroot == NULL) {
672 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
673 "[mod_vhost_ldap.c] set_document_root: DocumentRoot must be a directory");
675 return HTTP_INTERNAL_SERVER_ERROR;
678 /* TODO: ap_configtestonly && ap_docrootcheck && */
679 if (apr_filepath_merge((char**)&core->ap_document_root, NULL, reqc->docroot,
680 APR_FILEPATH_TRUENAME, r->pool) != APR_SUCCESS
681 || !ap_is_directory(r->pool, reqc->docroot)) {
683 ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
684 "[mod_vhost_ldap.c] set_document_root: Warning: DocumentRoot [%s] does not exist",
686 core->ap_document_root = reqc->docroot;
689 /* Hack to allow post-processing by other modules (mod_rewrite, mod_alias) */
693 #ifdef HAVE_UNIX_SUEXEC
694 static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r)
696 ap_unix_identity_t *ugid = NULL;
697 mod_vhost_ldap_config_t *conf =
698 (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config,
700 mod_vhost_ldap_request_t *req =
701 (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config,
707 // mod_vhost_ldap is disabled or we don't have LDAP Url
708 if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) {
712 if ((req == NULL)||(req->uid == NULL)||(req->gid == NULL)) {
716 if ((ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL) {
720 uid = (uid_t)atoll(req->uid);
721 gid = (gid_t)atoll(req->gid);
723 if ((uid < MIN_UID)||(gid < MIN_GID)) {
736 mod_vhost_ldap_register_hooks (apr_pool_t * p)
740 * Run before mod_rewrite
742 static const char * const aszRewrite[]={ "mod_rewrite.c", NULL };
744 ap_hook_post_config(mod_vhost_ldap_post_config, NULL, NULL, APR_HOOK_MIDDLE);
745 ap_hook_translate_name(mod_vhost_ldap_translate_name, NULL, aszRewrite, APR_HOOK_FIRST);
746 #ifdef HAVE_UNIX_SUEXEC
747 ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE);
749 #if (APR_MAJOR_VERSION >= 1)
750 ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
754 module AP_MODULE_DECLARE_DATA vhost_ldap_module = {
755 STANDARD20_MODULE_STUFF,
758 mod_vhost_ldap_create_server_config,
759 mod_vhost_ldap_merge_server_config,
761 mod_vhost_ldap_register_hooks,