PAPI::LDAPAuth - Perl functions to provide PAPI authentication data using LDAP

SYNOPSIS

Inside the AuthServer.cf file:

 $cfg = \%PAPI::AuthServer::cfgVar;
 
 $$cfg{workingDirectory} = "/usr/local/PAPI/AS/etc";
  
 . . .
 
 $$cfg{authenticationHook} = \&PAPI::LDAPAuth::VerifyUser;
 $$cfg{credentialHook} = \&PAPI::LDAPAuth::UserCredentials;
 $$cfg{attrRequestHook} = \&PAPI::LDAPAuth::UserAttributes;
 $$cfg{LDAPserver} = "ldap.dom.ain";
 $$cfg{LDAPport} = 389;
 $$cfg{LDAPUSERtemplate} = 'uid=<papi var="username"/>';
 $$cfg{LDAPAuthSearchBase} = 'ou=people,dc=dom,dc=ain';
 $$cfg{LDAPsearchBase} = 'dc=papi,dc=dom,dc=ain';
 # Uncomment these if you need simple authentication to access the LDAP server
 #$$cfg{LDAPbindDN} = "dc=papias,dc=papi,dc=dom,dc=ain';";
 #$$cfg{LDAPbindPassword} = "papipassword";
 # Uncomment these to use a TLS connection and verify server identity
 #$$cfg{LDAPS} = 1;
 #$$cfg{LDAPSverify} = 'require';
 #$$cfg{LDAPScafile} = '/etc/PAPI/CAs/MyRoot.pem';

REQUIRES

Net::LDAP >= 0.30

DESCRIPTION

These functions implement PAPI user authentication and credential data provision using LDAP.

The LDAP attributes and object classes used for these purposes are defined by the following schema. This schema should be made available to the LDAP server you intend to use. A file named papi.schema is included into the LDAPAuth source directory for this purpose.

Object classes

A papiSite object models an information resource that must be accessed using the PAPI protocol:

 objectclass ( 1.3.6.1.4.1.7547.4.2.1.1 NAME 'papiSite'
               DESC 'Resource protected with PAPI'
               SUP top
               STRUCTURAL
               MUST ( papiSiteId $ papiSiteTtl $ papiSiteService $
                      papiSitePoA $ papiSiteLocation $ papiSiteAuth )
               MAY  ( description $ papiSiteAcceptURL $ papiSiteRejectURL $
                      papiAssertion $ papiSiteAccess )
             )

A papiGroup object models a group of users with similar characteristics. It has a set of associated papiSites that users in the group have access to:

 objectclass ( 1.3.6.1.4.1.7547.4.2.1.2 NAME 'papiGroup'
               DESC 'Group of PAPI users'
               SUP top
               STRUCTURAL
               MUST ( papiGroupId )
               MAY  ( papiSiteId $ description $ papiQualifiedAssertion )
             )

A papiUser models an individual and her/his access rights to resources protected by the PAPI protocol. It may have a set of papiSites the user has access to, and/or a set of papiGroups the user belongs to.

 objectclass ( 1.3.6.1.4.1.7547.4.2.1.3 NAME 'papiUser'
               DESC 'User of PAPI services'
               SUP top
               AUXILIARY
               MAY ( papiGroupId $ papiSiteId $ papiQualifiedAssertion )
             )

The PAPI schema also defines ad-hoc classes (papiUserStr, papiGroupAux and papiSiteAux) intended to use the respective kinds whenever necessary.

Attribute types

The attributes essentially model the required parameters that PAPI needs for generating the access tokens to a site.

papiSitePoA
Base URL (method, server and, optionally, port) for the Point of Access for this site
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.1 NAME 'papiSitePoA'
                 SUP labeledURI )
papiSiteAuth
URI for requesting tokens to the Point of Access
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.2 NAME 'papiSiteAuth'
                 SUP labeledURI )
papiSiteAccess
URI for initially requesting the contents at the Point of Access
papiSiteLocation
Start location at the PoA for this site
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.3 NAME 'papiSiteLocation'
                 SUP labeledURI )
