pax_global_header00006660000000000000000000000064121677206120014516gustar00rootroot0000000000000052 comment=f6bb8d15b5ca5511ce983546ec935d8df16986aa mod-vhost-ldap-2.4.0/000077500000000000000000000000001216772061200143575ustar00rootroot00000000000000mod-vhost-ldap-2.4.0/AUTHORS000066400000000000000000000000401216772061200154210ustar00rootroot00000000000000Ondřej Surý mod-vhost-ldap-2.4.0/COPYING000066400000000000000000000011021216772061200154040ustar00rootroot00000000000000Copyright (c) 2005, Ondrej Sury All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mod-vhost-ldap-2.4.0/ChangeLog000066400000000000000000000103371216772061200161350ustar00rootroot000000000000002013-07-12 Ondřej Surý * VERSION: 2.4.0 * mod_vhost_ldap.c: Rely on ap_set_document_root() to set per request document root 2011-06-20 Ondřej Surý * VERSION: 2.0.8 * mod_vhost_ldap.c: Don't copy server struct if we have per request document root 2011-03-18 Ondřej Surý * VERSION: 2.0.7 * mod_vhost_ldap.c: Revert escaping wildcard character as it was already done before by ldap_bv2escaped_filter_value 2011-03-17 Ondřej Surý * VERSION: 2.0.6 * mod_vhost_ldap.c: Properly escape wildcard string to search for literal *.hostname * mod_vhost_ldap.c, vhost_ldap.conf: Add new boolean option VhostLDAPWildcard to disable wildcard search completely * mod_vhost_ldap.c: Fix cgi-bin processing (Courtesy of Anders Kaseorg) 2010-07-07 Ondřej Surý * VERSION: 2.0.5 * mod_vhost_ldap.c: Make a private copy of server config to each request to be thread safe. (Courtesy Anders Kaseorg) 2010-06-16 Ondřej Surý * VERSION: 2.0.3 * mod_vhost_ldap.c: Workaround concurrency issues with ap_document_root by adding mutex before it is set and release before handler is run. 2010-06-09 Ondřej Surý * VERSION: 2.0.1 * mod_vhost_ldap.c: Remove cleanup routine, it was causing segfaults. 2010-06-08 Ondřej Surý * VERSION: 2.0.0 release * mod_vhost_ldap.c: Sleep for (fibonacci numbers) seconds after LDAP failure * mod_vhost_ldap.c: Add a log WARNING when LDAP is unreachable * mod_vhost_ldap.c: Don't set r->filename, return DECLINE on success, only mangle documentroot and others, and let other apache modules handle real filenames * mod_vhost_ldap.c: Create and use function set_document_root inspired by apache2.2 * mod_vhost_ldap.c: Return correct error codes on failures and not DECLINED * mod_vhost_ldap.c: Put translate_name hook at FIRST place 2006-11-01 Ondřej Surý * VERSION: 1.2.0 release * mod_vhost_ldap.c: release apache-2.2 version as 1.2.0 2006-04-21 Bart Vanbrabant * VERSION: 1.0.1 release * mod_vhost_ldap.c: add support for apache-2.2.x 2006-01-30 Ondřej Surý * VERSION: 1.0.0 release * Fix small memory leak when used in subrequest (e.g. fastcgi) 2005-10-03 Ondřej Surý * mod_vhost_ldap.c: add support for running from subrequest (ie. mod_fastcgi) * VERSION: 0.2.9 release 2005-09-22 Ondřej Surý * mod_vhost_ldap.c: add support for Fallback Virtual Host * VERSION: 0.2.8 release 2005-09-19 Ondřej Surý * mod_vhost_ldap.c: add more information to log when vhost is not found * VERSION: 0.2.7 release 2005-09-16 Ondřej Surý * mod_vhost_ldap.c: implement merge_server_config to allow different settings for different vhosts * VERSION: 0.2.6 release 2005-09-09 Ondřej Surý * mod_vhost.ldap.c: implement workaround for fault mod_ldap caching http://issues.apache.org/bugzilla/show_bug.cgi?id=33901 * mod_vhost_ldap.c: change r->parsed_uri.path to more simpler r->uri * vhost_ldap.conf: add note about mod_ldap module requirement * VERSION: 0.2.5 release 2005-08-30 Ondřej Surý * mod_vhost_ldap.c: use VERSION file as authoritative source for VERSION number * mod_vhost_ldap.c: MIN_UID/MIN_GID lowered to 100/100 * VERSION: 0.2.4 release 2005-08-17 Ondřej Surý * Change off-by-one error in minimum UID/GID [courtesy of Fabian Fagerholm] * Fix LDAP schema (at last) [courtesy of Fabian Fagerholm] * Release 0.2.3 2005-08-16 Ondřej Surý * Works even without scriptAlias defined * Fixed schema, include apacheScriptAlias, change conflicting UIDs of attributes * DOCUMENT_ROOT variable is set correctly * Fixed some typos * Release 0.2.2 2005-08-02 Ondřej Surý * Complete rewrite... * Change apacheUsername to apacheSuexecUid and apacheSuexecGid 2005-05-25 Ondrej Sury * Version 0.2.0 * Renamed to mod_vhost_ldap * Add ScriptAlias * Add Suexec Username support mod-vhost-ldap-2.4.0/FILES000066400000000000000000000002201216772061200151360ustar00rootroot00000000000000AUTHORS vhost_ldap.conf ChangeLog COPYING INSTALL FILES Makefile mod_vhost_ldap.c mod_vhost_ldap.schema mod_vhost_ldap.spec README TODO VERSION mod-vhost-ldap-2.4.0/INSTALL000066400000000000000000000007441216772061200154150ustar00rootroot00000000000000Just run "make" to build the module and "make install" (as root) to install the module. This will use Apache's apxs to build/install from source. Have a look at vhost_ldap.conf to learn about configuration. Your LDAP server needs to include mod_vhost_ldap.schema. If you do not use OpenLDAP you are on your own to build a schema. You should configure the LDAP server to maintain indices on apacheServerName, apacheServerAlias and anything you use in your additional search filter. mod-vhost-ldap-2.4.0/Makefile000066400000000000000000000021731216772061200160220ustar00rootroot00000000000000APXS=apxs2 VERSION := $(shell cat VERSION) DISTFILES := $(shell cat FILES) TMPDIR := $(shell mktemp -d /tmp/mod-vhost-ldap.XXXXXXXX) all: mod_vhost_ldap.o install: $(APXS) -i mod_vhost_ldap.la clean: rm -f *.o rm -f *.lo rm -f *.la rm -f *.slo rm -rf .libs rm -rf mod_vhost_ldap-$(VERSION) rm -rf mod_vhost_ldap-$(VERSION).tar.gz mod_vhost_ldap.o: mod_vhost_ldap.c # Try building with per request document root and if it fails, do the normal build (kinda ugly, but should work) $(APXS) -Wc,-Wall -Wc,-Werror -Wc,-g -Wc,-DDEBUG -Wc,-DMOD_VHOST_LDAP_VERSION=\\\"mod_vhost_ldap/$(VERSION)\\\" -Wc,-DHAS_PER_REQUEST_DOCUMENT_ROOT -c -lldap_r mod_vhost_ldap.c || \ $(APXS) -Wc,-Wall -Wc,-Werror -Wc,-g -Wc,-DDEBUG -Wc,-DMOD_VHOST_LDAP_VERSION=\\\"mod_vhost_ldap/$(VERSION)\\\" -c -lldap_r mod_vhost_ldap.c archive: git clone $(CURDIR) $(TMPDIR)/mod-vhost-ldap-$(VERSION) cd $(TMPDIR)/mod-vhost-ldap-$(VERSION) && \ git checkout upstream cd $(TMPDIR) && \ tar --exclude-vcs --exclude debian/ -czf $(CURDIR)/../mod-vhost-ldap-$(VERSION).tar.gz mod-vhost-ldap-$(VERSION) format: indent *.c .PHONY: all install clean archive format mod-vhost-ldap-2.4.0/NEWS000066400000000000000000000007361216772061200150640ustar00rootroot000000000000002013-07-12 Ondřej Surý * 2.4.0: Add support for Apache 2.4, if you need mod_vhost_ldap for Apache 2.0 or 2.2, please use mod_vhost_ldap 2.0.8 2010-06-08 Ondřej Surý * 2.0.0: Big change in internal logic. mod_vhost_ldap doesn't lookup files and directories itself, but only mangle internal apache variables and let other modules do the work. This in turn allows other translate_name modules to work (namely mod_rewrite). mod-vhost-ldap-2.4.0/README000066400000000000000000000004701216772061200152400ustar00rootroot00000000000000 mod-vhost-ldap is Apache 2.x module for storing and configuring Virtual Hosts from LDAP. It supports DocumentRoot, ScriptAlias, ServerName, ServerAlias, ServerAdmin and SuexecUserGroup directives. . It's build on top of mod_ldap, so it uses it's caching capabilities and can be used with threaded apache. mod-vhost-ldap-2.4.0/TODO000066400000000000000000000000171216772061200150450ustar00rootroot00000000000000* Put back TLS mod-vhost-ldap-2.4.0/VERSION000066400000000000000000000000061216772061200154230ustar00rootroot000000000000002.4.0 mod-vhost-ldap-2.4.0/mod_vhost_ldap.c000066400000000000000000000622411216772061200175320ustar00rootroot00000000000000/* ============================================================ * Copyright (c) 2003-2004, Ondrej Sury * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* * mod_vhost_ldap.c --- read virtual host config from LDAP directory */ #define CORE_PRIVATE #include #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "http_request.h" #include "apr_version.h" #include "apr_ldap.h" #include "apr_reslist.h" #include "apr_strings.h" #include "apr_tables.h" #include "util_ldap.h" #include "util_script.h" #if !defined(APU_HAS_LDAP) && !defined(APR_HAS_LDAP) #error mod_vhost_ldap requires APR-util to have LDAP support built in #endif #if !AP_MODULE_MAGIC_AT_LEAST(20110605,0) #error mod_vhost_ldap 2.4 requires Apache 2.4 #endif #if !defined(WIN32) && !defined(OS2) && !defined(BEOS) && !defined(NETWARE) #define HAVE_UNIX_SUEXEC #endif #ifdef HAVE_UNIX_SUEXEC #include "unixd.h" /* Contains the suexec_identity hook used on Unix */ #endif #define MIN_UID 100 #define MIN_GID 100 #define MAX_FAILURES 5 module AP_MODULE_DECLARE_DATA vhost_ldap_module; typedef enum { MVL_UNSET, MVL_DISABLED, MVL_ENABLED } mod_vhost_ldap_status_e; typedef struct mod_vhost_ldap_config_t { mod_vhost_ldap_status_e enabled; /* Is vhost_ldap enabled? */ /* These parameters are all derived from the VhostLDAPURL directive */ char *url; /* String representation of LDAP URL */ char *host; /* Name of the LDAP server (or space separated list) */ int port; /* Port of the LDAP server */ char *basedn; /* Base DN to do all searches from */ int scope; /* Scope of the search */ char *filter; /* Filter to further limit the search */ deref_options deref; /* how to handle alias dereferening */ char *binddn; /* DN to bind to server (can be NULL) */ char *bindpw; /* Password to bind to server (can be NULL) */ int have_deref; /* Set if we have found an Deref option */ int have_ldap_url; /* Set if we have found an LDAP url */ int secure; /* True if SSL connections are requested */ char *fallback; /* Fallback virtual host */ int wildcard; /* Do wildcard search if host not found */ } mod_vhost_ldap_config_t; typedef struct mod_vhost_ldap_request_t { char *dn; /* The saved dn from a successful search */ char *name; /* ServerName */ char *admin; /* ServerAdmin */ char *docroot; /* DocumentRoot */ char *cgiroot; /* ScriptAlias */ char *uid; /* Suexec Uid */ char *gid; /* Suexec Gid */ } mod_vhost_ldap_request_t; char *attributes[] = { "apacheServerName", "apacheDocumentRoot", "apacheScriptAlias", "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", 0 }; static int total_modules; #if (APR_MAJOR_VERSION >= 1) static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close; static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find; static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn; static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare; static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid; static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn; static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported; static void ImportULDAPOptFn(void) { util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close); util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find); util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn); util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare); util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid); util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn); util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported); } #endif static int mod_vhost_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { module **m; /* Stolen from modules/generators/mod_cgid.c */ total_modules = 0; for (m = ap_preloaded_modules; *m != NULL; m++) total_modules++; /* make sure that mod_ldap (util_ldap) is loaded */ if (ap_find_linked_module("util_ldap.c") == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, s, "Module mod_ldap missing. Mod_ldap (aka. util_ldap) " "must be loaded in order for mod_vhost_ldap to function properly"); return HTTP_INTERNAL_SERVER_ERROR; } ap_add_version_component(p, MOD_VHOST_LDAP_VERSION); return OK; } static void * mod_vhost_ldap_create_server_config (apr_pool_t *p, server_rec *s) { mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof (mod_vhost_ldap_config_t)); conf->enabled = MVL_UNSET; conf->have_ldap_url = 0; conf->have_deref = 0; conf->binddn = NULL; conf->bindpw = NULL; conf->deref = always; conf->fallback = NULL; conf->wildcard = MVL_ENABLED; return conf; } static void * mod_vhost_ldap_merge_server_config(apr_pool_t *p, void *parentv, void *childv) { mod_vhost_ldap_config_t *parent = (mod_vhost_ldap_config_t *) parentv; mod_vhost_ldap_config_t *child = (mod_vhost_ldap_config_t *) childv; mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)apr_pcalloc(p, sizeof(mod_vhost_ldap_config_t)); conf->enabled = (child->enabled != MVL_UNSET) ? child->enabled : parent->enabled; if (child->have_ldap_url) { conf->have_ldap_url = child->have_ldap_url; conf->url = child->url; conf->host = child->host; conf->port = child->port; conf->basedn = child->basedn; conf->scope = child->scope; conf->filter = child->filter; conf->secure = child->secure; } else { conf->have_ldap_url = parent->have_ldap_url; conf->url = parent->url; conf->host = parent->host; conf->port = parent->port; conf->basedn = parent->basedn; conf->scope = parent->scope; conf->filter = parent->filter; conf->secure = parent->secure; } if (child->have_deref) { conf->have_deref = child->have_deref; conf->deref = child->deref; } else { conf->have_deref = parent->have_deref; conf->deref = parent->deref; } conf->binddn = (child->binddn ? child->binddn : parent->binddn); conf->bindpw = (child->bindpw ? child->bindpw : parent->bindpw); conf->fallback = (child->fallback ? child->fallback : parent->fallback); conf->wildcard = (child->wildcard != MVL_UNSET) ? child->wildcard : parent->wildcard; return conf; } /* * Use the ldap url parsing routines to break up the ldap url into * host and port. */ static const char *mod_vhost_ldap_parse_url(cmd_parms *cmd, void *dummy, const char *url) { int result; apr_ldap_url_desc_t *urld; #if (APR_MAJOR_VERSION >= 1) apr_ldap_err_t *result_err; #endif mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "[mod_vhost_ldap.c] url parse: `%s'", url); #if (APR_MAJOR_VERSION >= 1) /* for apache >= 2.2 */ result = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result_err)); if (result != LDAP_SUCCESS) { return result_err->reason; } #else result = apr_ldap_url_parse(url, &(urld)); if (result != LDAP_SUCCESS) { switch (result) { case LDAP_URL_ERR_NOTLDAP: return "LDAP URL does not begin with ldap://"; case LDAP_URL_ERR_NODN: return "LDAP URL does not have a DN"; case LDAP_URL_ERR_BADSCOPE: return "LDAP URL has an invalid scope"; case LDAP_URL_ERR_MEM: return "Out of memory parsing LDAP URL"; default: return "Could not parse LDAP URL"; } } #endif conf->url = apr_pstrdup(cmd->pool, url); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "[mod_vhost_ldap.c] url parse: Host: %s", urld->lud_host); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "[mod_vhost_ldap.c] url parse: Port: %d", urld->lud_port); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "[mod_vhost_ldap.c] url parse: DN: %s", urld->lud_dn); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "[mod_vhost_ldap.c] url parse: attrib: %s", urld->lud_attrs? urld->lud_attrs[0] : "(null)"); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "[mod_vhost_ldap.c] url parse: scope: %s", (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" : urld->lud_scope == LDAP_SCOPE_BASE? "base" : urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown")); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "[mod_vhost_ldap.c] url parse: filter: %s", urld->lud_filter); /* Set all the values, or at least some sane defaults */ if (conf->host) { char *p = apr_palloc(cmd->pool, strlen(conf->host) + strlen(urld->lud_host) + 2); strcpy(p, urld->lud_host); strcat(p, " "); strcat(p, conf->host); conf->host = p; } else { conf->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost"; } conf->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : ""; conf->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ? LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE; if (urld->lud_filter) { if (urld->lud_filter[0] == '(') { /* * Get rid of the surrounding parens; later on when generating the * filter, they'll be put back. */ conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1); conf->filter[strlen(conf->filter)-1] = '\0'; } else { conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter); } } else { conf->filter = "objectClass=apacheConfig"; } /* "ldaps" indicates secure ldap connections desired */ if (strncasecmp(url, "ldaps", 5) == 0) { conf->secure = 1; conf->port = urld->lud_port? urld->lud_port : LDAPS_PORT; ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "LDAP: vhost_ldap using SSL connections"); } else { conf->secure = 0; conf->port = urld->lud_port? urld->lud_port : LDAP_PORT; ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, "LDAP: vhost_ldap not using SSL connections"); } conf->have_ldap_url = 1; #if (APR_MAJOR_VERSION < 1) /* free only required for older apr */ apr_ldap_free_urldesc(urld); #endif return NULL; } static const char *mod_vhost_ldap_set_enabled(cmd_parms *cmd, void *dummy, int enabled) { mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); conf->enabled = (enabled) ? MVL_ENABLED : MVL_DISABLED; return NULL; } static const char *mod_vhost_ldap_set_binddn(cmd_parms *cmd, void *dummy, const char *binddn) { mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); conf->binddn = apr_pstrdup(cmd->pool, binddn); return NULL; } static const char *mod_vhost_ldap_set_bindpw(cmd_parms *cmd, void *dummy, const char *bindpw) { mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); conf->bindpw = apr_pstrdup(cmd->pool, bindpw); return NULL; } static const char *mod_vhost_ldap_set_deref(cmd_parms *cmd, void *dummy, const char *deref) { mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config (cmd->server->module_config, &vhost_ldap_module); if (strcmp(deref, "never") == 0 || strcasecmp(deref, "off") == 0) { conf->deref = never; conf->have_deref = 1; } else if (strcmp(deref, "searching") == 0) { conf->deref = searching; conf->have_deref = 1; } else if (strcmp(deref, "finding") == 0) { conf->deref = finding; conf->have_deref = 1; } else if (strcmp(deref, "always") == 0 || strcasecmp(deref, "on") == 0) { conf->deref = always; conf->have_deref = 1; } else { return "Unrecognized value for VhostLDAPAliasDereference directive"; } return NULL; } static const char *mod_vhost_ldap_set_fallback(cmd_parms *cmd, void *dummy, const char *fallback) { mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); conf->fallback = apr_pstrdup(cmd->pool, fallback); return NULL; } static const char *mod_vhost_ldap_set_wildcard(cmd_parms *cmd, void *dummy, int wildcard) { mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); conf->wildcard = (wildcard) ? MVL_ENABLED : MVL_DISABLED; return NULL; } command_rec mod_vhost_ldap_cmds[] = { AP_INIT_TAKE1("VhostLDAPURL", mod_vhost_ldap_parse_url, NULL, RSRC_CONF, "URL to define LDAP connection. This should be an RFC 2255 compliant\n" "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n" "
    \n" "
  • Host is the name of the LDAP server. Use a space separated list of hosts \n" "to specify redundant servers.\n" "
  • Port is optional, and specifies the port to connect to.\n" "
  • basedn specifies the base DN to start searches from\n" "
