Apache lookup module: Difference between revisions
(→Bugs and potential enhancements: LookupParentInst[Match] also broken) |
|||
Line 166: | Line 166: | ||
* What about Apache 1.3? | * 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? | * 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' ( | * '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)) | 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 | * 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 | ou=groups sub (&(uid=%u)(allUid=%u)) groupID |
Revision as of 16:55, 9 October 2007
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 mod_ucam_lookupquery-<ver>.tar.gz cd mod_ucam_lookupquery-<ver>
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 development files which will probably be provided by an openldap2-devel package or similar.
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:
- 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--;
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. 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