papiSiteTtl
Time to live for the tokens requested to the PoA for this site
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.4 NAME 'papiSiteTtl'
                 DESC 'TTL of access to this resource'
                 EQUALITY integerMatch
                 SINGLE-VALUE
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )
papiSiteService
Service identifier at the PoA for this site
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.5 NAME 'papiSiteService'
                 SUP name )
papiSiteAcceptURL
URL to be used for indicating request acceptance at the PoA for this site
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.8 NAME 'papiSiteAcceptURL'
                 SUP labeledURI )
papiSiteRejectURL
URL to be used for indicating request rejection at the PoA for this site
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.9 NAME 'papiSiteRejectURL'
                 SUP labeledURI )
papiAssertion
Format of the assertion on user attributes to be sent to the PoA for this site if no group/user specific definition exists
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.10 NAME 'papiAssertion'
                 DESC 'User assertion for this site'
                 EQUALITY caseExactMatch
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
                 SINGLE-VALUE )
papiQualifiedAssertion
Format of the assertion on user attributes to be sent to a PoA identified in the qualifying part of the attribute. These attributes store pairs (siteID, assertionFormat), where siteID must correspond to one papiSiteID and assertionFormat describes the assertion to be used for that site. The separator of both parts is made of any number of whitespace characters (spaces or tabs).
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.11 NAME 'papiQualifiedAssertion'
                 DESC 'User assertion to use for the identified site'
                 EQUALITY caseExactMatch
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
papiSiteId
Identifier for papiSite objects
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.6 NAME 'papiSiteId' 
                 DESC 'Site name'
                 EQUALITY caseIgnoreMatch
                 SUBSTR caseIgnoreSubstringsMatch
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
papiGroupId
Identifier for papiGroup objects
 attributetype ( 1.3.6.1.4.1.7547.4.2.2.7 NAME 'papiGroupId'
                 DESC 'Group name'
                 EQUALITY caseIgnoreMatch
                 SUBSTR caseIgnoreSubstringsMatch
                 SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )

FUNCTIONS

VerifyUser($con, $cfg)
This function is intended to be hooked at the authenticationHook in a PAPI AuthServer. It uses the connection variable password (and any other required by the user template, see below) to validate an authentication request against the LDAP server defined by the configurations variables LDAPserver (defaults to ``ldap'') and LDAPport (defaults to 389). If the configuration variable LDAPS is set to 1, the connection will use TLS (and the default port will be 636). TLS parameters can configured by means of LDAPS* variables.
Authentication is performed by:
1. Creating a LDAP connection according to the values of LDAPserver, LDAPport and LDAPS*.
2. Binding to the LDAP server either anonymously or using the parameters defined by LDAPbindDN and LDAPbindPassword.
3. Searching under the LDAP location defined by LDAPAuthSearchBase for an entry of class PAPIuser that matches the filter defined by the configuration variable LDAPUSERtemplate. Search is performed using the scope defined by LDAPAuthScope (subtree by default). Connection and/or configuration variables are substituted into the DN template using the syntax <papi var=``VarName''/>, the same used for substituting PAPI AuthServer variables in other templates. By default, the template is:
 uid=<papi var="username"/>
4. Trying to bind to the LDAP server using the DN determined in the step above and the value of password.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
UserCredentials($con, $cfg)
This function is intended to be hooked at the credentialHook in a PAPI AuthServer. It uses LDAP to retrieve the list of site definitions a user can connect to. It returns data for the sites included in the user entry itself and in the entries for those groups the user belongs to. The user definition into the LDAP server is located using the following procedure:
1. Create a LDAP connection according to the values of LDAPserver, LDAPport and LDAPS*.
2. Bind to the LDAP server either anonymously or using the parameters defined by LDAPbindDN and LDAPbindPassword.
3. Search under the LDAP location defined by LDAPAuthSearchBase for an entry of class PAPIuser that matches the filter defined by the configuration variable LDAPUSERtemplate. Search is performed using the scope defined by LDAPAuthScope (subtree by default) Connection and/or configuration variables are substituted into the DN template using the syntax <papi var=``VarName''/>, the same used for substituting PAPI AuthServer variables in other templates. By default, the template is:
 uid=<papi var="PAPIuid"/>