\n"), AP_INIT_TAKE1 ("VhostLDAPBindDN", mod_vhost_ldap_set_binddn, NULL, RSRC_CONF, "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."), AP_INIT_TAKE1("VhostLDAPBindPassword", mod_vhost_ldap_set_bindpw, NULL, RSRC_CONF, "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."), AP_INIT_FLAG("VhostLDAPEnabled", mod_vhost_ldap_set_enabled, NULL, RSRC_CONF, "Set to off to disable vhost_ldap, even if it's been enabled in a higher tree"), AP_INIT_TAKE1("VhostLDAPDereferenceAliases", mod_vhost_ldap_set_deref, NULL, RSRC_CONF, "Determines how aliases are handled during a search. Can be one of the" "values \"never\", \"searching\", \"finding\", or \"always\". " "Defaults to always."), AP_INIT_TAKE1("VhostLDAPFallback", mod_vhost_ldap_set_fallback, NULL, RSRC_CONF, "Set default virtual host which will be used when requested hostname" "is not found in LDAP database. This option can be used to display" "\"virtual host not found\" type of page."), AP_INIT_FLAG("VhostLDAPWildcard", mod_vhost_ldap_set_wildcard, NULL, RSRC_CONF, "Set to off to disable wildcard search if the requested hostname is not found."), {NULL} }; #define FILTER_LENGTH MAX_STRING_LEN static int mod_vhost_ldap_translate_name(request_rec *r) { mod_vhost_ldap_request_t *reqc; int failures = 0; const char **vals = NULL; char filtbuf[FILTER_LENGTH]; mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_module); util_ldap_connection_t *ldc = NULL; int result = 0; const char *dn = NULL; char *cgi; const char *hostname = NULL; int is_fallback = 0; int sleep0 = 0; int sleep1 = 1; int sleep; struct berval hostnamebv, shostnamebv; char *document_root; int ret = DECLINED; reqc = (mod_vhost_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t)); memset(reqc, 0, sizeof(mod_vhost_ldap_request_t)); ap_set_module_config(r->request_config, &vhost_ldap_module, reqc); // mod_vhost_ldap is disabled or we don't have LDAP Url if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) { return DECLINED; } start_over: if (conf->host) { ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw, conf->deref, conf->secure); } else { ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c] translate: no conf->host - weird...?"); return HTTP_INTERNAL_SERVER_ERROR; } hostname = r->hostname; if (hostname == NULL || hostname[0] == '\0') goto null; fallback: ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c]: translating hostname [%s], uri [%s]", hostname, r->uri); ber_str2bv(hostname, 0, 0, &hostnamebv); if (ldap_bv2escaped_filter_value(&hostnamebv, &shostnamebv) != 0) goto null; apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, shostnamebv.bv_val, shostnamebv.bv_val); ber_memfree(shostnamebv.bv_val); result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope, attributes, filtbuf, &dn, &vals); util_ldap_connection_close(ldc); /* sanity check - if server is down, retry it up to 5 times */ if (AP_LDAP_IS_SERVER_DOWN(result) || (result == LDAP_TIMEOUT) || (result == LDAP_CONNECT_ERROR)) { sleep = sleep0 + sleep1; ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c]: lookup failure, retry number #[%d], sleeping for [%d] seconds", failures, sleep); if (failures++ < MAX_FAILURES) { /* Back-off exponentially */ apr_sleep(apr_time_from_sec(sleep)); sleep0 = sleep1; sleep1 = sleep; goto start_over; } else { return HTTP_GATEWAY_TIME_OUT; } } if (result == LDAP_NO_SUCH_OBJECT) { if (conf->wildcard == MVL_ENABLED) { if (strcmp(hostname, "*") != 0) { if (strncmp(hostname, "*.", 2) == 0) hostname += 2; hostname += strcspn(hostname, "."); hostname = apr_pstrcat(r->pool, "*", hostname, NULL); ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c] translate: " "virtual host not found, trying wildcard %s", hostname); goto fallback; } } null: if (conf->fallback && (is_fallback++ <= 0)) { ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c] translate: " "virtual host %s not found, trying fallback %s", hostname, conf->fallback); hostname = conf->fallback; goto fallback; } ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c] translate: " "virtual host %s not found", hostname); return HTTP_BAD_REQUEST; } /* handle bind failure */ if (result != LDAP_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c] translate: " "translate failed; virtual host %s; URI %s [%s]", hostname, r->uri, ldap_err2string(result)); return HTTP_INTERNAL_SERVER_ERROR; } /* mark the user and DN */ reqc->dn = apr_pstrdup(r->pool, dn); /* Optimize */ if (vals) { int i = 0; while (attributes[i]) { if (strcasecmp (attributes[i], "apacheServerName") == 0) { reqc->name = apr_pstrdup (r->pool, vals[i]); } else if (strcasecmp (attributes[i], "apacheServerAdmin") == 0) { reqc->admin = apr_pstrdup (r->pool, vals[i]); } else if (strcasecmp (attributes[i], "apacheDocumentRoot") == 0) { reqc->docroot = apr_pstrdup (r->pool, vals[i]); } else if (strcasecmp (attributes[i], "apacheScriptAlias") == 0) { reqc->cgiroot = apr_pstrdup (r->pool, vals[i]); } else if (strcasecmp (attributes[i], "apacheSuexecUid") == 0) { reqc->uid = apr_pstrdup(r->pool, vals[i]); } else if (strcasecmp (attributes[i], "apacheSuexecGid") == 0) { reqc->gid = apr_pstrdup(r->pool, vals[i]); } i++; } } ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c]: loaded from ldap: " "apacheServerName: %s, " "apacheServerAdmin: %s, " "apacheDocumentRoot: %s, " "apacheScriptAlias: %s, " "apacheSuexecUid: %s, " "apacheSuexecGid: %s", reqc->name, reqc->admin, reqc->docroot, reqc->cgiroot, reqc->uid, reqc->gid); if ((reqc->name == NULL)||(reqc->docroot == NULL)) { ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c] translate: " "translate failed; ServerName or DocumentRoot not defined"); return HTTP_INTERNAL_SERVER_ERROR; } cgi = NULL; if (reqc->cgiroot) { cgi = strstr(r->uri, "cgi-bin/"); if (cgi && (cgi != r->uri + strspn(r->uri, "/"))) { cgi = NULL; } } if (cgi) { /* Set exact filename for CGI script */ cgi = apr_pstrcat(r->pool, reqc->cgiroot, cgi + strlen("cgi-bin"), NULL); if ((cgi = ap_server_root_relative(r->pool, cgi))) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[mod_vhost_ldap.c]: ap_document_root is: %s", ap_document_root(r)); r->filename = cgi; r->handler = "cgi-script"; apr_table_setn(r->notes, "alias-forced-type", r->handler); ret = OK; } } else if (r->uri[0] == '/') { /* we don't set r->filename here, and let other modules do it * this allows other modules (mod_rewrite.c) to work as usual */ /* r->filename = apr_pstrcat (r->pool, reqc->docroot, r->uri, NULL); */ } else { /* We don't handle non-file requests here */ return DECLINED; } document_root = apr_pstrdup(r->pool, ap_context_document_root(r)); /* Make it absolute, relative to ServerRoot */ reqc->docroot = ap_server_root_relative(r->pool, reqc->docroot); if (reqc->docroot == NULL) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "[mod_vhost_ldap.c] set_document_root: DocumentRoot must be a directory"); return HTTP_INTERNAL_SERVER_ERROR; } /* TODO: ap_configtestonly && ap_docrootcheck && */ if (apr_filepath_merge(&document_root, NULL, reqc->docroot, APR_FILEPATH_TRUENAME, r->pool) != APR_SUCCESS || !ap_is_directory(r->pool, reqc->docroot)) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "[mod_vhost_ldap.c] set_document_root: Warning: DocumentRoot [%s] does not exist", reqc->docroot); document_root = reqc->docroot; } ap_set_context_info(r, NULL, document_root); ap_set_document_root(r, document_root); /* Return DECLINE to allow post-processing by other modules (mod_rewrite, mod_alias) */ return ret; } #ifdef HAVE_UNIX_SUEXEC static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r) { ap_unix_identity_t *ugid = NULL; mod_vhost_ldap_config_t *conf = (mod_vhost_ldap_config_t *)ap_get_module_config(r->server->module_config, &vhost_ldap_module); mod_vhost_ldap_request_t *req = (mod_vhost_ldap_request_t *)ap_get_module_config(r->request_config, &vhost_ldap_module); uid_t uid = -1; gid_t gid = -1; // mod_vhost_ldap is disabled or we don't have LDAP Url if ((conf->enabled != MVL_ENABLED)||(!conf->have_ldap_url)) { return NULL; } if ((req == NULL)||(req->uid == NULL)||(req->gid == NULL)) { return NULL; } if ((ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL) { return NULL; } uid = (uid_t)atoll(req->uid); gid = (gid_t)atoll(req->gid); if ((uid < MIN_UID)||(gid < MIN_GID)) { return NULL; } ugid->uid = uid; ugid->gid = gid; ugid->userdir = 0; return ugid; } #endif static void mod_vhost_ldap_register_hooks (apr_pool_t * p) { /* * Run before mod_rewrite */ static const char * const aszRewrite[]={ "mod_rewrite.c", NULL }; ap_hook_post_config(mod_vhost_ldap_post_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_translate_name(mod_vhost_ldap_translate_name, NULL, aszRewrite, APR_HOOK_FIRST); #ifdef HAVE_UNIX_SUEXEC ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE); #endif ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA vhost_ldap_module = { STANDARD20_MODULE_STUFF, NULL, NULL, mod_vhost_ldap_create_server_config, mod_vhost_ldap_merge_server_config, mod_vhost_ldap_cmds, mod_vhost_ldap_register_hooks, }; mod-vhost-ldap-2.4.0/mod_vhost_ldap.schema000066400000000000000000000040651216772061200205500ustar00rootroot00000000000000## ## OIDs are owned by Globe Internet ## ## 1.3.6.1.4.1.14287.1.x - mod_vhost_ldap ## 1.3.6.1.4.1.14287.1.1.x - attributetypes ## 1.3.6.1.4.1.14287.1.2.x - objectclasses ## attributetype ( 1.3.6.1.4.1.8387.1.1.2 NAME 'apacheServerName' SUP name DESC 'mod_vhost_ldap: Apache ServerName' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.8387.1.1.3 NAME 'apacheServerAlias' SUP name DESC 'mod_vhost_ldap: Apache ServerAlias' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} ) attributetype ( 1.3.6.1.4.1.8387.1.1.4 NAME 'apacheDocumentRoot' SUP name DESC 'mod_vhost_ldap: Apache DocumentRoot' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.8387.1.1.5 NAME 'apacheServerAdmin' SUP name DESC 'mod_vhost_ldap: Apache ServerAdmin' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.14287.1.1.6 NAME 'apacheScriptAlias' SUP name DESC 'mod_cfg_ldap: Apache ScriptAlias' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.8387.1.1.7 NAME 'apacheSuexecUid' SUP name DESC 'mod_vhost_ldap: Apache SuexecUid' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.8387.1.1.8 NAME 'apacheSuexecGid' SUP name DESC 'mod_vhost_ldap: Apache SuexecGid' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} SINGLE-VALUE ) objectclass ( 1.3.6.1.4.1.8387.1.2.1 NAME 'apacheConfig' SUP 'top' MUST ( apacheServerName $ apacheDocumentRoot ) MAY ( apacheServerAlias $ apacheServerAdmin $ apacheScriptAlias $ apacheSuexecUid $ apacheSuexecGid ) ) mod-vhost-ldap-2.4.0/vhost_ldap.conf000066400000000000000000000010161216772061200173670ustar00rootroot00000000000000# # mod_vhost_ldap allows you to keep your virtual host configuration # in an LDAP directory and update it in nearly realtime. # ### NOTE ### ### mod_vhost_ldap depends on mod_ldap ### ### you have to enable mod_ldap as well ### LoadModule vhost_ldap_module modules/mod_vhost_ldap.so VhostLDAPEnabled on VhostLDAPUrl "ldap://127.0.0.1/ou=vhosts,ou=web,dc=localhost" VhostLdapBindDN "cn=admin,dc=localhost" VhostLDAPBindPassword "changeme" VhostLDAPWildcard on