/* Copyright © 1998, 1999 Enbridge Pipelines Inc. Copyright © 1999-2006 Dave Carrigan All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Apache itself. This module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. The copyright holder of this module can not be held liable for any general, special, incidental or consequential damages arising out of the use of the module. $Id: auth_ldap_config.c,v 1.14 2001/07/04 14:40:00 dave Exp $ */ #include "auth_ldap.h" extern module MODULE_VAR_EXPORT auth_ldap_module; void * create_auth_ldap_dir_config(pool *p, char *d) { auth_ldap_config_rec *sec = (auth_ldap_config_rec *)ap_pcalloc(p, sizeof(auth_ldap_config_rec)); sec->auth_authoritative = 1; sec->enabled = 1; sec->groupattr = ap_make_array(p, GROUPATTR_MAX_ELTS, sizeof(struct groupattr_entry)); sec->version = 0; /* use default */ sec->have_ldap_url = 0; sec->ldc = NULL; sec->host = NULL; sec->url = ""; sec->binddn = NULL; sec->bindpw = NULL; sec->deref = always; sec->group_attrib_is_dn = 1; #ifdef AUTH_LDAP_FRONTPAGE_HACK sec->frontpage_hack = 0; #endif #ifdef HAVE_TLS sec->starttls = 0; #endif sec->dn = ""; sec->user_is_dn = 0; sec->compare_dn_on_server = 0; return sec; } const char * parse_auth_ldap_version(cmd_parms *cmd, auth_ldap_config_rec *sec, char *version) { ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "version %s: Trying to parse version '%s'", auth_ldap_version, version); sec->version = atol(version); return NULL; } /* Use the ldap url parsing routines to break up the ldap url into host and port, and find/make a pointer to a LDAPconnection struct */ const char * parse_auth_ldap_url(cmd_parms *cmd, auth_ldap_config_rec *sec, char *url) { int result; LDAPURLDesc *urld; ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "version %s: Trying to parse an url `%s'", auth_ldap_version, url); result = 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"; } } sec->url = ap_pstrdup(cmd->pool, url); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "Url parse: Host: %s", urld->lud_host); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "Url parse: Port: %d", urld->lud_port); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "Url parse: DN: %s", urld->lud_dn); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "Url parse: Attrib: %s", urld->lud_attrs? urld->lud_attrs[0] : "(null)"); ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "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, cmd->server, "Url parse: Filter: %s", urld->lud_filter); /* Set all the values, or at least some sane defaults */ if (sec->host) { char *p = ap_palloc(cmd->pool, strlen(sec->host) + strlen(urld->lud_host) + 2); strcpy(p, urld->lud_host); strcat(p, " "); strcat(p, sec->host); sec->host = p; } else { sec->host = urld->lud_host? ap_pstrdup(cmd->pool, urld->lud_host) : "localhost"; } sec->basedn = urld->lud_dn? ap_pstrdup(cmd->pool, urld->lud_dn) : ""; if (urld->lud_attrs && urld->lud_attrs[0]) { sec->attribute = ap_pstrdup(cmd->pool, urld->lud_attrs[0]); } else { sec->attribute = "uid"; } sec->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. */ sec->filter = ap_pstrdup(cmd->pool, urld->lud_filter+1); sec->filter[strlen(sec->filter)-1] = '\0'; } else { sec->filter = ap_pstrdup(cmd->pool, urld->lud_filter); } } else { sec->filter = "objectclass=*"; } if (strncmp(url, "ldaps", 5) == 0) { ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "{%d} requesting secure LDAP", (int)getpid()); #ifdef WITH_SSL sec->port = urld->lud_port? urld->lud_port : LDAPS_PORT; sec->secure = 1; #else #if defined(WITH_OPENLDAP) && LDAP_VENDOR_VERSION <= 20000 return "Secure LDAP (ldaps://) not supported. Rebuild auth_ldap"; #endif #endif } else { ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, cmd->server, "{%d} not requesting secure LDAP", (int)getpid()); #ifdef WITH_SSL sec->secure = 0; #endif sec->port = urld->lud_port? urld->lud_port : LDAP_PORT; } sec->have_ldap_url = 1; ldap_free_urldesc(urld); return NULL; } const char * auth_ldap_set_compare_flag(cmd_parms *cmd, void *dummy, char *arg) { ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, cmd->server, "Ignoring deprecated AuthLDAPCacheCompareOps directive."); return NULL; } const char * auth_ldap_set_deref(cmd_parms *cmd, auth_ldap_config_rec *sec, char *arg) { if (strcmp(arg, "never") == 0 || strcasecmp(arg, "off") == 0) { sec->deref = never; } else if (strcmp(arg, "searching") == 0) { sec->deref = searching; } else if (strcmp(arg, "finding") == 0) { sec->deref = finding; } else if (strcmp(arg, "always") == 0 || strcasecmp(arg, "on") == 0) { sec->deref = always; } else { return "Unrecognized value for AuthLDAPAliasDereference directive"; } return NULL; } const char * auth_ldap_add_group_attribute(cmd_parms *cmd, auth_ldap_config_rec *sec, char *arg) { struct groupattr_entry *new; if (sec->groupattr->nelts > GROUPATTR_MAX_ELTS) return "Too many AuthLDAPGroupAttribute directives"; new = ap_push_array(sec->groupattr); new->name = ap_pstrdup(cmd->pool, arg); return NULL; } const char * auth_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy, char *ttl) { auth_ldap_server_conf *c = (auth_ldap_server_conf *)ap_get_module_config(cmd->server->module_config, &auth_ldap_module); c->search_cache_ttl = atol(ttl); return NULL; } const char * auth_ldap_set_cache_size(cmd_parms *cmd, void *dummy, char *size) { auth_ldap_server_conf *c = (auth_ldap_server_conf *)ap_get_module_config(cmd->server->module_config, &auth_ldap_module); c->search_cache_size = atol(size); if (c->search_cache_size < 0) c->search_cache_size = 0; return NULL; } const char * auth_ldap_set_opcache_ttl(cmd_parms *cmd, void *dummy, char *ttl) { auth_ldap_server_conf *c = (auth_ldap_server_conf *)ap_get_module_config(cmd->server->module_config, &auth_ldap_module); c->compare_cache_ttl = atol(ttl); return NULL; } const char * auth_ldap_set_opcache_size(cmd_parms *cmd, void *dummy, char *size) { auth_ldap_server_conf *c = (auth_ldap_server_conf *)ap_get_module_config(cmd->server->module_config, &auth_ldap_module); c->compare_cache_size = atol(size); if (c->compare_cache_size < 0) c->compare_cache_size = 0; return NULL; } #ifdef WITH_SSL const char * auth_ldap_set_certdbpath(cmd_parms *cmd, void *dummy, char *path) { auth_ldap_server_conf *c = (auth_ldap_server_conf *)ap_get_module_config(cmd->server->module_config, &auth_ldap_module); c->have_certdb = 1; if (ldapssl_client_init(path, NULL) != 0) return "Could not initialize SSL client"; else return NULL; } #endif void auth_ldap_module_kill(void *data) { #ifdef WITH_SHARED_LDAP_CACHE if (auth_ldap_mm != NULL) { ap_mm_destroy(auth_ldap_mm); auth_ldap_mm = NULL; } #endif } void auth_ldap_child_kill(void *data) { /* Nothing to do */ } void auth_ldap_init_module(server_rec *s, pool *p) { ap_register_cleanup(p, s, auth_ldap_module_kill, auth_ldap_child_kill); #ifdef WITH_SHARED_LDAP_CACHE if (ap_mm_useable()) { extern AP_MM *auth_ldap_mm; ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, s, "Trying to enable shared cache."); auth_ldap_mm = ap_mm_create(0, "/tmp/auth_ldap_cache"); if (auth_ldap_mm != NULL) { ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, s, "Successfully enabled shared cache."); ap_mm_permission(auth_ldap_mm, ALD_MM_FILE_MODE, ap_user_id, -1); } else { ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, s, "Shared cache allocation failed."); } } else { ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, s, "MM is unavailable; not enabling shared cache."); } #endif auth_ldap_cache = ald_create_cache(50, auth_ldap_url_node_hash, auth_ldap_url_node_compare, auth_ldap_url_node_copy, auth_ldap_url_node_free); } void * create_auth_ldap_config(pool *p, server_rec *s) { auth_ldap_server_conf *c = (auth_ldap_server_conf *)ap_pcalloc(p, sizeof(auth_ldap_server_conf)); c->search_cache_ttl = 600; c->search_cache_size = 1024; c->compare_cache_ttl = 600; c->compare_cache_size = 1024; c->mtx = ap_create_mutex(NULL); c->ldapconnections = NULL; #ifdef WITH_SSL c->have_certdb = 0; #endif return c; }