Apache2::AuthZLDAP - Authorization module based on LDAP filters or LDAP groups


Apache2-AuthZLDAP documentation Contained in the Apache2-AuthZLDAP distribution.

Index


Code Index:

NAME

Top

Apache2::AuthZLDAP - Authorization module based on LDAP filters or LDAP groups

VERSION

Top

Version 0.02

SYNOPSIS

Top

This module is an authorization handler for Apache 2. Its authorization method relies on openLDAP filters.

CONFIGURATION

Top

This module can work with all authentification module that provides a valid REMOTE_USER env var. For example :

* Basic Apache auth
* CAS authentication (mod_cas, Apache2::AuthCAS)

Example with CAS authentication :

    <VirtualHost 192.168.0.1:80>
    ## these vars can be initialized outside of directory 
    PerlSetVar LDAPURI             ldap://myldaphost/
    PerlSetVar LDAPbaseDN          ou=groups,dc=organization,dc=domain

 


    <Directory "/var/www/somewhere">
    AuthName CAS
    AuthType CAS
    ## define a filter. [uid] will be replaced by user value on runtime 
    PerlSetVar LDAPfilter          &(member=uid=[uid],ou=people,dc=organization,dc=domain)(cn=admins)
    ## charging of the module for authZ
    PerlAuthzHandler Apache2::AuthZLDAP
    require valid-user
    </Directory>

    </VirtualHost>

Configuration Options

    # Set to the LDAP URI
    # Multiple URIs can be set for failover LDAP servers
    # Note: ldaps Defaults to port 636
    PerlSetVar LDAPURI          ldap://ldaphost1
    PerlSetVar LDAPURI          ldaps://ldaphost2
    PerlSetVar LDAPURI          ldap://ldaphost3:1001

    # How to handle the certificate verification for ldaps:// URIs
    # See start_tls in Net::LDAP for more information
    # If you set any of the LDAPSSL* variables, be sure to include only
    # ldaps:// URIs. Otherwise the connection will fail.
    # (none|optional|require)
    PerlSetVar LDAPSSLverify    none

    # Set to a directory that contains the CA certs
    PerlSetVar LDAPSSLcapath    /path/to/cadir

    # Set to a file that contains the CA cert
    PerlSetVar LDAPSSLcafile    /path/to/cafile.pem

    # Turn on TLS to encrypt a connection
    # Note: This is different from ldaps:// connections. ldaps:// specifies
    # an LDAP connection totally encapsulated by SSL usually running on a 
    # different port. TLS tells the LDAP server to encrypt a cleartext ldap://
    # connection from the time the start_tls command is issued.
    # (yes|no)
    PerlSetVar LDAPTLS          yes

    # How to handle the certificate verification
    # See start_tls in Net::LDAP for more information
    # (none|optional|require)
    PerlSetVar LDAPTLSverify    none

    # Set to a directory that contains the CA certs
    PerlSetVar LDAPTLScapath    /path/to/cadir

    # Set to a file that contains the CA cert
    PerlSetVar LDAPTLScafile    /path/to/cafile.pem

    # Specifies a user/password to use for the bind
    # If LDAPuser is not specified, AuthZLDAP will attempt an anonymous bind
    PerlSetVar LDAPuser         cn=user,o=org
    PerlSetVar LDAPpassword     secret

    # Sets the LDAP search scope
    # (base|one|sub)
    # Defaults to sub
    PerlSetVar LDAPscope        sub

    # Defines the search filter
    # [uid] will be replaced by the username passed in to AuthZLDAP
    PerlSetVar LDAPfilter       &(member=uid=[uid],ou=people,dc=organization,dc=domain)(cn=admins)

AUTHOR

Top

Dominique Launay, <dominique.launay AT cru.fr> Thanks to David Lowry, <dlowry AT bju.edu> for making the code more readable and improving it.

BUGS

Top

Please report any bugs or feature requests through the web interface at https://sourcesup.cru.fr/tracker/?func=add&group_id=354&atid=1506 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

Top

You can find documentation for this module with the perldoc command.

    perldoc Apache2::AuthZLDAP







ACKNOWLEDGEMENTS

Top

COPYRIGHT & LICENSE

Top


Apache2-AuthZLDAP documentation Contained in the Apache2-AuthZLDAP distribution.
package Apache2::AuthZLDAP;

use warnings;
use strict;
use mod_perl2;
BEGIN {
		require Apache2::Const;
		require Apache2::Access;
		require Apache2::SubRequest;
		require Apache2::RequestRec;
		require Apache2::RequestUtil;
		require Apache2::Response;
		require APR::Table;
		Apache2::Const->import(-compile => 'HTTP_UNAUTHORIZED','OK', 'HTTP_INTERNAL_SERVER_ERROR');
		require Apache2::Log;
		require Apache2::Directive;
		require Net::LDAP;
} 
our $VERSION = '0.02';

