<?php
error_reporting(0);
#=== FUNCTION ==================================================================
# NAME: ldapAuthenticationAndAuthorizationWithAttributes
# PARAMETERS:
# $strLDAPHost String LDAP Server URI
# $strUIDAttr String Schema attribute for user ID search
# $strSystemUser String System credential username
# $strSystemPassword String System credential password
# $strUserBaseDN String User search LDAP base DN
# $strLogonUserID String Input user ID
# $strLogonUserPassword String Input user password
# $arrayAttrsToReturn String Attributes to be returned
# $strGroupBaseDN String (optional) Group search LDAP base DN
# $strGroupNamingAttribute String (optional) Schema attribute for group search
# $strMembershipAttr String (optional) Schema attribute for group membership
# $strAuthGroup String (optional) Group name
# DESCRIPTION: Verify authentication and authorization against AD server.a
#
# RETURNS: array(BindReturnCode, Authorized, array(returnValues))
# BindReturnCode: -1 indicates LDAP connection failure, -2 indicates system account auth failed, -3 indicates user auth not attempted, >=0 is IANA-registered resultCode values (https://www.iana.org/assignments/ldap-parameters/ldap-parameters.xml#ldap-parameters-6)
# NOTE: 0 is successful authentication in IANA-registered resultCode
# Authorized: 0 authorization not attempted, -1 is not a member of the located group, 1 is member of the located group
# arrayUserAttributeValues Array with values of $arrayAttrsToReturn
#
# USAGE: $arrayUserAuthorized = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", $strInputUserName, $strInputUserPassword, array('givenName', 'sn'), "ou=securitygroups,dc=example,dc=com","cn", "member", "LJRTestGroup")
#===============================================================================
function ldapAuthenticationAndAuthorizationWithAttributes($strLDAPHost,$strUIDAttr, $strSystemUser, $strSystemPassword, $strUserBaseDN, $strLogonUserID, $strLogonUserPassword, $arrayAttrsToReturn, $strGroupBaseDN=null, $strGroupNamingAttribute=null, $strMembershipAttr=null, $strAuthGroup=null){
$arrayAuthResults = array();
$arrayUserAttributeValues = array();
// Validate password is not null, otherwise directory servers implementing unauthenticated bind (https://tools.ietf.org/html/rfc4513#section-5.1.2) will return 0 on auth attempts with null password
if( strlen($strLogonUserPassword) < 1){
$arrayAuthResults['BindReturnCode'] = -3;
$arrayAuthResults['Authorized'] = -1;
}
else{
// Connect to the LDAP directory for system ID queries
$systemDS = ldap_connect($strLDAPHost);
ldap_set_option($systemDS, LDAP_OPT_PROTOCOL_VERSION, 3);
if ($systemDS) {
// Bind with the system ID and find $strLogonUserID FQDN
$systemBind = ldap_bind($systemDS, $strSystemUser, $strSystemPassword);
if(ldap_errno($systemDS) == 0){
$strLDAPFilter="(&($strUIDAttr=$strLogonUserID))";
$result=ldap_search($systemDS,$strUserBaseDN,$strLDAPFilter, $arrayAttrsToReturn);
$entry = ldap_first_entry($systemDS, $result);
$strFoundUserFQDN= ldap_get_dn($systemDS, $entry);
if($strFoundUserFQDN){
$userDS = ldap_connect($strLDAPHost);
ldap_set_option($userDS, LDAP_OPT_PROTOCOL_VERSION, 3);
$userBind = ldap_bind($userDS, $strFoundUserFQDN, $strLogonUserPassword);
$arrayAuthResults['BindReturnCode'] = ldap_errno($userDS);
ldap_close($userDS);
if($arrayAuthResults['BindReturnCode'] == 0){
$objFoundUser = ldap_get_entries($systemDS, $result);
for($arrayAttrsToReturn as $strAttributeName){
$arrayUserAttributeValues[$strAttributeName] = $objFoundUser[0][$strAttributeName];
}
$arrayAuthResults['AttributeValues'] = $arrayUserAttributeValues;
//////////////////////////////////////////////////////////////////////////////////////
// If an auth group has been supplied, verify authorization
//////////////////////////////////////////////////////////////////////////////////////
if($strAuthGroup){
// Escapes in DN need to be double-escaped or bad search filter error is encountered
$strGroupQuery = "(&($strGroupNamingAttribute=$strAuthGroup)($strMembershipAttr=" . str_replace("\\","\\\\", $strFoundUserFQDN) . "))";
$groupResult = ldap_search($systemDS,$strGroupBaseDN, $strGroupQuery);
$authorisedState = ldap_count_entries($systemDS ,$groupResult);
// If a group matching the filter is found, the user is authorised
if($authorisedState == 1){
$arrayAuthResults['Authorized'] = 1;
}
// Otherwise the user is not a member of the group and is not authorised
else{
$arrayAuthResults['Authorized'] = -1;
}
}
else{
$arrayAuthResults['Authorized'] = 0;
}
//////////////////////////////////////////////////////////////////////////////////////
ldap_close($systemDS);
}
// If the bind failed, the user has not logged in successfully so they cannot be authorized
else{
$arrayAuthResults['Authorized'] = -1;
ldap_close($systemDS);
ldap_close($userDS);
}
}
// User not found in directory
else{
$arrayAuthResults['BindReturnCode'] = 32;
$arrayAuthResults['Authorized'] = -1;
}
}
// system bind failed
else{
$arrayAuthResults['BindReturnCode'] = -2;
$arrayAuthResults['Authorized'] = -1;
ldap_close($systemDS);
}
}
// ldap connection failed
else{
$arrayAuthResults['BindReturnCode'] = -1;
$arrayAuthResults['Authorized'] = -1;
}
}
return $arrayAuthResults;
}
print "User password not supplied:\n";
$arrayNullPassword = array();
$arrayNullPassword = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", '');
var_dump($arrayNullPassword);
print "Bad password:\n";
$arrayBadPassword = array();
$arrayBadPassword = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'N0tTh3P@s5w0rd',"ou=SecurityGroups,dc=example,dc=com","cn", "member");
var_dump($arrayBadPassword);
print "\nInvalid user:\n";
$arrayUserNotInDirectory = array();
$arrayUserNotInDirectory = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "xe0012345", 'xDoesN0tM@tt3r');
var_dump($arrayUserNotInDirectory);
print "\nGood password without authorization:\n";
$arrayUserAuthenticated = array();
$arrayUserAuthenticated = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re');
var_dump($arrayUserAuthenticated);
print "\nGood password with authorized user:\n";
$arrayUserAuthorized = array();
$arrayUserAuthorized = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re',"ou=SecurityGroups,dc=example,dc=com","cn", "member", "cfyP_Unix_UnixUsers");
var_dump($arrayUserAuthorized);
print "\nGood password with unauthorized user:\n";
$arrayUserNotAuthorized = array();
$arrayUserNotAuthorized = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "Sy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re',"ou=SecurityGroups,dc=example,dc=com","cn", "member", "WIN AM Team West");
var_dump($arrayUserNotAuthorized);
print "\nBad system account:\n";
$arrayBadSystemCred = array();
$arrayBadSystemCred = ldapAuthenticationAndAuthorizationWithAttributes("ldaps://ad.example.com","sAMAccountName","ldapquery@example.com", "xSy5t3mP@ssw0rdG03sH3re", "ou=example,dc=example,dc=com", "e0012345", 'Us3rP@s5w0rdG035H3re|Us3rP@s5w0rdG035H3re');
var_dump($arrayBadSystemCred);
?>