Apache lookup module: Difference between revisions
(Fix name of archive file and created directory) |
(→Building the module: Add some MacOS instructions) |
||
Line 20: | Line 20: | ||
apxs may not be on root's default path and may be renamed, e.g. to apxs2, on some | apxs may not be on root's default path and may be renamed, e.g. to apxs2, on some | ||
platforms. apxs and related files are sometimes provided by a httpd-devel, apache-devel, or apache2-devel package which will need to be installed. You will also need the OpenLDAP libraries and development files which will probably be provided by openldap and openldap2-devel packages, or similar. You may or may not also need to explicitly include the ldap libraries when building the module (the error message "undefined symbol: ldap_first_attribute" when restarting Apache suggests that you do and you haven't), in which case try | platforms. apxs and related files are sometimes provided by a httpd-devel, apache-devel, or apache2-devel package which will need to be installed. You will also need the OpenLDAP libraries and development files which will probably be provided by openldap and openldap2-devel packages, or similar. You may or may not also need to explicitly include the ldap libraries when building the module (the error message "undefined symbol: ldap_first_attribute" or similar when restarting Apache suggests that you do and you haven't), in which case try | ||
apxs -c -i -lldap -llber mod_ucam_lookupquery. | apxs -c -i -lldap -llber mod_ucam_lookupquery. | ||
Version 0.90 of the module isn't as portable as one might like. Depending on your platform details (Apache version, OpenLDAP version, C compiler, etc.) you may need to make some or all of the following changes. Some, though not all, of these changes are included in the source RPM above but won't be included by default | Building under MacOS is more complicated still, because MacOS supports multiple architectures (e.g. i386 and x86_64) and you need to build the module so that it matches the architecture under which Apache runs. For most recent version (at least Leopard & Snow Leopard (10.5/10.6)) the following incantation should work (it builds a 2-way fat binary supporting both i386 and x86_64 architectures): | ||
apxs -c -i -lldap -llber -Wc,'-arch i386 -arch x86_64' -Wl,'-arch i386 -arch x86_64' mod_ucam_lookupquery.c | |||
[Note that most earlier versions of MacOS shipped with Apache version 1 with which this module is not compatible] | |||
Version 0.90 of the module isn't as portable as one might like. Depending on your platform details (Apache version, OpenLDAP version, C compiler, etc.) you may need to make some or all of the following changes. Some, though not all, of these changes are included in the source RPM above but won't be included by default except when built on RedHat systems. | |||
* Add, around line 26: | * Add, around line 26: |
Revision as of 07:09, 22 July 2011
This is an Apache2 module (which appears to work in Apache 2.0 and Apache 2.2) designed to perform authorization functions for an existing REMOTE_USER (as derived from Raven or otherwise) by querying lookup.
- Media:Ucam_lookupquery-0.90.tar.gz - Source tar ball
- Media:Ucam_lookupquery-0.90-1.src.rpm - Very basic source RPM
Please send questions about this module to lookup-support@ucs.cam.ac.uk.
Building the module
To build the module from source and copy it into the correct Apache directory, first unpack the distribution tar file and cd into the directory it creates:
tar zxf Ucam_lookupquery-0.90.tar.gz cd Ucam_lookupquery
then issue the following command as root:
apxs -c -i mod_ucam_lookupquery.c
apxs may not be on root's default path and may be renamed, e.g. to apxs2, on some platforms. apxs and related files are sometimes provided by a httpd-devel, apache-devel, or apache2-devel package which will need to be installed. You will also need the OpenLDAP libraries and development files which will probably be provided by openldap and openldap2-devel packages, or similar. You may or may not also need to explicitly include the ldap libraries when building the module (the error message "undefined symbol: ldap_first_attribute" or similar when restarting Apache suggests that you do and you haven't), in which case try
apxs -c -i -lldap -llber mod_ucam_lookupquery.
Building under MacOS is more complicated still, because MacOS supports multiple architectures (e.g. i386 and x86_64) and you need to build the module so that it matches the architecture under which Apache runs. For most recent version (at least Leopard & Snow Leopard (10.5/10.6)) the following incantation should work (it builds a 2-way fat binary supporting both i386 and x86_64 architectures):
apxs -c -i -lldap -llber -Wc,'-arch i386 -arch x86_64' -Wl,'-arch i386 -arch x86_64' mod_ucam_lookupquery.c
[Note that most earlier versions of MacOS shipped with Apache version 1 with which this module is not compatible]
Version 0.90 of the module isn't as portable as one might like. Depending on your platform details (Apache version, OpenLDAP version, C compiler, etc.) you may need to make some or all of the following changes. Some, though not all, of these changes are included in the source RPM above but won't be included by default except when built on RedHat systems.
- Add, around line 26:
#include "http_request.h" /* for ap_hook_auth_checker */ #include "apr_lib.h" /* for apr_isspace.h */
- At line 150, change
int error_code;
to
int error_code = 0;
- For some older versions of OpenLDAP, Change lines 187/8 from
else if (strcmp(scope, "one") == 0) intscope = LDAP_SCOPE_ONE; else if (strcmp(scope, "sub") == 0) intscope = LDAP_SCOPE_SUB;
to
else if (strcmp(scope, "one") == 0) intscope = LDAP_SCOPE_ONELEVEL; else if (strcmp(scope, "sub") == 0) intscope = LDAP_SCOPE_SUBTREE;
- Change line 575 from
regex_t *r = ap_pregcomp(p, w, REG_ICASE);
to
ap_regex_t *r = ap_pregcomp(p, w, AP_REG_ICASE);
- Change line 829 from
while (s > fakeuser && isspace(s[-1])) s--;
to
while (s > fakeuser && apr_isspace(s[-1])) s--;
In addition you might want to change a number of instances (e.g. at lines 877, 910, and 196) of APLOG_ERR to APLOG_INFO to reduce the noise in your Apache error log.
Basic documentation
Load the module by including
LoadModule ucam_lookupquery_module modules/mod_ucam_lookupquery.so
in the Apache configuration file, replacing 'modules/mod_ucamlookupquery.so' if necessary with the path to the the file containing the module, relative to ServerRoot if it doesn't start '/'.
To use it, include something like
Require LookupInst CS
in a protection block (except that this example doesn't currently work - see below). See below for other configuration options.
OPTIONS ------- LookupAuthoritative Value: on|off Default: on LookupHostPort Value: space-separated list Default: ldap.lookup.cam.ac.uk:389 (actually uses LDAP_PORT) (1) IPv6 literal addresses can be enclosed in []. (2) It tries each one till one answers, one way or another. LookupBase Value: string Default: "o=University of Cambridge,dc=cam,dc=ac,dc=uk" AUTHENTICATION -------------- LookupBindDN Value: string Default: unset LookupPwd Value: string Default: unset If both of these are set, a non-anonymous LDAP bind is done, first setting up an encrypted (TLS) session. If either one is not set, a non-encrypted, anonymous bind is done. REQUIREMENTS ------------ Apart from LookupQuery, all these come in pairs, LookupXxx and LookupXxxMatch. The former do exact matches on the data, the latter do regular expression matches. Multiple data values for a Require implement OR. Multiple Requires implement AND. It is not clear if this is the True Apache Way or not - I have failed to find a definitive statement - but it seems to me that whether multiple Requires do AND or OR should be controlled from a higher level (compare "satisfy any" for Require+Allow) because each run of the module just deals with a single Require and returns yes/no. There would have to be a much more elaborate memory scheme to implement OR at this level. Require LookupInst[Match] name1 [name2 ...] Runs: ou=people sub (uid=%u) inst Needs: (a) Exactly one entry (b) Exactly one attribute value, must match one of the names Example: Require LookupInst CS CL Require LookupAttr[Match] comma-separated-attrnames value1 [value2 ...] Runs: ou=people sub (uid=%u) comma-separated-attrnames Needs: (a) Exactly one entry (b) At least one attribute value must match something in the list Example: Require LookupAttr cn,displayName "Jon Warbrick" "Philip Hazel" Require LookupParentInst[Match] name1 [name2 ...] Runs: ou=people sub (uid=%u) inst Needs: (a) Exactly one entry (b) Exactly one attribute value, must match one of the names Else: ou=insts sub (instID=inst) parentInstID Needs: (a) Exactly one entry (b) Exactly one attribute value, must match one of the names Else: Loop up the tree till ROOT (which is checked). Example: Require LookupParentInst COLL Require LookupUserInGroup[Match] name1 [name2 ...] Runs: ou=groups sub (uid=%u) groupID Needs: (a) One or more entries (b) At least one of the groupIDs to match one of the names. Example: Require LookupUserInGroup 100001 100656 Require LookupQuery baseplus scope filter Runs: baseplus scope filter Needs: One or more entries (no attributes are looked up) Example: RequireLookupQuery ou=groups sub (&(uid=%u)(groupTitle=*Computing Service*)) The last rather artificial example checks that the user is a member of at least one group that has "Computing Service" in its title. To run a query on the base itself, the first argument can be given as an empty string in quotes. In the filter, literal characters * ( ) \ must be escaped as follows: * => \2A ( => \28 ) => \29 \ => \5C The sequence %u is replaced by the userid. To include a literal % before a lower case u, use \75.
Bugs and potential enhancements
- What about Apache 1.3?
- Is there any way to keep a cached connection to ldap.lookup.cam.ac.uk? If so, should it be done?
- 'Require LookupInst[Match]' expects exactly one attribute value, which won't be the case for someone affiliated to multiple institutions. To confuse matters, it reports a 'Temporary failure accessing the database' (because it gets an unexpected number of attributes). It should require at least one attribute value, which must match one of the names. As a work around, you can use something like
Require LookupQuery ou=people sub (&(uid=%u)(instID=CS))
- The same applies (without the convenient work around) to LookupParentInst[Match]
- There is no scope for matching against the allUid when checking group membership using a privileged account. Probably needs to run
ou=groups sub (&(uid=%u)(allUid=%u)) groupID
- Authenticated binds force the use of TLS and require that the OpenLDAP client libraries are configured to verify the JANET certificate used by lookup. Error messages in the Apache log such as 'ldap_start_tls_s: Connect error (-11)' indicate that this isn't the case.
- The module doesn't provide any way to customise the location of trusted CA certificates. For OpenLDAP the default location of a file listing trusted CA certificates and/or a directory containing 'OpenSSL-hashed' trusted CA certificates can be set per-user from ~/.ldaprc or system-wide from ldap.conf (perhaps in /etc/openlap or /etc/ldap) using the TLS_CACERT and TLS_CACERTDIR directives. See 'man ldap.conf'.
- The CA certificate required is one for the 'GTE CyberTrust Global Root' - it is included by default in many Linux distributions, but not SuSE. It can be obtained from Globalsign at http://secure.globalsign.net/cacert/ct_root.pem.
- Setting 'TLS_REQCERT allow' in ldap.conf/.ldaprc will disable all certificate checking, which is fine for testing but a BAD IDEA otherwise.
- Versions of OpenLDAP linked against GnuTLS (rather than OpenSSL - Debian/Ubuntu in particular) don't support TLS_CACERTDIR. Further some (esp. that included with Ubuntu 8.04 'Hardy Herron') don't seem to be able to successfully verify lookup's certificate at all.