From 866f08330b3077d982ba4651cc0da14685c9cb1d Mon Sep 17 00:00:00 2001 From: Piotr Wadas Date: Tue, 18 Jul 2006 21:37:28 +0000 Subject: [PATCH] warning - watch attribute OIDS, they're not registered with IANA nor something, turn schemacheck in your openldap.conf git-svn-id: svn://svn.debian.org/svn/modvhostldap/branches/ext-config/mod-vhost-ldap@46 4dd36cbf-e3fd-0310-983d-db0e06859cf4 --- AUTHORS | 1 + COPYING | 2 +- ChangeLog | 29 +- FILES | 1 + Makefile | 27 +- README | 74 +- TODO | 13 +- VERSION | 2 +- examples/slapd.conf | 54 +- examples/vhost_ldap.conf | 64 +- mod_vhost_ldap.c | 1425 ++++++++++++++++++++------------------ mod_vhost_ldap.schema | 5 +- vhost_ldap.conf | 64 +- 13 files changed, 989 insertions(+), 772 deletions(-) diff --git a/AUTHORS b/AUTHORS index 17353ee..63f7d51 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ Ondřej Surý +Piotr Wadas diff --git a/COPYING b/COPYING index 237707e..c0d40ef 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2005, Ondrej Sury +Copyright (c) 2006, Ondrej Sury, Piotr Wadas All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/ChangeLog b/ChangeLog index 14529dc..b71eaa0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,30 @@ +2006-07-18 Piotr Wadas + * mod_vhost_ldap.c : many changes, new directives, new features + * new features include: support for aliasing, support for http auth + * stored in ldap ( per-location and per-directory), and support + * for unix crypt() encrypted passwords for webusers, directives + * for turning off aliasing support, per-location auth, per-directory + * auth etc, now we support 12 directives total + * mod_vhost_ldap.c : added support for appending global user defined + * filter, parsed standalone with ldap_uri directive parsing + * mod_vhost_ldap.c : restored ldap-based fallback vhost support + * mod_vhost_ldap.c : replaced directives handling functions with one + * function for all directives, based on switch() + * mod_vhost_ldap.c : cleanup and optimization for attribute values + * retrieving for each kind of object (users, aliases, vhosts etc. + * mod_vhost_ldap.h added + * apache_alias.schema: added with attributes and objectclasses for + * per-directory and per-location aliasing + * apache_ext.schema: added object classess attributes for http auth + * and object classess for http auth + * general code cleanup, new separated functions + * replaced versioning scheme to be more like apache versions + * VERSION: 2.0.3 release + 2006-03-30 Piotr Wadas * mod_vhost_ldap.c: add support for basic ldap auth. Yuck. - * VERSION: 2.0.0 release + * VERSION: 0.3.0 release -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 diff --git a/FILES b/FILES index b0c070f..444c649 100644 --- a/FILES +++ b/FILES @@ -11,3 +11,4 @@ mod_vhost_ldap.spec README TODO VERSION +apache_ext.schema diff --git a/Makefile b/Makefile index 74d42f0..3b0a5d8 100644 --- a/Makefile +++ b/Makefile @@ -14,33 +14,34 @@ clean: rm -f *.la rm -f *.slo rm -rf .libs - rm -rf mod_vhost_ldap-$(VERSION) - rm -rf mod_vhost_ldap-$(VERSION).tar.gz +restart: + > /var/log/apache2/error.log + /usr/bin/apache2sctl stop + /usr/bin/apache2sctl start mod_vhost_ldap.o: 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 - + /usr/bin/apache2sctl restart + encclean: rm enc encrypt: gcc -Wall encrypt.c -o enc -lcrypt -deb: make clean - svn export svn+ssh://ondrej@svn.debian.org/svn/modvhostldap mod-vhost-ldap-`cat VERSION`.orig; - /usr/bin/pdebuild --configfile /home/ondrej/.pbuilderrc.unstable +dtpasswdclean: + rm dtpasswd + +dtpasswd: + gcc -Wall -Werror -l crypt -o dtpasswd dtpasswd.c -archive: - svn export svn+ssh://ondrej@svn.debian.org/svn/modvhostldap/mod-vhost-ldap mod-vhost-ldap-`cat VERSION`; - rm -rf mod-vhost-ldap-$(VERSION)/debian - tar czf ../tarballs/mod-vhost-ldap-$(VERSION).tar.gz mod-vhost-ldap-$(VERSION); - ln -sf mod-vhost-ldap-$(VERSION).tar.gz ../tarballs/mod-vhost-ldap_$(VERSION).orig.tar.gz - tar cjf ../tarballs/mod-vhost-ldap-$(VERSION).tar.bz2 mod-vhost-ldap-$(VERSION); - rm -rf mod-vhost-ldap-$(VERSION); +deb: + debuild --no-tgz-check format: indent *.c .PHONY: all install clean archive format encrypt encclean + diff --git a/README b/README index 9121929..1c9ebe1 100644 --- a/README +++ b/README @@ -1,7 +1,67 @@ - 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. - Access control comes with module version 2.x - . - It's build on top of mod_ldap, so it uses it's caching capabilities - and can be used with threaded apache. +This directory contains user application schema definitions for use +with slapd(8). + +File Description +---- ----------- +corba.schema Corba Object (RFC 2714) +core.schema OpenLDAP "core" +cosine.schema COSINE Pilot +inetorgperson.schema InetOrgPerson +java.schema Java Object (RFC 2713) +misc.schema Miscellaneous Schema (experimental) +nis.schema Network Information Service +openldap.schema OpenLDAP Project (FYI) + +Additional "generally useful" schema definitions can be submitted +using the OpenLDAP Issue Tracking System . +Submissions should include a stable reference to a mature, open +technical specification (e.g., an RFC) for the schema. + +--- + +This notice applies to all files in this directory. + +Copyright 1998-2005 The OpenLDAP Foundation, Redwood City, California, USA +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted only as authorized by the OpenLDAP +Public License. A copy of this license is available at +http://www.OpenLDAP.org/license.html or in file LICENSE in the +top-level directory of the distribution. + +--- + +This notice applies to all schema in this directory which are derived +from RFCs and other Internet Standards documents. + +Portions Copyright 1991-2004, The Internet Society. All Rights Reserved. + +This document and translations of it may be copied and furnished +to others, and derivative works that comment on or otherwise explain +it or assist in its implementation may be prepared, copied, published +and distributed, in whole or in part, without restriction of any +kind, provided that the above copyright notice and this paragraph +are included on all such copies and derivative works. However, +this document itself may not be modified in any way, such as by +removing the copyright notice or references to the Internet Society +or other Internet organizations, except as needed for the purpose +of developing Internet standards in which case the procedures for +copyrights defined in the Internet Standards process must be +followed, or as required to translate it into languages other than +English. + +The limited permissions granted above are perpetual and will not +be revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on +an "AS IS" basis and THE AUTHORS, THE INTERNET SOCIETY, AND THE +INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE +OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY +IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. + + +--- +$OpenLDAP: pkg/ldap/servers/slapd/schema/README,v 1.18.2.4 2005/01/20 17:01:18 kurt Exp $ diff --git a/TODO b/TODO index 08692fc..1608704 100644 --- a/TODO +++ b/TODO @@ -1,15 +1,16 @@ * Put back TLS -* general code review (use of per-directory-config ?) +* Put back suexec * implement php_admin_flag and php_admin_value setting for vhosts with ldap -* implement directory access control, similar to location -* implement directory/location aliasing between vhosts, based on ldap * implement logging-related directives for ldap-based vhosts * implement require group * implement use of other authentication methods than basic, including X509, +* DONE * general code review (use of per-directory-config ?) +* DONE *implement directory access control, similar to location +* DONE * implement directory/location aliasing between vhosts, based on ldap and authentication based not only with apacheExtUserObject, but also with -classic posixAccount/Group, probably with use of other excellent modules -like mod_authz_ldap and others.. +classic posixAccount/Group (currently this is implemented via unix password +support * testing with apache 2.2.x * testers are welcomed, probably some nullpointer and overflows possibility extists, anyway Apache The Greate works holds the line - I tested some -generated module segfaults, and they doesn't break apache itself, module only. +generated module segfaults, and they doesn't break apache and module itself, childs only. diff --git a/VERSION b/VERSION index 227cea2..50ffc5a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 +2.0.3 diff --git a/examples/slapd.conf b/examples/slapd.conf index 8cbcf4c..0ada828 100644 --- a/examples/slapd.conf +++ b/examples/slapd.conf @@ -1,23 +1,20 @@ -TLSCipherSuite HIGH:MEDIUM:+SSLv3 -TLSCertificateFile /etc/ldap/TLS/ldapserver.crt -TLSCertificateKeyFile /etc/ldap/TLS/ldapserver.key -TLSCACertificateFile /etc/ldap/TLS/ca.crt +#TLSCipherSuite HIGH:MEDIUM:+SSLv3 +#TLSCertificateFile /etc/ldap/TLS/ldapserver.crt +#TLSCertificateKeyFile /etc/ldap/TLS/ldapserver.key +#TLSCACertificateFile /etc/ldap/TLS/ca.crt -allow bind_v2 -allow update_anon +#allow bind_v2 +disallow bind_anon tls_2_anon include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/inetorgperson.schema -include /etc/ldap/schema/dnsdomain2.schema -include /etc/ldap/schema/sendmail.schema include /etc/ldap/schema/misc.schema -include /etc/ldap/schema/ISPEnv2.schema include /etc/ldap/schema/local.schema -include /etc/ldap/schema/mod_vhost_ldap.schema -include /home/pwadas/workspace/mod-vhost-ldap/apache_ext.schema -#include /etc/ldap/schema/samba.schema +include /etc/ldap/schema/mod_vhost_ldap.schema +include /etc/ldap/schema/apache_ext.schema +include /etc/ldap/schema/apache_alias.schema pidfile /var/run/slapd/slapd.pid argsfile /var/run/slapd.args @@ -26,9 +23,9 @@ moduleload back_bdb backend bdb schemacheck on -checkpoint 512 30 +checkpoint 1 5 -#sumuja sie - np. 512+128 +#sum values as ldap level # 1 trace function calls # 2 debug packet handling # 4 heavy trace debugging @@ -42,27 +39,24 @@ checkpoint 512 30 # 1024 print communication with shell backends # 2048 entry parsing -loglevel 256 -#loglevel 0 +#loglevel 768 +loglevel 0 database bdb lastmod on suffix "dc=ROOT" directory "/var/lib/ldap" +sizelimit unlimited +timelimit unlimited -index default pres,eq,sub -index uniqueMember,member pres -index cn,sn,uid,associatedDomain,memberUid,domainUid,commonUid,gecos,businessCategory pres,eq,sub -index customerName,customerCompanyName,customerDescription,customerCity,customerRegion,customerResponsiblePerson pres,eq,sub -index objectClass,homeDirectory,loginShell,uidNumber,gidNumber,customerID,authorizedService,customerRole,customerSupportCode,pTRRecord,ipHostNumber pres,eq -index MXRecord,NSRecord,SOARecord,ARecord,MDRecord,CNAMERecord,DNSTTL,DNSClass,HINFORecord,MINFORecord,TXTRecord,SIGRecord,KEYRecord,AAAARecord pres,eq -index resellerName,resellerCompanyName,resellerDescription,resellerCity,resellerRegion,resellerResponsiblePerson pres,eq,sub -index resellerID,resellerRole,resellerSupportCode pres,eq -index sendmailMTAHost,sendmailMTAAliasGrouping,sendmailMTAKey,sendmailMTAMapName,sendmailMTAMapValue,sendmailMTAClassName,sendmailMTAClassValue pres,eq -index apacheServerName,apacheServerAlias,apacheDocumentRoot,apacheServerAdmin pres,eq -index apacheExtConfigUri,apacheExtConfigServerName pres,eq,sub -index apacheLocationOptionsDn,apacheExtConfigRequireValidUser,apacheExtConfigUserDn,apacheExtConfigUserServerName,apacheExtConfigObjectName pres,eq -index vacationActive eq +include /etc/ldap/indexes + +rootdn "cn=admin,dc=foo,dc=bar" + +access to dn.base="" + by * read access to * - by * write + by dn="cn=admin,dc=foo,dc=bar" + by dn="cn=nobody,dc=foo,dc=bar" read + by * none diff --git a/examples/vhost_ldap.conf b/examples/vhost_ldap.conf index 36c73e9..495364d 100644 --- a/examples/vhost_ldap.conf +++ b/examples/vhost_ldap.conf @@ -1,17 +1,55 @@ -# -# 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 ### +### and probably set various cache options for it ### + +###scope values: base, one, sub +###deref values: never, finding, searching, always +###remember, user specified filter is checked as RFC-defined ldap filter before substitution +###user filter specified here results with following internal filters and variables: +### _A_ is the server name from the request (vhost server name to find) +### _B_ is the uri for which access control is to be determined +### _C_ is the name of the require valid-user directive (auth prompt message) +### _D_ is the the user-defined filter +### _E_ is the protected physical directory (doesn't need to be existing file or dir) +### _F_ is the alias location uri +### _G_ is the protected uri for which access control is to be determined (see _E_) +### _H_ is the alias uri which is to be aliased to specified directory +### Each use of search filter is logged with debug level + +##################################################################### +### Vhost search +### (&(_D_)(|(apacheServerName=_A_)(apacheServerAlias=_A_))) +##################################################################### +### Protected Location Search +### (&(_D_)(apacheExtConfigServerName=_A_)(apacheExtConfigUri=_B_)) +##################################################################### +### Protected Directory Search +### (&(_D_)(apacheExtConfigPath=_E_)) +##################################################################### +### Alias Object Search +### (&(_D_)(apacheAliasConfigServerName=_A_)(apacheAliasConfigSourceUri=_H_)) +##################################################################### +### Web user Location Search +### (&(_D_)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserServerName=_A_)(apacheExtConfigUserLocationUri=_G_)) +##################################################################### +### Web user Directory Search +### (&(_D_)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserDirectoryName=_E_)) +################################## + +### ldap[si]://host[:port]/basedn[?attrib[?scope[?filter]]] + + VhostLdapEnabled On + VhostLdapUrl ldap[si]://host[:port]/basedn[?attrib[?scope[?filter]]] + #VhostLdapUrl ldap://hostname:389/dc=foo,dc=bar?*?sub?objectClass=activeObject + VhostLdapBindDn "cn=read only apache admin,dc=foo,dc=bar" + VhostLdapBindPw "secretpassword" + VhostLdapWlcBaseDn "ou=webAccess,dc=foo,dc=bar" + VhostLdapWucBaseDn "ou=webAccounts,dc=foo,dc=bar" + VhostLdapAliasesBaseDn "ou=webAliases,dc=foo,dc=bar" + VhostLdapDeref "never" + VhostLdapFallback default + VhostAliasesEnabled On + VhostLocAuthEnabled On + VhostDirAuthEnabled On -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" - diff --git a/mod_vhost_ldap.c b/mod_vhost_ldap.c index 1d81bb7..1baff61 100644 --- a/mod_vhost_ldap.c +++ b/mod_vhost_ldap.c @@ -1,149 +1,37 @@ /* ============================================================ * Copyright (c) 2003-2006, Ondrej Sury, Piotr Wadas * 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. - * - */ - -/* NOTE: only static members must be "used" to build, so for time-to-time used routines we don't declare static */ - -/* + * NOTE: only static members must be "used" to build, + * so for time-to-time used routines we don't declare static * mod_vhost_ldap.c --- read virtual host config from LDAP directory * version 2.0 - included ldap-based basic auth & authz + * remember to add "-lcrypt" in Makefile if there's a need to generate new password + * for now not needed (validation only), this below is almost copy-paste from apache source, htpasswd.c */ + +#include "mod_vhost_ldap.h" -//remember to add "-lcrypt" in Makefile if there's a need to generate new password -// for now not needed (validation only), this below is almost copy-paste from apache source, htpasswd.c -/* - -#include "crypt.h" -#include "time.h" - -void to64(char *s, unsigned long v, int n) +module AP_MODULE_DECLARE_DATA vhost_ldap_module; +/******************************************************************/ +char *pw_encrypt (const char *clear, const char *salt) { - static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - while (--n >= 0) { - *s++ = itoa64[v&0x3f]; - v >>= 6; - } -} - -char *htenc(const char *clearpasswd) { - char *res; - char salt[9]; - (void) srand((int) time((time_t *) NULL)); - to64(&salt[0], rand(), 8); - salt[8] = '\0'; - res = crypt(clearpasswd, salt); - return res; + //this function encrypts password in unix crypt md5 way + extern char *crypt (__const char *__key, __const char *__salt); + static char cipher[128]; + char *cp = crypt (clear, salt); + strcpy (cipher, cp); + return cipher; } - -*/ - -#define CORE_PRIVATE - -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_log.h" -#include "http_request.h" -#include "apr_ldap.h" -#include "apr_strings.h" -#include "apr_reslist.h" -#include "util_ldap.h" -#include "apr_md5.h" -#include "apr_sha1.h" -#include "unistd.h" - -#ifndef APU_HAS_LDAP -#fatal "mod_vhost_ldap requires APR util to have LDAP support built in" -#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 - -/* do not accept empty "" strings */ -#define strtrue(s) (s && *s) - -#define MIN_UID 100 -#define MIN_GID 100 -#define FILTER_LENGTH MAX_STRING_LEN - -module AP_MODULE_DECLARE_DATA vhost_ldap_module; - -typedef enum mod_vhost_ldap_status_e { - 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? */ - - 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) xx */ - int have_deref; /* Set if we have found an Deref option */ - int have_ldap_url; /* Set if we have found an LDAP url */ - char *wlcbasedn; /* Base DN to do all location config searches */ - char *wucbasedn; /* Base DN to do all webuser config searches */ - int secure; /* True if SSL connections are requested */ -} mod_vhost_ldap_config_t; -typedef struct mod_vhost_ldap_request_t { - char *dn; /* The saved dn from a successful search */ - char *name; /* apacheServerName */ - char *admin; /* apacheServerAdmin */ - char *docroot; /* apacheDocumentRoot */ - char *uid; /* Suexec Uid */ - char *gid; /* Suexec Gid */ - int has_reqlines; /* placeholder */ - apr_array_header_t *serveralias; /* apacheServerAlias */ - apr_array_header_t *rqlocationlines; /* apacheServerAlias */ - -} mod_vhost_ldap_request_t; -typedef struct mod_vhost_ldap_extconfig_object_t { /* what the hell this "t" means ??. eh, whatever ;) */ - //we use apr_array_header_t for multi-value attributed, parsed later (yuck!) from grr ";" separated string - char *extconfname; /* apacheExtConfigObjectName, single-value, syntax SUP cn */ - char *exturi; /* apacheExtConfigUri, single-value, uri for which this settings are here - * should be used in combine with extconfig server name */ - int extconftype; /* apacheExtConfigRequireValidUser, single-value bool, - * if TRUE then require valid-user, if FALSE userlist-type config - */ - - apr_array_header_t *extservername; /* apacheExtConfigServerName",MULTI-value, - * e.g. for http://anyserver/statistics (?), syntax SUP cn - */ - apr_array_header_t *extusers; /* "apacheExtConfigUserDn", MULTI-value, syntax SUP DN */ - -} mod_vhost_ldap_extconfig_object_t; -typedef struct mod_vhost_ldap_webuser_t { - - char *webusername; /* apacheExtConfigUserName, single-value */ - apr_array_header_t *webuserpassword; /* userPassword, multi-value */ - char *webuserserver; /* apacheExtConfigUserServerName, server of this user, multi-value */ - -} mod_vhost_ldap_webuser_t; +/******************************************************************/ static int strschrcount(apr_pool_t * p, const char *src, const char *delim) { int i = 1; @@ -155,6 +43,26 @@ static int strschrcount(apr_pool_t * p, const char *src, const char *delim) } return x; } +/******************************************************************/ +static void *mvhl_dump_config_request ( mvhl_config *currentconf, request_rec *r) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "BaseDn: %s", currentconf->basedn); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "BindDn: %s", currentconf->binddn); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "BindPw: %s", currentconf->bindpw); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Deref: %d", currentconf->deref); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Enabled: %d", currentconf->enabled); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "UserFilter: %s", currentconf->filter); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "HaveLdapUrl: %d", currentconf->have_ldap_url); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "HaveDeref: %d", currentconf->have_deref); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Url: %s", currentconf->url); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Port: %d", currentconf->port); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Scope: %d", currentconf->scope); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Fallback: %s", currentconf->fallback); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "WucBaseDn: %s", currentconf->wucbasedn); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "WlcBaseDn: %s", currentconf->wlcbasedn); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "AliasesBaseDn: %s", currentconf->aliasesbasedn); + return NULL; +} +/******************************************************************/ void log_dump_apr_array(request_rec * r, apr_array_header_t * arr, const char *prefix) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering log_dump_apr_array"); @@ -165,9 +73,14 @@ void log_dump_apr_array(request_rec * r, apr_array_header_t * arr, const char *p } ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving log_dump_apr_array"); } -static apr_array_header_t *get_parsed_string_atrr_arr(request_rec * r, const char *server_alias_attrvar_line, - const char *delim) +/******************************************************************/ +static apr_array_header_t *get_parsed_string_atrr_arr(request_rec * r, const char *server_alias_attrvar_line, const char *delim) { + /* + * This little piece of code creates apr_array from the string seperated by delim. + * It's primary usage is to get array of ldap one attribute values, which is + * retrieved (when multi-value) as ";" separated string. + */ ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering get_parsed_string_atrr_arr |%s|", server_alias_attrvar_line); if(server_alias_attrvar_line) { @@ -196,8 +109,8 @@ static apr_array_header_t *get_parsed_string_atrr_arr(request_rec * r, const cha ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving get_parsed_string_atrr_arr NULL"); return NULL; } -static apr_array_header_t *get_ap_reqs(apr_pool_t * p, mod_vhost_ldap_extconfig_object_t * extreqc, - char *mainservername, char *userlist) +/******************************************************************/ +static apr_array_header_t *get_ap_reqs(apr_pool_t * p, mvhl_extconfig_object * extreqc, char *mainservername, char *userlist) { ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL," get_ap_reqs Entering"); @@ -224,214 +137,288 @@ static apr_array_header_t *get_ap_reqs(apr_pool_t * p, mod_vhost_ldap_extconfig_ ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL," Leaving get_ap_reqs, returning require line |require %s|", rline->requirement); return res; } -static void mod_vhost_ldap_dovhostconfig(request_rec * r, char *attributes[], const char **vals, - mod_vhost_ldap_request_t * reqc) +/******************************************************************/ +static void mvhl_dovhostconfig(request_rec * r, char *attributes[], const char **vals, mvhl_request * reqc) { - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " dovhostconfig Entering "); - int i = 0; - while(attributes[i]) { - - if(strcasecmp(attributes[i], "apacheServerName") == 0) { - reqc->name = apr_pstrdup(r->pool, vals[i]); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " %d apacheServerName %s", i, reqc->name); - } - - if(strcasecmp(attributes[i], "apacheServerAdmin") == 0) { - reqc->admin = apr_pstrdup(r->pool, vals[i]); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " %d apacheServerAdmin %s", i, reqc->admin); - } - - if(strcasecmp(attributes[i], "apacheDocumentRoot") == 0) { - reqc->docroot = apr_pstrdup(r->pool, vals[i]); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " %d apacheDocumentRoot %s", i, reqc->docroot); - } - - if(strcasecmp(attributes[i], "apacheSuexecUid") == 0) { - reqc->uid = apr_pstrdup(r->pool, vals[i]); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " %d apacheSuexecUid %s", i, reqc->uid); - } - - if(strcasecmp(attributes[i], "apacheSuexecGid") == 0) { - reqc->gid = apr_pstrdup(r->pool, vals[i]); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " %d apacheSuexecGid %s", i, reqc->gid); - } - - if(strcasecmp(attributes[i], "apacheExtConfigHasRequireLine") == 0) { - if(vals[i]) { - reqc->has_reqlines = strcasecmp("TRUE", apr_pstrdup(r->pool, vals[i])) == 0 ? 1 : 0; - - if(reqc->has_reqlines) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " %d Vhost %s has extended access configuration", i, reqc->name); - } - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " %d Vhost %s doesn't have extended access configuration", i, reqc->name); - } - } - - if(strcasecmp(attributes[i], "apacheServerAlias") == 0) { - if(vals[i]) { - reqc->serveralias = - (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i], - (const char *) ";"); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " %d apacheServerAlias is set", i); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " %d No apacheServerAlias for this vhost found", i); - reqc->serveralias = NULL; - } - } - - if(strcasecmp(attributes[i], "apacheLocationOptionsDn") == 0) { - if(vals[i]) { - reqc->rqlocationlines = - (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i], - (const char *) ";"); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " %d apacheLocationOptionsDn is set", i); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " host %s marked ext-configured but no attributes pointing extConfig !! ldap scheme should avoid it !!", reqc->name); - reqc->rqlocationlines = NULL; - } - } - i++; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering vhost configuration"); + /* + * we got 10 attributes to search for, counting from 0 to 9 + */ + int i; + for ( i = 0; i <= 9; i++ ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " VhostConfig Iteration %d :: will get %s", i, attributes[i]); + switch (i) { + /* 0 apacheServerName */ + case 0: reqc->name = apr_pstrdup(r->pool, vals[i]); break; + /* 1 apacheServerAlias - may be null */ + case 1: reqc->serveralias = (vals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i],(const char *) ";") : NULL; break; + /* 2 apacheDocumentRoot */ + case 2: reqc->docroot = apr_pstrdup(r->pool, vals[i]); break; + /* 3 apacheSuexecUid */ + case 3: reqc->uid = (vals[i]) ? apr_pstrdup(r->pool, vals[i]) : reqc->uid ; break; + /* 4 apacheSuexecGid */ + case 4: reqc->gid = (vals[i]) ? apr_pstrdup(r->pool, vals[i]): reqc->gid ; break; + /* 5 apacheServerAdmin */ + case 5: reqc->admin = (vals[i]) ? apr_pstrdup(r->pool, vals[i]) : NULL ; break; + /* 6 apacheExtConfigHasRequireLine */ + //if there's no HasRequireLine attribute set we assume we don't have reqlines + case 6: reqc->has_reqlines = (vals[i] && strcasecmp("TRUE", apr_pstrdup(r->pool, vals[i])) == 0) ? 1 : 0; break; + /* 7 apacheLocationOptionsDn */ + case 7: reqc->rqlocationlines = (vals[i]) ? reqc->rqlocationlines = (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i], (const char *) ";") : NULL ; break; + /* 8 apacheAliasesConfigEnabled */ + case 8: reqc->has_aliaslines = ( vals[i] && strcasecmp("TRUE", apr_pstrdup(r->pool, vals[i])) == 0 ) ? 1 : 0; break; + /* 9 apacheAliasConfigOptionsDn */ + case 9: reqc->aliaseslines = (vals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, vals[i], (const char *) ";") : NULL; + } } - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " dovhostconfig Leaving "); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving vhost configuration , exit assignments: "); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheServerName \'%s\'", reqc->name); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheServerAdmin \'%s\'", reqc->admin); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheDocumentRoot \'%s\'", reqc->docroot); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheSuexecUid \'%s\'", reqc->uid); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, " apacheSuexecGid \'%s\'", reqc->gid); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + (reqc->has_reqlines && reqc->rqlocationlines ) ? + apr_pstrdup(r->pool, "vhost \'%s\' has access control") : + apr_pstrdup(r->pool, " vhost \'%s\' doesn't have access control"), + reqc->name); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + (reqc->has_aliaslines && reqc->has_aliaslines ) ? + apr_pstrdup(r->pool, "vhost \'%s\' has dir aliases") : + apr_pstrdup(r->pool, " vhost \'%s\' doesn't have dir aliases"), + reqc->name); } -static void mod_vhost_ldap_doextconfig(request_rec * r, char *extconfigattributes[], const char **extconfvals, - mod_vhost_ldap_extconfig_object_t * extreqc) +/******************************************************************/ +static void mvhl_doextconfig(request_rec * r, char *extconfigattributes[], const char **extconfvals, mvhl_extconfig_object * extreqc) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " doextconfig Entering "); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering Access Control config"); + /* + * we got 6 attributes to search for, counting from 0 to 5 + */ int i = 0; - - while(extconfigattributes[i]) { - if(strcasecmp(extconfigattributes[i], "apacheExtConfigObjectName") == 0) { - extreqc->extconfname = apr_pstrdup(r->pool, extconfvals[i]); - } - - if(strcasecmp(extconfigattributes[i], "apacheExtConfigUri") == 0) { - extreqc->exturi = apr_pstrdup(r->pool, extconfvals[i]); - } - - if(strcasecmp(extconfigattributes[i], "apacheExtConfigRequireValidUser") == 0) { - if(extconfvals[i]) { - - //this value determines whether we have "require valid-user" object (TRUE) , - //or (FALSE) object "require user johny mary dorothy witch" - //here set retrieved value, regardless what it is, to play with it later. - extreqc->extconftype = - strcasecmp("TRUE", apr_pstrdup(r->pool, extconfvals[i])) == 0 ? 1 : 0; - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Set require valid-user to %d (%s)", extreqc->extconftype, (char *) apr_pstrdup(r->pool, extconfvals[i])); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " For this ext config require valid-user is not set"); - } - } - - if(strcasecmp(extconfigattributes[i], "apacheExtConfigServerName") == 0) { - - if(extconfvals[i]) { - extreqc->extservername = - (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], - (const char *) ";"); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - " No ExtServerName values found"); - extreqc->extservername = NULL; - } - } - - if(strcasecmp(extconfigattributes[i], "apacheExtConfigUserDn") == 0) { - - if(extconfvals[i]) { - extreqc->extusers = - (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], - (const char *) ";"); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - " apacheExtConfigUserDn values NOT found (any valid-user or no users specified."); - extreqc->extusers = NULL; - } - } - - i++; + for ( i = 0; i <= 4; i++ ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Vhost Access Control Iteration %d :: will get %s", i, extconfigattributes[i]); + switch (i) { + /* 0 apacheExtConfigUri */ + case 0: extreqc->exturi = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL ; break; + /* 1 apacheExtConfigRequireValidUser + * this value determines whether we have "require valid-user" object (TRUE) , + * or (FALSE) object "require user johny mary dorothy witch" + * here set retrieved value, regardless what it is, to play with it later. + */ + case 1: extreqc->extconftype = (extconfvals[i] && strcasecmp("TRUE", apr_pstrdup(r->pool, extconfvals[i])) == 0) ? 1 : 0; break; + /* 2 apacheExtConfigServerName */ + case 2: extreqc->extservername = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL ; break; + /* 3 apacheExtConfigObjectName */ + case 3: extreqc->extconfname = apr_pstrdup(r->pool, extconfvals[i]); break; + /* 4 apacheExtConfigUserDn */ + case 4: + extreqc->extusers = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL; break; + /* 5 apacheExtConfigPath */ + case 5: + extreqc->extdir = (extconfvals[i]) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extconfvals[i], (const char *) ";") : NULL ; break; + } } - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " doextconfig Leaving "); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving Access Control config :: exit assignments"); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " This Access Object prompt is \'%s\'", extreqc->extconfname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, + (extreqc->exturi ) ? + apr_pstrdup(r->pool, " \'%s\' extConfigUri has at least one URI value") : + apr_pstrdup(r->pool, " \'%s\' has extConfigUri assigned"), + extreqc->extconfname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, + (extreqc->extdir ) ? + apr_pstrdup(r->pool, " \'%s\' extConfigPath has at least one directory value") : + apr_pstrdup(r->pool, " \'%s\' has extConfig assigned"), + extreqc->extconfname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + (extreqc->extconftype) ? + apr_pstrdup(r->pool, " \'%s\' requires valid-user") : + apr_pstrdup(r->pool, " \'%s\' requires user from userlist"), + extreqc->extconfname) ; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + (extreqc->extservername ) ? + apr_pstrdup(r->pool, " \'%s\' has at least one serverName assigned") : + apr_pstrdup(r->pool, " \'%s\' has no assigned serverNames"), + extreqc->extconfname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + (extreqc->extusers ) ? + apr_pstrdup(r->pool, " \'%s\' has at least one webuser object assigned") : + apr_pstrdup(r->pool, " \'%s\' has no assigned webusers objects"), + extreqc->extconfname ); + } -static void mod_vhost_ldap_doextuserconfig(request_rec * r, char *ldap_webuser_attributes[], const char **extuservals, - mod_vhost_ldap_webuser_t * extuserreqc) +/******************************************************************/ +static void mvhl_doextuserconfig(request_rec * r, char *ldap_webuser_attributes[], const char **extuservals, mvhl_webuser * extuserreqc) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " doextuserconfig Entering"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering extwebuser Config"); + /* + * we got 5 attributes to search for, counting from 0 to 4 + */ int i = 0; - while(ldap_webuser_attributes[i]) { - if(strcasecmp(ldap_webuser_attributes[i], "apacheExtConfigUserName") == 0) { + for ( i = 0; i <= 4; i++ ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Web user Iteration %d :: will get %s", i, ldap_webuser_attributes[i]); + switch (i) { + /* 0 apacheExtConfigUserName */ + case 0: extuserreqc->webusername = apr_pstrdup(r->pool, extuservals[i]); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "%d apacheExtConfigUserName set to %s", i, extuserreqc->webusername); + break; + /* 1 apacheExtConfigUserServerName */ + case 1: + extuserreqc->webuserserver = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; + break; + /* 2 userPassword */ + case 2: + extuserreqc->webuserpassword = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; + break; + /* 3 apacheExtConfigUserDirectoryName */ + case 3: + extuserreqc->webuserdirectory = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; + break; + case 4: + /* apacheExtConfigUserLocationUri */ + extuserreqc->webuserlocationuri = ( extuservals[i] ) ? (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], (const char *) ";") : NULL; + break; + } - if(strcasecmp(ldap_webuser_attributes[i], "apacheExtConfigUserServerName") == 0) { - extuserreqc->webuserserver = apr_pstrdup(r->pool, extuservals[i]); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "%d apacheExtConfigUserServerName set to %s", i, extuserreqc->webuserserver); - } - if(strcasecmp(ldap_webuser_attributes[i], "userPassword") == 0) { - extuserreqc->webuserpassword = - (apr_array_header_t *) get_parsed_string_atrr_arr(r, extuservals[i], - (const char *) ";"); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "%d userPassword retrievied", i); + } + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving extwebuser Config :: exit assignments"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " This webuser name is \'%s\'", extuserreqc->webusername); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + ( extuserreqc->webuserserver ) ? + apr_pstrdup(r->pool, " \'%s\' has at least one server assigned") : + apr_pstrdup(r->pool, " \'%s\' has no serverNames assigned"), + extuserreqc->webusername ); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + ( extuserreqc->webuserpassword ) ? + apr_pstrdup(r->pool, " \'%s\' has at least one password assigned") : + apr_pstrdup(r->pool, " \'%s\' has no passwords assigned"), + extuserreqc->webusername ); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + ( extuserreqc->webuserdirectory ) ? + apr_pstrdup(r->pool, " \'%s\' has at least one physical directory assigned") : + apr_pstrdup(r->pool, " \'%s\' has no physical directories assigned"), + extuserreqc->webusername ); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + /* following three lines evaluates to one string in which final argument (fourth line) is substituted */ + ( extuserreqc->webuserlocationuri ) ? + apr_pstrdup(r->pool, " \'%s\' has at least one location assigned") : + apr_pstrdup(r->pool, " \'%s\' has no locations assigned"), + extuserreqc->webusername ); + +} +/******************************************************************/ +static void mvhl_doaliasesconfig(request_rec * r, char *aliases_attributes[], const char **aliasesvals, mvhl_aliasconf_object * aliasreqc){ + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering aliasObject Config"); + /* + * we got 4 attributes to search for, counting from 0 to 3 + */ + int i = 0; + + for (i = 0; i <= 3; i++ ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Alias config Iteration %d :: will get %s", i, aliases_attributes[i]); + switch (i) { + /* 0 apacheAliasConfigSourceUri */ + case 0: + aliasreqc->aliassourceuri = (apr_array_header_t *) get_parsed_string_atrr_arr(r, aliasesvals[i], (const char *) ";"); + //aliasreqc->aliassourceuri = apr_pstrdup(r->pool, aliasesvals[i]); + break; + /* 1 apacheAliasConfigServerName - MULTI-VALUE */ + case 1: + aliasreqc->aliasconfservername = (apr_array_header_t *) get_parsed_string_atrr_arr(r, aliasesvals[i], (const char *) ";"); + break; + /* 2 apacheAliasConfigTargetDir */ + case 2: + aliasreqc->aliastargetdir = apr_pstrdup(r->pool, aliasesvals[i]); + break; + /* 3 apacheAliasConfigObjectName */ + case 3: + aliasreqc->aliasconfname = apr_pstrdup(r->pool, aliasesvals[i]); + break; } - i++; } - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " doextuserconfig Leaving"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Leaving alias Config :: exit assignments"); + /* defined ldap schema force alias object to have all of these attributes, so there's no way for existing object without any of them*/ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " This alias config object name is \'%s\'", aliasreqc->aliasconfname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " \'%s\' has at least one SourceUri assigned", aliasreqc->aliasconfname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " \'%s\' target dir is \'%s\'", aliasreqc->aliasconfname, aliasreqc->aliastargetdir); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, apr_pstrdup(r->pool, " \'%s\' has at least one serverName assigned"), aliasreqc->aliasconfname ); } -static int mod_vhost_ldap_authenticate_basic_user(request_rec * r) +/******************************************************************/ +static int mvhl_authenticate_basic_user(request_rec * r) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering mvhl_authenticate_basic_user"); const char *sent_pw; - mod_vhost_ldap_webuser_t *extuserreqc; - extuserreqc = (mod_vhost_ldap_webuser_t *) apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_webuser_t)); + mvhl_webuser *extuserreqc; + extuserreqc = (mvhl_webuser *) apr_pcalloc(r->pool, sizeof(mvhl_webuser)); int rc = ap_get_basic_auth_pw(r, &sent_pw); - if(rc != OK) - return rc; + if(rc != OK) return rc; + if(strtrue(r->user) && strtrue(sent_pw)) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " Entering mod_vhost_ldap_authenticate_basic_user"); - + int result = 0; char userfilter[FILTER_LENGTH]; - mod_vhost_ldap_config_t *conf = - (mod_vhost_ldap_config_t *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); - const char *dn = NULL; - util_ldap_connection_t *ldc = NULL; const char **extuservals = NULL; - int result = 0; - char *ldap_webuser_attributes[] = - { "apacheExtConfigUserName", "apacheExtConfigUserServerName", "userPassword", 0 }; - - apr_snprintf(userfilter, FILTER_LENGTH, "(&(apacheExtConfigUserName=%s)(apacheExtConfigUserServerName=%s))", r->user,r->server->server_hostname); + util_ldap_connection_t *ldc = NULL; + char *ldap_webuser_attributes[] = { "apacheExtConfigUserName", "apacheExtConfigUserServerName", "userPassword", 0 }; + mvhl_config *conf = (mvhl_config *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); + apr_snprintf(userfilter, FILTER_LENGTH, "(&(apacheExtConfigUserName=%s))", r->user); ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " AuthUser search filter: %s", userfilter); - ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw, conf->deref, - conf->secure); - result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wucbasedn, conf->scope, - ldap_webuser_attributes, userfilter, &dn, &extuservals); + ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw, conf->deref, conf->secure); + result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wucbasedn, conf->scope, ldap_webuser_attributes, userfilter, &dn, &extuservals); util_ldap_connection_close(ldc); if(extuservals) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, " User %s found.", r->user); - mod_vhost_ldap_doextuserconfig(r, ldap_webuser_attributes, extuservals, extuserreqc); + mvhl_doextuserconfig(r, ldap_webuser_attributes, extuservals, extuserreqc); int x = 0; + //we're checking for each password - if any matches, then we return immediately char **passwords = (char **) extuserreqc->webuserpassword->elts; + for (x = 0; x < extuserreqc->webuserpassword->nelts; x++) { - if ( ( apr_password_validate(sent_pw, passwords[x]) == OK) || strcasecmp(sent_pw,passwords[x]) == 0 ) { - ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Authentication for user %s at %s successful.", extuserreqc->webusername, r->server->server_hostname); - return OK; + if ( apr_password_validate(sent_pw, passwords[x]) == OK ) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " APR authentication for user %s at %s successful.", extuserreqc->webusername, r->server->server_hostname); + return OK; + } + + char *prefix = "{CRYPT}"; + int prefixlen = 7; + if ( strcasecmp( apr_pstrndup(r->pool, passwords[x], prefixlen ), prefix ) == 0 ) { + char *stripped = passwords[x] + prefixlen; + char *userinputhash = pw_encrypt (sent_pw, stripped ); + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " User entered: \'%s\' ", sent_pw ); + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Retrieved value: \'%s\'", passwords[x] ); + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Retrieved value (stripped): \'%s\'", stripped ); + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " User input hash: \'%s\'", userinputhash ); + if ( strcasecmp( userinputhash , stripped ) == 0 ) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Unix authentication for user %s at %s successful.", extuserreqc->webusername, r->server->server_hostname); + return OK; + } + } + + if ( strcasecmp(sent_pw,passwords[x]) == 0 ) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, " Clear text authentication for user %s at %s successful.", extuserreqc->webusername, r->server->server_hostname); + return OK; } } - } else { ap_log_rerror(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, 0, r, " User %s at %s not found", extuserreqc->webusername, r->server->server_hostname); @@ -451,7 +438,8 @@ static int mod_vhost_ldap_authenticate_basic_user(request_rec * r) return HTTP_UNAUTHORIZED; } -static int check_mod_vhost_ldap_auth_require(char *user, const char *t, request_rec * r) +/******************************************************************/ +static int check_mvhl_auth_require(char *user, const char *t, request_rec * r) { const char *w; w = ap_getword(r->pool, &t, ' '); @@ -476,13 +464,14 @@ static int check_mod_vhost_ldap_auth_require(char *user, const char *t, request_ return HTTP_INTERNAL_SERVER_ERROR; } ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - ": %s : Reached end of check_mod_vhost_ldap_auth_require!", r->server->server_hostname); + ": %s : Reached end of check_mvhl_auth_require!", r->server->server_hostname); return HTTP_INTERNAL_SERVER_ERROR; } -static int mod_vhost_ldap_check_auth(request_rec * r) +/******************************************************************/ +static int mvhl_check_auth(request_rec * r) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - ": mod_vhost_ldap_check_auth, parsing existing ap_requires for %s at %s ", r->user, r->server->server_hostname); + ": mvhl_check_auth, parsing existing ap_requires for %s at %s ", r->user, r->server->server_hostname); char *user = r->user; int rv; register int x; @@ -494,7 +483,7 @@ static int mod_vhost_ldap_check_auth(request_rec * r) for (x = 0; x < reqs_arr->nelts; x++) { t = reqs[x].requirement; - if((rv = check_mod_vhost_ldap_auth_require(user, t, r)) != HTTP_UNAUTHORIZED) { + if((rv = check_mvhl_auth_require(user, t, r)) != HTTP_UNAUTHORIZED) { return rv; } } @@ -503,28 +492,47 @@ static int mod_vhost_ldap_check_auth(request_rec * r) ap_note_basic_auth_failure(r); return HTTP_UNAUTHORIZED; } -static void *mod_vhost_ldap_create_server_config(apr_pool_t * p, server_rec * s) +/******************************************************************/ +static void *mvhl_create_sconfig(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; + //ldap://host[:port]/basedn[?attrib[?scope[?filter]]] + mvhl_config *conf = (mvhl_config *) apr_pcalloc(p, sizeof(mvhl_config)); + conf->enabled = 0; conf->have_ldap_url = 0; - conf->have_deref = 0; - conf->binddn = NULL; - conf->bindpw = NULL; - conf->deref = always; - conf->wlcbasedn = NULL; - conf->wucbasedn = NULL; - + conf->have_deref = 0; + conf->scope = LDAP_SCOPE_SUBTREE; + conf->deref = never; + conf->host = NULL; + conf->port = 389; + conf->url = NULL; + conf->filter = NULL; + conf->binddn = NULL; + conf->bindpw = NULL; + conf->basedn = NULL; + conf->wlcbasedn = NULL; + conf->wucbasedn = NULL; + conf->aliasesbasedn = NULL; + conf->fallback = NULL; + conf->secure = 0; + conf->alias_enabled = 0; + conf->loc_auth_enabled = 0; + conf->dir_auth_enabled = 0; return conf; } -static void *mod_vhost_ldap_merge_server_config(apr_pool_t * p, void *parentv, void *childv) +/******************************************************************/ +static void *mvhl_merge_sconfig(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 ? parent->enabled : child->enabled); + mvhl_config *parent = (mvhl_config *) parentv; + mvhl_config *child = (mvhl_config *) childv; + mvhl_config *conf = (mvhl_config *) apr_pcalloc(p, sizeof(mvhl_config)); + + conf->enabled = (child->enabled ? child->enabled : parent->enabled); + 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->alias_enabled = (child->alias_enabled ? child->alias_enabled : parent->alias_enabled); + conf->loc_auth_enabled = (child->loc_auth_enabled ? child->loc_auth_enabled : parent->loc_auth_enabled); + conf->dir_auth_enabled = (child->dir_auth_enabled ? child->dir_auth_enabled : parent->dir_auth_enabled); if(child->have_ldap_url) { conf->have_ldap_url = child->have_ldap_url; @@ -537,8 +545,10 @@ static void *mod_vhost_ldap_merge_server_config(apr_pool_t * p, void *parentv, v conf->secure = child->secure; conf->wlcbasedn = child->wlcbasedn; conf->wucbasedn = child->wucbasedn; + conf->aliasesbasedn = child->aliasesbasedn; } - else { + else + { conf->have_ldap_url = parent->have_ldap_url; conf->url = parent->url; conf->host = parent->host; @@ -549,43 +559,41 @@ static void *mod_vhost_ldap_merge_server_config(apr_pool_t * p, void *parentv, v conf->secure = parent->secure; conf->wlcbasedn = parent->wlcbasedn; conf->wucbasedn = parent->wucbasedn; - + conf->aliasesbasedn = parent->aliasesbasedn; } if(child->have_deref) { conf->have_deref = child->have_deref; conf->deref = child->deref; } - else { + 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); return conf; } -static const char *mod_vhost_ldap_parse_url(cmd_parms * cmd, void *dummy, const char *url) +/******************************************************************/ +static const char *conf_mvhl_url(cmd_parms * cmd, void *dummy, const char *url) { int result; apr_ldap_url_desc_t *urld; - mod_vhost_ldap_config_t *conf = - (mod_vhost_ldap_config_t *) ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); - + mvhl_config *conf = (mvhl_config *) ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); 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"; + case LDAP_URL_ERR_MEM: return "0x01 can't allocate memory space"; + case LDAP_URL_ERR_PARAM: return "0x02 parameter is bad"; + case LDAP_URL_ERR_BADSCHEME: return "0x03 URL doesn't begin with ldap[si]://"; + case LDAP_URL_ERR_BADENCLOSURE: return "0x04 URL is missing trailing >"; + case LDAP_URL_ERR_BADURL: return "0x05 URL is bad"; + case LDAP_URL_ERR_BADHOST: return "0x06 host port is bad"; + case LDAP_URL_ERR_BADATTRS: return "0x07 bad (or missing) attributes"; + case LDAP_URL_ERR_BADSCOPE: return "0x08 scope string is invalid (or missing)"; + case LDAP_URL_ERR_BADFILTER: return "0x09 bad or missing filter"; + case LDAP_URL_ERR_BADEXTS: return "0x0a bad or missing extensions"; + default: return "Could not parse LDAP URL"; } } conf->url = apr_pstrdup(cmd->pool, url); @@ -601,6 +609,7 @@ static const char *mod_vhost_ldap_parse_url(cmd_parms * cmd, void *dummy, const 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; @@ -608,7 +617,8 @@ static const char *mod_vhost_ldap_parse_url(cmd_parms * cmd, void *dummy, const if(urld->lud_filter) { if(urld->lud_filter[0] == '(') { /* - * Get rid of the surrounding parens; later on when generating the + * Get rid of the surrounding parentheses; + * later on when generating the * filter, they'll be put back. */ conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter + 1); @@ -618,9 +628,9 @@ static const char *mod_vhost_ldap_parse_url(cmd_parms * cmd, void *dummy, const conf->filter = apr_pstrdup(cmd->pool, urld->lud_filter); } } - else { + /*else { conf->filter = "objectClass=apacheConfig"; - } + }*/ /* "ldaps" indicates secure ldap connections desired */ @@ -638,409 +648,462 @@ static const char *mod_vhost_ldap_parse_url(cmd_parms * cmd, void *dummy, const apr_ldap_free_urldesc(urld); 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_wucbasedn(cmd_parms * cmd, void *dummy, const char *wucbasedn) -{ - mod_vhost_ldap_config_t *conf = - (mod_vhost_ldap_config_t *) ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); - conf->wucbasedn = apr_pstrdup(cmd->pool, wucbasedn); - return NULL; -} -static const char *mod_vhost_ldap_set_wlcbasedn(cmd_parms * cmd, void *dummy, const char *wlcbasedn) -{ - - mod_vhost_ldap_config_t *conf = - (mod_vhost_ldap_config_t *) ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); - conf->wlcbasedn = apr_pstrdup(cmd->pool, wlcbasedn); - 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(deref) { - if(strcmp(deref, "never") == 0 || strcmp(deref, "searching") == 0 || strcmp(deref, "finding") == 0 - || strcmp(deref, "always") == 0) { - conf->deref = *deref; - conf->have_deref = 1; - } - else { - return "Unrecognized value for VhostLDAPAliasDereference directive"; +/******************************************************************/ +static const char *conf_mvhl(cmd_parms *cmd, void *dummy, const char *confval) { + + if ( strlen(confval) == 0 ) { return NULL; } + + { + //we're getting currently set (or default from mvhl_create_config if not set already) + mvhl_config *conf = (mvhl_config *) ap_get_module_config(cmd->server->module_config, &vhost_ldap_module); + int *cmdtype = (int *) cmd->info; + char *currval = apr_pstrdup(cmd->pool, confval); + switch (*cmdtype) { + case 1: + conf->enabled = ( strcmp(currval,"On") == 0 )? 1 : 0; + break; + case 2: + conf->binddn = currval; + break; + case 3: + conf->bindpw = currval; + break; + case 4: + //const values: never = 0, searching = 1, finding = 2, always = 3 + if ( strcmp(currval,"never") == 0 ) { conf->deref = never; conf->have_deref = 1;} + if ( strcmp(currval,"searching")== 0 ) { conf->deref = searching; conf->have_deref = 1;} + if ( strcmp(currval,"finding") == 0 ) { conf->deref = finding; conf->have_deref = 1;} + if ( strcmp(currval,"always") == 0 ) { conf->deref = always; conf->have_deref = 1;} + break; + case 5: + conf->wlcbasedn = currval; + break; + case 6: + conf->wucbasedn = currval; + break; + case 7: + conf->fallback = currval; + break; + case 8: + conf->aliasesbasedn = currval; + break; + case 9: + conf->alias_enabled = ( strcmp(currval,"On") == 0 )? 1 : 0 ; + break; + case 10: + conf->loc_auth_enabled = ( strcmp(currval,"On") == 0 )? 1 : 0; + break; + case 11: + conf->dir_auth_enabled = ( strcmp(currval,"On") == 0 )? 1 : 0; + break; } + return NULL; } - return NULL; + } +/******************************************************************/ +static int apply_vhost(mvhl_config *conf, const char *hostname, request_rec * r, util_ldap_connection_t *ldc, const char *dn, mvhl_request *reqc ) { - - -static int mod_vhost_ldap_translate_name(request_rec * r) -{ char filtbuf[FILTER_LENGTH]; - char extconffiltbuf[FILTER_LENGTH]; - apr_table_t *e; - request_rec *top; - mod_vhost_ldap_config_t *conf; - mod_vhost_ldap_request_t *reqc; - mod_vhost_ldap_extconfig_object_t *extreqc; - core_server_config *core; - - util_ldap_connection_t *ldc = NULL; - const char **vals, **extconfvals = NULL; - const char *dn = NULL; - const char *hostname = NULL; - int failures = 0; - int i = 0; - int result = 0; - - /* - * more info about attributes in typedefs definitions and schema desc - * PS. Did You ever wonder why they used this damned weird "\0", instead, - * let's say, '$' or 'EndOfWord' or whatever ?? - */ - - char *attributes[] = { "apacheServerName", "apacheServerAlias", "apacheDocumentRoot", - "apacheSuexecUid", "apacheSuexecGid", "apacheServerAdmin", - "apacheExtConfigHasRequireLine", "apacheLocationOptionsDn", - 0 - }; - - char *extconfigattributes[] = { "apacheExtConfigUri", "apacheExtConfigRequireValidUser", - "apacheExtConfigServerName", "apacheExtConfigObjectName", - "apacheExtConfigUserDn", - 0 - }; - - //we assume we're in trouble, and will change it, if not. - result = LDAP_SERVER_DOWN; - - top = r->main ? r->main : r; - hostname = r->hostname; - - //get our module config options - conf = (mod_vhost_ldap_config_t *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); - - //a reference to core config - core = (core_server_config *) ap_get_module_config(r->server->module_config, &core_module); - - //and some variable initialization - reqc = (mod_vhost_ldap_request_t *) apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_request_t)); - extreqc = (mod_vhost_ldap_extconfig_object_t *) apr_pcalloc(r->pool, sizeof(mod_vhost_ldap_extconfig_object_t)); - - //current request config get set - 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; - } - - if(conf->host) { - - apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", - conf->filter, hostname, hostname); - - while(failures++ <= 5 && result == LDAP_SERVER_DOWN) { - //searching for connection - ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw, - conf->deref, conf->secure); - result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope, attributes, - filtbuf, &dn, &vals); - util_ldap_connection_close(ldc); - } - } - else { - return DECLINED; + apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Server search filter: %s", filtbuf); + const char **vals = NULL; + char *attributes[] = { "apacheServerName", "apacheServerAlias", "apacheDocumentRoot", "apacheSuexecUid","apacheSuexecGid","apacheServerAdmin","apacheExtConfigHasRequireLine","apacheLocationOptionsDn","apacheAliasesConfigEnabled","apacheAliasConfigOptionsDn",0 }; + int failures = 0; + int result = LDAP_SERVER_DOWN; + while(failures++ <= 5 && result == LDAP_SERVER_DOWN) { + result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope, attributes, filtbuf, &dn, &vals); } + /* + * we don't test conf->host nor connection, because if these failed, declined was already returned + * instead, we do a search for specified fallback vhost + */ + if ( result == LDAP_NO_SUCH_OBJECT ) + { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Vhost %s not found, will try to fall-back to defined vhost: %s", hostname, conf->fallback); + hostname = conf->fallback; + apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(|(apacheServerName=%s)(apacheServerAlias=%s)))", conf->filter, hostname, hostname); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Server search filter: %s", filtbuf); + result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->basedn, conf->scope, attributes, filtbuf, &dn, &vals); + } + if(result != LDAP_SUCCESS) { - return DECLINED; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Vhost %s defined as fallback not found, err %s", hostname, ldap_err2string(result)); + return 0; } reqc->dn = apr_pstrdup(r->pool, dn); + if (vals) { mvhl_dovhostconfig(r, attributes, vals, reqc); } - if(vals) { - //this translate_name function we're in is long enough, don't You think? - //we set all into reqc struct - mod_vhost_ldap_dovhostconfig(r, attributes, vals, reqc); - } - - if((reqc->name == NULL) || (reqc->docroot == NULL)) { - - return DECLINED; - } + if( (reqc->name == NULL) || (reqc->docroot == NULL) || ! (r->uri[0] == '/') ) return 0; + r->filename = apr_pstrcat(r->pool, reqc->docroot, r->uri, NULL); + return 1; + +} +/******************************************************************/ +static void apply_aliasing(mvhl_request *reqc, request_rec * r, mvhl_config *conf, util_ldap_connection_t *ldc, const char *dn) { + + if(reqc->has_aliaslines == 1 && reqc->aliaseslines ) { + const char **aliasesconfvals = NULL; + char aliasesfilter[FILTER_LENGTH]; + char *aliases_attributes[] = { "apacheAliasConfigSourceUri", "apacheAliasConfigServerName", "apacheAliasConfigTargetDir", "apacheAliasConfigObjectName",0 }; + mvhl_aliasconf_object *aliasreqc = (mvhl_aliasconf_object *) apr_pcalloc(r->pool, sizeof(mvhl_aliasconf_object)); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has alias configuration, need to check if for current uri"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Original r->filename: %s", r->filename); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Original r->uri: %s", r->uri); + int i = 0; + int result = 0; - if(r->uri[0] == '/') { - r->filename = apr_pstrcat(r->pool, reqc->docroot, r->uri, NULL); - } - else { - return DECLINED; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering Alias Objects search"); + while(i <= strlen(apr_pstrdup(r->pool, r->uri)) && !aliasesconfvals ) { + i++; + char *aliasbuff = apr_pstrndup(r->pool, r->uri, i); + apr_snprintf(aliasesfilter, FILTER_LENGTH,"(&(%s)(apacheAliasConfigServerName=%s)(apacheAliasConfigSourceUri=%s))", conf->filter, reqc->name, aliasbuff); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Alias Object search filter: %s", aliasesfilter); + /* we reuse ldap connection opened previously with alias entries, + * access control entries and webusers entries searches changing used filter as needed (!!) */ + result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->aliasesbasedn, conf->scope, aliases_attributes, aliasesfilter, &dn, &aliasesconfvals); + } + + if(result != LDAP_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost aliases config, but probably not for this URI, alias config entry not found"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Tried with ldap search filter: %s", aliasesfilter); + } + else { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This uri has aliases config, configuration object found"); + if(aliasesconfvals) { mvhl_doaliasesconfig(r, aliases_attributes, aliasesconfvals, aliasreqc); } + ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Entering alias substitution"); + r->filename = apr_pstrcat (r->pool, aliasreqc->aliastargetdir , r->uri + i, NULL); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Final filename r->filename: %s", r->filename); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Final uri (unchanged) r->uri: %s", r->uri); + } + } + else + { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "This vhost has no aliases, or it is disabled via apacheAliasesConfigEnabled = (FALSE|not set) skipping.."); + } +} +/******************************************************************/ +static void apply_location_access_control(mvhl_request *reqc, request_rec * r, mvhl_config *conf, util_ldap_connection_t *ldc, const char *dn) { if(reqc->has_reqlines == 1 && reqc->rqlocationlines) { - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "This vhost has access control configured, need to check if it's enabled for current uri"); - result = 0; - i = 0; - - //we have mercy, and do not open a connection for each uri search ;) - - ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw, conf->deref, - conf->secure); - - //ask Your programming teacher, what's all about with - // these "NO, TRY _VERY_ HARD, AND THEN TRY AGAIN _NOT_ TO USE BREAK FOR LOOP LEAVING" ;) - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extConfig Objects search"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has location access control configured, need to check if it's enabled for current uri"); + int result = 0; + int i = 0; + char extconffiltbuf[FILTER_LENGTH]; + const char **extconfvals = NULL; + char *extconfigattributes[] = { "apacheExtConfigUri","apacheExtConfigRequireValidUser","apacheExtConfigServerName","apacheExtConfigObjectName","apacheExtConfigUserDn","apacheExtConfigPath",0}; + mvhl_extconfig_object *extreqc = (mvhl_extconfig_object *) apr_pcalloc(r->pool, sizeof(mvhl_extconfig_object)); + char *buff = NULL; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extConfig Location Objects search"); while(i <= strlen(apr_pstrdup(r->pool, r->uri)) && !extconfvals) { i++; - char *buff = apr_pstrndup(r->pool, r->uri, i); - //ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Searching for hostname %s and URI %s, origname is %s", hostname, buff, reqc->name); - //uncomment this, if You'd like to see in log how uri gets checked - //ap_log_error(APLOG_MARK,APLOG_DEBUG,OK,NULL,"%s", buff); - - //well, we must had been connecting already, so we don't do more ldap server connection checks, - //and we're doing a search with cache_getuser instead of using extConfigObject dn apacheConfig object attribute value(s), - //because there's no convenient function in apr api. - //vhost location RDN attribute is used actually by some GUI to make things easier - //TODO: use some generic ldap functions (?) classic search or implement more ldap routines for apr - - //so, we do a search below locationDnBase for config object with matches current hostname and uri.. - //note, that we took our current uri, and we're searching starting from / adding one by one chararacter - //to match config object - access config is always the same as first matching upper url access config. - //and more - if someone defined accessobject for /main and /main/subdir, the first one is used. - //when upper is deleted - next below is returned, and so far.. - //and more - if there are two or more extConfig object for the same combination of server/uri, - //then first found is returned and search isn't processed further. - - //we do a search based on original reqc->name instead of current hostname, to apply rules even if we're accessing - //site via ServerAlias name - apr_snprintf(extconffiltbuf, FILTER_LENGTH, - "(&(apacheExtConfigServerName=%s)(apacheExtConfigUri=%s))", reqc->name, buff); - - result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wlcbasedn, conf->scope, - extconfigattributes, extconffiltbuf, &dn, &extconfvals); - + buff = apr_pstrndup(r->pool, r->uri, i); + /* + * ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Searching for hostname %s and URI %s, origname is %s", hostname, buff, reqc->name); + * uncomment this, if You'd like to see in log how uri gets checked + * ap_log_error(APLOG_MARK,APLOG_DEBUG,OK,NULL,"%s", buff); + + * well, we must had been connecting already, so we don't do more ldap server connection checks, + * and we're doing a search with cache_getuser instead of using extConfigObject dn apacheConfig object attribute value(s), + * because there's no convenient function in apr api. + * vhost location RDN attribute is used actually by some GUI to make things easier + * TODO: use some generic ldap functions (?) classic search or implement more ldap routines for apr + + * so, we do a search below locationDnBase for config object with matches current hostname and uri.. + * note, that we took our current uri, and we're searching starting from / adding one by one chararacter + * to match config object - access config is always the same as first matching upper url access config. + * and more - if someone defined accessobject for /main and /main/subdir, the first one is used. + * when upper is deleted - next below is returned, and so far.. + * and more - if there are two or more extConfig object for the same combination of server/uri, + * then first found is returned and search isn't processed further. + + * we do a search based on original reqc->name instead of current hostname, to apply rules even if we're accessing + * site via ServerAlias name + */ + apr_snprintf(extconffiltbuf, FILTER_LENGTH,"(&(%s)(apacheExtConfigServerName=%s)(apacheExtConfigUri=%s))", conf->filter, reqc->name, buff); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"ExtConfig Location Object search filter: %s", extconffiltbuf); + result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wlcbasedn, conf->scope, extconfigattributes, extconffiltbuf, &dn, &extconfvals); //matched URI, if found, is returned anyway with extconfvals as ldap attribute value. } - //ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Closing LDAP Connection"); - util_ldap_connection_close(ldc); if(result != LDAP_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "This vhost has access control, but probably not for this URI, access config entry not found"); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "Tried with ldap search filter: %s", extconffiltbuf); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has access control, but probably not for this URI, access config entry not found"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Tried with ldap search filter: %s", extconffiltbuf); } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "This uri has access control, configuration object is found"); - - if(extconfvals) { - //this translate_name function we're in is long enough, don't You think? - //we set all into extreqc struct - //ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extconfig buffer fill"); - mod_vhost_ldap_doextconfig(r, extconfigattributes, extconfvals, extreqc); - } + else + { + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This uri has access control, configuration object is found"); + //we set all into extreqc struct + //ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extconfig buffer fill"); + if(extconfvals) { mvhl_doextconfig(r, extconfigattributes, extconfvals, extreqc); } ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Entering ap_requires generation process"); - - core_dir_config *coredirconf = - (core_dir_config *) ap_get_module_config(r->per_dir_config, &core_module); + core_dir_config *coredirconf = (core_dir_config *) ap_get_module_config(r->per_dir_config, &core_module); coredirconf->ap_auth_name = extreqc->extconfname; coredirconf->ap_auth_type = (char *) "basic"; char *userlist = "user nobody"; + /* + st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); + st->search_cache_ttl = 0; + */ + char userfilter[FILTER_LENGTH]; + /* we'll search for user object with custom filter applied, which has assigned matched location name and which has assigned current servername */ + apr_snprintf(userfilter, FILTER_LENGTH, "(&(%s)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserServerName=%s)(apacheExtConfigUserLocationUri=%s))", conf->filter, reqc->name, buff); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"User search filter: %s", userfilter); + + mvhl_webuser *extuserreqc = (mvhl_webuser *) apr_pcalloc(r->pool, sizeof(mvhl_webuser)); + int i = 0; if(extreqc->extusers) { - mod_vhost_ldap_webuser_t *extuserreqc; - extuserreqc = - (mod_vhost_ldap_webuser_t *) apr_pcalloc(r->pool, - sizeof(mod_vhost_ldap_webuser_t)); - char *ldap_webuser_attributes[] = - { "apacheExtConfigUserName", "apacheExtConfigUserServerName", "userPassword", - 0 - }; - ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw, - conf->deref, conf->secure); - int i = 0; + log_dump_apr_array(r,extreqc->extusers,"extUser"); + char **extuserdns = (char **) extreqc->extusers->elts; for (i = 0; i < extreqc->extusers->nelts; i++) { - char userfilter[FILTER_LENGTH]; - const char **extuservals = NULL; int result = 0; - apr_snprintf(userfilter, FILTER_LENGTH, - "(&(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserServerName=%s))", - reqc->name); - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "User search filter: %s", userfilter); - result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wucbasedn, - conf->scope, ldap_webuser_attributes, - userfilter, &dn, &extuservals); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "User search basedn: %s", extuserdns[i]); + //we don't use wucbasedn as we already know what webuser distinguishedname can be + char *ldap_webuser_attributes[] = { "apacheExtConfigUserName","apacheExtConfigUserServerName","userPassword", "apacheExtConfigUserDirectoryName", "apacheExtConfigUserLocationUri", 0}; + result = util_ldap_cache_getuserdn(r, ldc, conf->url, extuserdns[i], LDAP_SCOPE_BASE, ldap_webuser_attributes, userfilter, &dn, &extuservals); if(extuservals) { - mod_vhost_ldap_doextuserconfig(r, ldap_webuser_attributes, extuservals, - extuserreqc); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 0: %s", extuservals[0]); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 1: %s", extuservals[1]); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 2: %s", extuservals[2]); + mvhl_doextuserconfig(r, ldap_webuser_attributes, extuservals, extuserreqc); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current username: %s", extuserreqc->webusername); + userlist = apr_pstrcat(r->pool, userlist, " ", extuserreqc->webusername, NULL); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current userlist: %s", userlist); } - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "current username: %s", extuserreqc->webusername); - - userlist = apr_pstrcat(r->pool, userlist, " ", extuserreqc->webusername, NULL); - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "current userlist: %s", userlist); } - - util_ldap_connection_close(ldc); } ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "final userlist: %s ", userlist); - - ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthName set to %s", coredirconf->ap_auth_name); ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthType set to %s", coredirconf->ap_auth_type); ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Preparing access control line"); - coredirconf->ap_requires = - (apr_array_header_t *) get_ap_reqs(r->pool, extreqc, reqc->name, userlist); - + coredirconf->ap_requires = (apr_array_header_t *) get_ap_reqs(r->pool, extreqc, reqc->name, userlist); } } else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, - "This vhost is not configured for access control, or it is disabled via apacheExtConfigHasRequireLine = FALSE skipping.."); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "This vhost is not configured for access control, or it is disabled via apacheExtConfigHasRequireLine = ( FALSE|not set) skipping.."); } +} +/******************************************************************/ +static void apply_directory_access_control(mvhl_request *reqc, request_rec * r, mvhl_config *conf, util_ldap_connection_t *ldc, const char *dn) { - top->server->server_hostname = apr_pstrdup(top->pool, reqc->name); - + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has directory access control configured, need to check if it's enabled for current filename"); + int result = 0; + int i = 0; + char extconffiltbuf[FILTER_LENGTH]; + const char **extconfvals = NULL; + char *extconfigattributes[] = { "apacheExtConfigUri","apacheExtConfigRequireValidUser","apacheExtConfigServerName","apacheExtConfigObjectName","apacheExtConfigUserDn","apacheExtConfigPath",0}; + mvhl_extconfig_object *extreqc = (mvhl_extconfig_object *) apr_pcalloc(r->pool, sizeof(mvhl_extconfig_object)); + char *buff = NULL; + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extConfig Directory Objects search"); + while(i <= strlen(apr_pstrdup(r->pool, r->filename)) && !extconfvals) { + i++; + buff = apr_pstrndup(r->pool, r->filename, i); + /* + * ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Searching for hostname %s and URI %s, origname is %s", hostname, buff, reqc->name); + * uncomment this, if You'd like to see in log how uri gets checked + * ap_log_error(APLOG_MARK,APLOG_DEBUG,OK,NULL,"%s", buff); + + * well, we must had been connecting already, so we don't do more ldap server connection checks, + * and we're doing a search with cache_getuser instead of using extConfigObject dn apacheConfig object attribute value(s), + * because there's no convenient function in apr api. + * vhost location RDN attribute is used actually by some GUI to make things easier + * TODO: use some generic ldap functions (?) classic search or implement more ldap routines for apr + + * so, we do a search below locationDnBase for config object with matches current hostname and uri.. + * note, that we took our current uri, and we're searching starting from / adding one by one chararacter + * to match config object - access config is always the same as first matching upper url access config. + * and more - if someone defined accessobject for /main and /main/subdir, the first one is used. + * when upper is deleted - next below is returned, and so far.. + * and more - if there are two or more extConfig object for the same combination of server/uri, + * then first found is returned and search isn't processed further. + + * we do a search based on original reqc->name instead of current hostname, to apply rules even if we're accessing + * site via ServerAlias name + */ + apr_snprintf(extconffiltbuf, FILTER_LENGTH,"(&(%s)(apacheExtConfigPath=%s))", conf->filter, buff); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"ExtConfig Directory Object search filter: %s", extconffiltbuf); + result = util_ldap_cache_getuserdn(r, ldc, conf->url, conf->wlcbasedn, conf->scope, extconfigattributes, extconffiltbuf, &dn, &extconfvals); + //matched dir, if found, is returned anyway with extconfvals as ldap attribute value. + } - if(reqc->admin) { - top->server->server_admin = apr_pstrdup(top->pool, reqc->admin); + if(result != LDAP_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This vhost has access control, but probably not for this directory, access config entry not found"); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"Tried with ldap search filter: %s", extconffiltbuf); + } + else + { + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"This directory has access control, configuration object is found"); + //we set all into extreqc struct + //ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Entering extconfig buffer fill"); + if(extconfvals) { mvhl_doextconfig(r, extconfigattributes, extconfvals, extreqc); } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Entering ap_requires generation process"); + core_dir_config *coredirconf = (core_dir_config *) ap_get_module_config(r->per_dir_config, &core_module); + coredirconf->ap_auth_name = extreqc->extconfname; + coredirconf->ap_auth_type = (char *) "basic"; + char *userlist = "user nobody"; + + /* + st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); + st->search_cache_ttl = 0; + */ + char userfilter[FILTER_LENGTH]; + /* we'll search for user object with custom filter applied, which has assigned matched directory name */ + apr_snprintf(userfilter, FILTER_LENGTH, "(&(%s)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserDirectoryName=%s))", conf->filter, buff); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r,"User search filter: %s", userfilter); + + mvhl_webuser *extuserreqc = (mvhl_webuser *) apr_pcalloc(r->pool, sizeof(mvhl_webuser)); + int i = 0; + if(extreqc->extusers) { + log_dump_apr_array(r,extreqc->extusers,"extUser"); + char **extuserdns = (char **) extreqc->extusers->elts; + for (i = 0; i < extreqc->extusers->nelts; i++) { + const char **extuservals = NULL; + int result = 0; + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "User search basedn: %s", extuserdns[i]); + //we don't use wucbasedn as we already know what webuser distinguishedname can be + char *ldap_webuser_attributes[] = { "apacheExtConfigUserName","apacheExtConfigUserServerName","userPassword", "apacheExtConfigUserDirectoryName", "apacheExtConfigUserLocationUri", 0}; + result = util_ldap_cache_getuserdn(r, ldc, conf->url, extuserdns[i], LDAP_SCOPE_BASE, ldap_webuser_attributes, userfilter, &dn, &extuservals); + if(extuservals) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 0: %s", extuservals[0]); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 1: %s", extuservals[1]); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Val 2: %s", extuservals[2]); + mvhl_doextuserconfig(r, ldap_webuser_attributes, extuservals, extuserreqc); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current username: %s", extuserreqc->webusername); + userlist = apr_pstrcat(r->pool, userlist, " ", extuserreqc->webusername, NULL); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "current userlist: %s", userlist); + } + } + } + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "final userlist: %s ", userlist); + ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthName set to %s", coredirconf->ap_auth_name); + ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "AuthType set to %s", coredirconf->ap_auth_type); + ap_log_error(APLOG_MARK, APLOG_DEBUG, OK, NULL, "Preparing access control line"); + coredirconf->ap_requires = (apr_array_header_t *) get_ap_reqs(r->pool, extreqc, reqc->name, userlist); } + +} +/******************************************************************/ +static int mvhl_translate_name(request_rec * r) +{ + request_rec *top = r->main ? r->main : r; + apr_table_t *e = top->subprocess_env; + + //module config and current request config objects + mvhl_config *conf = (mvhl_config *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); + mvhl_dump_config_request(conf, r); //debug + // mod_vhost_ldap is disabled or we don't have LDAP Url, we check these as soon as we can (after debugging dump) + if(( conf->enabled == 0) || (! conf->have_ldap_url) || ( ! conf->host ) ) return DECLINED; + + //get core config and current request config, then set current request config + core_server_config *core = (core_server_config *) ap_get_module_config(r->server->module_config, &core_module); + mvhl_request *reqc = (mvhl_request *) apr_pcalloc(r->pool, sizeof(mvhl_request)); + ap_set_module_config(r->request_config, &vhost_ldap_module, reqc); + + const char *hostname = r->hostname; + const char *dn = NULL; + + //we'll reuse ldap connection opened here + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Opening LDAP Connection"); + util_ldap_connection_t *ldc = util_ldap_connection_find(r, conf->host, conf->port, conf->binddn, conf->bindpw,conf->deref, conf->secure); + + //heart of the system :) + if ( conf->enabled == 0 || ! apply_vhost(conf, hostname, r, ldc, dn, reqc ) ) return DECLINED; + if (conf->alias_enabled > 0 ) apply_aliasing(reqc, r, conf, ldc, dn); + if (conf->loc_auth_enabled > 0 ) apply_location_access_control(reqc, r, conf, ldc, dn); + if (conf->dir_auth_enabled > 0 ) apply_directory_access_control(reqc, r, conf, ldc, dn); + + ap_log_rerror(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "Closing LDAP Connection"); + util_ldap_connection_close(ldc); + + /* finished with Access control for location **********************************/ + top->server->server_hostname = apr_pstrdup(top->pool, reqc->name); + if(reqc->admin) {top->server->server_admin = apr_pstrdup(top->pool, reqc->admin); } // set environment variables - e = top->subprocess_env; apr_table_addn(e, "SERVER_ROOT", reqc->docroot); core->ap_document_root = apr_pstrdup(top->pool, reqc->docroot); return OK; } - -#ifdef HAVE_UNIX_SUEXEC -static ap_unix_identity_t *mod_vhost_ldap_get_suexec_id_doer(const request_rec * r) +/******************************************************************/ +static ap_unix_identity_t *mvhl_suexec_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); + mvhl_config *conf = (mvhl_config *) ap_get_module_config(r->server->module_config, &vhost_ldap_module); + mvhl_request *req = (mvhl_request *) 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; - } + // mod_vhost_ldap is disabled or we don't have LDAP Url + if( + (uid < MIN_UID) || + (gid < MIN_GID) || + ( conf->enabled == 0 ) || + (!conf->have_ldap_url) || + (req == NULL) || + (req->uid == NULL) || + (req->gid == NULL) || + (ugid = apr_palloc(r->pool, sizeof(ap_unix_identity_t))) == NULL + ) { return NULL; } ugid->uid = uid; ugid->gid = gid; ugid->userdir = 0; - return ugid; } -#endif - -static int mod_vhost_ldap_post_config(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * s) +/******************************************************************/ +static int mvhl_post_config(apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * s) { /* make sure that mod_ldap (util_ldap) is loaded */ - if(ap_find_linked_module("util_ldap.c") == NULL) { - return HTTP_INTERNAL_SERVER_ERROR; - } - + if(ap_find_linked_module("util_ldap.c") == NULL) {return HTTP_INTERNAL_SERVER_ERROR;} ap_add_version_component(p, MOD_VHOST_LDAP_VERSION); return OK; } - -static void mod_vhost_ldap_register_hooks(apr_pool_t * p) -{ - ap_hook_post_config(mod_vhost_ldap_post_config, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_translate_name(mod_vhost_ldap_translate_name, NULL, NULL, APR_HOOK_MIDDLE); -#ifdef HAVE_UNIX_SUEXEC - ap_hook_get_suexec_identity(mod_vhost_ldap_get_suexec_id_doer, NULL, NULL, APR_HOOK_MIDDLE); -#endif - ap_hook_check_user_id(mod_vhost_ldap_authenticate_basic_user, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_auth_checker(mod_vhost_ldap_check_auth, NULL, NULL, APR_HOOK_MIDDLE); -} - -static const 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("VhostLDAPWebLocationConfigBaseDn", mod_vhost_ldap_set_wlcbasedn, NULL, RSRC_CONF, - "Base DN to do all location config searches."), - - AP_INIT_TAKE1("VhostLDAPWebUsersBaseDn", mod_vhost_ldap_set_wucbasedn, NULL, RSRC_CONF, - "Base DN to do all location config searches"), - +/******************************************************************/ +static const command_rec mvhl_cmds[] = { + AP_INIT_TAKE1("VhostLdapUrl", conf_mvhl_url, NULL, RSRC_CONF,"RFC 2255 URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]]."), + AP_INIT_TAKE1("VhostLdapEnabled", conf_mvhl, MVHL_ENABLED, RSRC_CONF,"Set to off or unset to disable vhost_ldap module completely"), + AP_INIT_TAKE1("VhostAliasesEnabled", conf_mvhl, MVHL_ALIASENABLED, RSRC_CONF,"Set to off or unset to disable ldap-based dir aliases"), + AP_INIT_TAKE1("VhostLocAuthEnabled", conf_mvhl, MVHL_LAUTHENABLED, RSRC_CONF,"Set to off or unset to disable per-location authentication"), + AP_INIT_TAKE1("VhostDirAuthEnabled", conf_mvhl, MVHL_DAUTHENABLED, RSRC_CONF,"Set to off or unset to disable per-location authentication"), + AP_INIT_TAKE1("VhostLdapBindDn", conf_mvhl, MVHL_BINDDN, RSRC_CONF,"DN to use to bind to LDAP server"), + AP_INIT_TAKE1("VhostLdapBindPw", conf_mvhl, MVHL_BINDPW, RSRC_CONF,"Password to use to bind to LDAP server"), + AP_INIT_TAKE1("VhostLdapWlcBaseDn", conf_mvhl, MVHL_WLCBASEDN, RSRC_CONF,"Base DN to do all access control config searches."), + AP_INIT_TAKE1("VhostLdapWucBaseDn", conf_mvhl, MVHL_WUCBASEDN, RSRC_CONF,"Base DN to do all user config searches"), + AP_INIT_TAKE1("VhostLdapAliasesBaseDn", conf_mvhl, MVHL_ALIASBASEDN, RSRC_CONF,"Base DN to do all aliases config searches"), + AP_INIT_TAKE1("VhostLdapFallback", conf_mvhl, MVHL_FALLBACK, RSRC_CONF,"Fallback vhost server name to use - to display not-found info"), + AP_INIT_TAKE1("VhostLdapDeref", conf_mvhl, MVHL_DEREF, RSRC_CONF,"values: never, searching, finding, always"), {NULL} }; - +/******************************************************************/ +static void mvhl_register_hooks(apr_pool_t * p) +{ + ap_hook_post_config(mvhl_post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_translate_name(mvhl_translate_name, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_get_suexec_identity(mvhl_suexec_doer, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_check_user_id(mvhl_authenticate_basic_user, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_auth_checker(mvhl_check_auth, NULL, NULL, APR_HOOK_MIDDLE); +} +/******************************************************************/ module AP_MODULE_DECLARE_DATA vhost_ldap_module = { - STANDARD20_MODULE_STUFF, // jakas lista - NULL, // create per-directory config structure - NULL, // merge per-directory config structures, default is to override - mod_vhost_ldap_create_server_config, // called when module configuration data needs to be created/allocated. - mod_vhost_ldap_merge_server_config, // merge per-server config structures - mod_vhost_ldap_cmds, // Here we pass in the list of new configuration directives. - mod_vhost_ldap_register_hooks, // register me in apache core + STANDARD20_MODULE_STUFF, + NULL, // create per-directory config structure + NULL, // merge per-directory config structures, default is to override + mvhl_create_sconfig,// called when module configuration data needs to be created/allocated. + mvhl_merge_sconfig, // merge per-server config structures + mvhl_cmds, // Here we pass in the list of new configuration directives. + mvhl_register_hooks,// register me in apache core }; diff --git a/mod_vhost_ldap.schema b/mod_vhost_ldap.schema index f84db29..dd0c4a2 100644 --- a/mod_vhost_ldap.schema +++ b/mod_vhost_ldap.schema @@ -62,7 +62,8 @@ attributetype ( 1.3.6.1.4.1.8387.1.1.8 NAME 'apacheSuexecGid' 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 ) ) + apacheSuexecUid $ apacheSuexecGid ) + AUXILIARY + ) diff --git a/vhost_ldap.conf b/vhost_ldap.conf index 36c73e9..495364d 100644 --- a/vhost_ldap.conf +++ b/vhost_ldap.conf @@ -1,17 +1,55 @@ -# -# 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 ### +### and probably set various cache options for it ### + +###scope values: base, one, sub +###deref values: never, finding, searching, always +###remember, user specified filter is checked as RFC-defined ldap filter before substitution +###user filter specified here results with following internal filters and variables: +### _A_ is the server name from the request (vhost server name to find) +### _B_ is the uri for which access control is to be determined +### _C_ is the name of the require valid-user directive (auth prompt message) +### _D_ is the the user-defined filter +### _E_ is the protected physical directory (doesn't need to be existing file or dir) +### _F_ is the alias location uri +### _G_ is the protected uri for which access control is to be determined (see _E_) +### _H_ is the alias uri which is to be aliased to specified directory +### Each use of search filter is logged with debug level + +##################################################################### +### Vhost search +### (&(_D_)(|(apacheServerName=_A_)(apacheServerAlias=_A_))) +##################################################################### +### Protected Location Search +### (&(_D_)(apacheExtConfigServerName=_A_)(apacheExtConfigUri=_B_)) +##################################################################### +### Protected Directory Search +### (&(_D_)(apacheExtConfigPath=_E_)) +##################################################################### +### Alias Object Search +### (&(_D_)(apacheAliasConfigServerName=_A_)(apacheAliasConfigSourceUri=_H_)) +##################################################################### +### Web user Location Search +### (&(_D_)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserServerName=_A_)(apacheExtConfigUserLocationUri=_G_)) +##################################################################### +### Web user Directory Search +### (&(_D_)(objectClass=apacheExtendedConfigUserObject)(apacheExtConfigUserDirectoryName=_E_)) +################################## + +### ldap[si]://host[:port]/basedn[?attrib[?scope[?filter]]] + + VhostLdapEnabled On + VhostLdapUrl ldap[si]://host[:port]/basedn[?attrib[?scope[?filter]]] + #VhostLdapUrl ldap://hostname:389/dc=foo,dc=bar?*?sub?objectClass=activeObject + VhostLdapBindDn "cn=read only apache admin,dc=foo,dc=bar" + VhostLdapBindPw "secretpassword" + VhostLdapWlcBaseDn "ou=webAccess,dc=foo,dc=bar" + VhostLdapWucBaseDn "ou=webAccounts,dc=foo,dc=bar" + VhostLdapAliasesBaseDn "ou=webAliases,dc=foo,dc=bar" + VhostLdapDeref "never" + VhostLdapFallback default + VhostAliasesEnabled On + VhostLocAuthEnabled On + VhostDirAuthEnabled On -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" - -- 2.45.1