Objects are searched in the server using the LDAP search base defined by the configuration variable LDAPsearchBase (defaults to ``'').
Assertions are built from the user data and every site data using the result returned by buildAssertion (see below).
If the configuration variable useDefaultSite exists and is set to a non-zero value, it also includes an empty site definition, so the AuthServer appends a new site using the default values it is applying.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
GroupList($con, $cfg)
This function is intended to be hooked at the credentialHook in a PAPI AuthServer. It returns a site list consisting of the sites related to the groups whose identifiers are included into the configuration variable groupList. The list has to be comma-separated.
The function binds to the LDAP server defined by the configurations variables LDAPserver (defaults to ``ldap'') and LDAPport (defaults to 389), either anonymously or using the parameters defined by LDAPbindDN and LDAPbindPassword. Objects are searched in the server using the LDAP search base defined by the configuration variable LDAPsearchBase (defaults to ``'').
Assertions are built from the user data and every site data using the result returned by buildAssertion (see below).
If the configuration variable useDefaultSite exists and is set to a non-zero value, it also includes an empty site definition, so the AuthServer appends a new site using the default values it is applying.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
AllSites($con, $cfg)
This function is intended to be hooked at the credentialHook in a PAPI AuthServer. It returns a site list consisting of all the sites known to the LDAP server.
The function binds to the LDAP server defined by the configurations variables LDAPserver, LDAPport and LDAPS*, either anonymously or using the parameters defined by LDAPbindDN and LDAPbindPassword. Objects are searched in the server using the LDAP search base defined by the configuration variable LDAPsearchBase (defaults to ``'').
Assertions are built from the user data and the every site data using the result returned by buildAssertion (see below).
If the configuration variable useDefaultSite exists and is set to a non-zero value, it also includes an empty site definition, so the AuthServer appends a new site using the default values it is applying.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
DefCredentials ()
This function is intended to be hooked at the credentialHook in a PAPI AuthServer. It just returns an empty site list, so the default values configured for the AuthServer are used. To be used as a stub when no other more sophisticated credentials assignment methods are requested.
Arguments:
None
UserAttributes($con, $cfg)
This function is intended to be hooked at the attrRequestHook in a PAPI AuthServer. It uses the connection variable PAPIPOAURL to look for a defined site in the LDAP base defined by the configuration variables LDAPserver, LDAPport and LDAPsearchBase (and, optionally, LDAPS*, LDAPbindDN and LDAPbindPassword). User data is determined by means of the DN found by means of by LDAPUSERtemplate and LDAPAuthSearchBase, as described for UserCredentials() above.
If a suitable site is found, it returns the applicable assertion format and the time-to-live defined for the site. If no site is found matching the requesting URL, it sets the PAPIerror variable and a negative value is returned.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
GroupListAttributes($con, $cfg)
This function is intended to be hooked at the attrRequestHook in a PAPI AuthServer. It uses the connection variable PAPIPOAURL to look for a defined site in the LDAP base defined by the configuration variables LDAPserver, LDAPport and LDAPsearchBase (and, optionally, LDAPS*, LDAPbindDN and LDAPbindPassword). The site must be defined inside the list of papiSite objects defined by the configuration variable groupList. If a suitable site is found, it returns the applicable assertion format and the time-to-live defined for the site. If no site is found matching the requesting URL, it sets the PAPIerror variable and a negative value is returned.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
AllSiteAttributes($con, $cfg)
This function is intended to be hooked at the attrRequestHook in a PAPI AuthServer. It uses the connection variable PAPIPOAURL to look for a site defined site within the LDAP base defined by the configuration variables LDAPserver, LDAPport and LDAPsearchBase (and, optionally, LDAPS*, LDAPbindDN and LDAPbindPassword). If a suitable site is found, it returns the applicable assertion format and the time-to-live defined for the site. If no site is found matching the requesting URL, it sets the PAPIerror variable and a negative value is returned.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
DefAttributes($con, $cfg)
This function is intended to be hooked at the attrRequestHook in a PAPI AuthServer. It uses the connection variable PAPIPOAURL to match against the default site defined for the AuthServer. It can be used as a stub when no other more sophisticated methods are requested.
Arguments:
$con: Hash with the PAPI AuthServer connection variables.
$cfg: Hash with the PAPI AuthServer configuration variables.
buildAssertion ($siteRef, $groupListRef, $userRef)
This is an auxiliary function for calculating the correct assertion to be sent to the PoA defined for a given papiSite object.
It uses the attribute papiAssertion in the papiSite object and/or the attributes papiQualifiedAssertion in the applicable papiUser and/or papiGroup objects, according to the following rules:
  1. Use the format defined by the attribute papiQualifiedAssertion matching the papiSiteID for the corresponding site defined in the papiUser entry.

  2. If (1) is not applicable, use the format defined by the attribute papiQualifiedAssertion that matches the papiSiteID for the corresponding site in any of the applicable papiGroup objects.

  3. If (2) is not applicable, use the format defined by the attribute papiAssertion of the papiSite object for the corresponding site.

  4. If (3) is not applicable, leave the assertion empty, so the default value is used (see AuthServer).