sub handler{
    my $r= shift;
    return Apache2::Const::OK unless $r->is_initial_req;

    ## Location Variables to connect to the good server
    my @LDAPURI = $r->dir_config->get('LDAPURI');

    my $LDAPSSLverify = lc($r->dir_config('LDAPSSLverify'));
    my $LDAPSSLcapath = $r->dir_config('LDAPSSLcapath');
    my $LDAPSSLcafile = $r->dir_config('LDAPSSLcafile');
    
    my $LDAPTLS =  lc($r->dir_config('LDAPTLS')) || "no";
    my $LDAPTLSverify = lc($r->dir_config('LDAPTLSverify'));
    my $LDAPTLScapath = $r->dir_config('LDAPTLScapath');
    my $LDAPTLScafile = $r->dir_config('LDAPTLScafile');

    if($LDAPTLS ne "yes" && $LDAPTLS ne "no"){
	$LDAPTLS="no";
    }

    ## bind
    my $LDAPuser = $r->dir_config('LDAPuser'); 
    my $LDAPpassword = $r->dir_config('LDAPpassword');

    ## baseDN and Filters
    my $LDAPbaseDN = $r->dir_config('LDAPbaseDN');
    my $LDAPscope =  lc($r->dir_config('LDAPscope'));
    my $LDAPfilter = $r->dir_config('LDAPfilter');

    if($LDAPscope ne 'base' && $LDAPscope ne 'one' && $LDAPscope ne 'sub'){
        $LDAPscope = 'sub';
    }
    
    my $location = $r->location;
    
    ## Some error checking
    if (not @LDAPURI) {
        $r->log_error("Apache2::AuthZLDAP : $location, did not specify a LDAPURI");
	return Apache2::Const::HTTP_UNAUTHORIZED; 
    }

    if (not defined $LDAPfilter) {
        $r->log_error("Apache2::AuthZLDAP : $location, did not specify a LDAPfilter");
	return Apache2::Const::HTTP_UNAUTHORIZED; 
    }

    ## did user authentified ?
    ## retrieval of user id
    my $user = $r->user;
    if (not defined $user){
	$r->log_error("Apache2::AuthZLDAP : $location, user didn't authentify uid empty");
	return Apache2::Const::HTTP_UNAUTHORIZED; 
    }else{
	$LDAPfilter =~ s/\[uid\]/$user/;
    }

    ## port initialisation
    my $session; ## TODO make this come from a pool maybe?
    my $mesg;

    unless ($session = Net::LDAP->new(\@LDAPURI, capath=>$LDAPSSLcapath, cafile=>$LDAPSSLcafile, verify=>$LDAPSSLverify)) {
        $r->log_error("Apache2::AuthZLDAP : $location, LDAP error cannot create session");
        return Apache2::Const::HTTP_UNAUTHORIZED;
    }
    
    if ($LDAPTLS eq 'yes') {
        $mesg = $session->start_tls(capath=>$LDAPTLScapath, cafile=>$LDAPTLScafile, verify=>$LDAPTLSverify);
	if ($mesg->code) {
             $r->log_error("Apache2::AuthZLDAP : $location, LDAP error could not start TLS : ".$mesg->error);
	}
        return Apache2::Const::HTTP_UNAUTHORIZED;
    }
    
    ## user password bind if configured else anonymous
    if (defined $LDAPuser and defined $LDAPpassword){
        $mesg = $session->bind($LDAPuser,password=>$LDAPpassword);
    }else{
        $mesg = $session->bind();
    }

    if($mesg->code){
	my $err_msg = 'LDAP error cannot bind ';
        if (defined $LDAPuser){
             $err_msg .= "as $LDAPuser";
        }else{
             $err_msg .= 'anonymously';
        }
        $r->log_error("Apache2::AuthZLDAP : $location, $err_msg : ".$mesg->error);
        return Apache2::Const::HTTP_UNAUTHORIZED; 
    }
    
    ## search performing, if there is a result, OK
    $mesg = $session->search( # perform a search
			   base   => $LDAPbaseDN,
			   scope => $LDAPscope,
			   filter => $LDAPfilter,
			   );
    if ($mesg->code) {
         $r->log_error("Apache2::AuthZLDAP : $location, LDAP error could not search : ".$mesg->error);
	return Apache2::Const::HTTP_UNAUTHORIZED;
    }
    if ($mesg->count != 0){
	$r->log->notice("Apache2::AuthZLDAP : $user authorized to access $location");  
	$session->unbind;
	return Apache2::Const::OK;
    }else{
	$session->unbind;
	$r->log_error("Apache2::AuthZLDAP : $user not allowed to access $location");
	return Apache2::Const::HTTP_UNAUTHORIZED;
    }
}

1; # End of Apache2::AuthZLDAP