Once the assertion format has been identified (and provided it is not empty) the string is passed to expandAssertion (see below) in order to get the appropriate attribute expansions prior to returning the final value.

Arguments:

$siteRef: A reference to a Net::LDAP::Entry object, holding the papiSite object describing the corresponding site.

$groupListRef: A reference to a (possibly empty) list of Net::LDAP::Entry object references, each one holding a papiGroup object describing a applicable group.

$userRef: A (possibly undefined) reference to a Net::LDAP::Entry object, holding the papiUser object corresponding to the applicable user.

expandAssertion ($userRef, $assertion)
This is an auxiliary function for expanding attribute values into the assertion to be sent to the PoA defined for a given papiSite object.
Expansions are performed by substituting two different constructs with the values of attributes of the object describing the applicable papiUser, passed as first argument. These constructs are:
<papi attr=``AttrName''/>, substituted by the value of the attribute 'AttrName' in the user's entry. If 'AttrName' is multivalued, the first value returned by the LDAP server is used.
<papi attrlist=``AttrName'' sep=``String''/>, substituted by a string built by composing the values of attribute 'AttrName' in the user's entry using the value of 'String' as separator.
If the reference to the papiUser entry is not defined, or any of the referred attributes does not hold a value, the corresponding elements are substituted by an empty string.
Arguments:
$userRef: A (possibly undefined) reference to a Net::LDAP::Entry object, holding the papiUser object corresponding to the applicable user.
$assertion: The string containing the assertion format to be expanded.

Configuring TLS access

The LDAPS variable, if set to 1, directs the functions desscribed here to use TLS when connecting to the LDAP server. LDAPS* variables are used to configure the TLS parameters used by Net::LDAP. Each of these variables corresponds to a TLS-configuring value, defined by the suffix in its name. Altough you should refer to the documentation of your installed Net::LDAP module for more details, these are some of the more significative:

LDAPSverify 'none'|'optional'|'require'
Set the Net::LDAP variable verify, defining how to verify the server's certificate:
none: The server may provide a certificate but it will not be checked
optional: Verify only when the server offers a certificate
require: The server must provide a certificate, and it must be valid.
LDAPSclientcert /path/to/cert.pem
LDAPSclientkey /path/to/key.pem
If you want to use the client to offer a certificate to the server for SSL authentication, these variables set the Net::LDAP variables clientcert and clientkey to the files holding the certificate and the private key, respectively. These files must be in PEM format.
LDAPScapath /path/to/CAcertDir/
LDAPScafile /path/to/CAcert.pem
When verifying the server's certificate, either set the Net::LDAP variable capatht to the pathname of the directory containing CA certificates, or set cafile to the filename containing the certificate of a CA recognized to sign the server's certificate. These certificates must all be in PEM format.

SEE ALSO

PAPI AuthServer

The documentation of your installed Net::LDAP module.