Added Active Directory LDAP hostname lookup

If you are using Active Directory, you likely have multiple LDAP servers.  Which servers your Windows clients use is controlled by a DNS entry for sites and services.  This DNS entry looks like _ldap._tcp.corporate._sites.yourdomain.com .  This code change allows for the LDAP host name to be looked up automatically based on the DNS entry.  This way if your Active Directory architecture changes (different Domain Controllers / LDAP servers ), you won't need to update this plugin's configuration.  This is only enabled if you set the new LDAPAUTH_DNS_SITES_AND_SERVICES configuration value.  Please see documentation in the README.md.
This commit is contained in:
Brooke Hedrick 2017-11-15 13:58:53 -06:00 committed by GitHub
parent 3e7f66652d
commit b8064a482b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 1 deletions

View File

@ -47,6 +47,11 @@ To define the type of user cache used:
To automatically add LDAP users to config.php:
* define( 'LDAPAUTH_ADD_NEW', true ); // (optional) Add LDAP users to config.php
To use Active Directory Sites and Services DNS entry for LDAP server name lookup
* define( 'LDAPAUTH_DNS_SITES_AND_SERVICES', '_ldap._tcp.corporate._sites.yourdomain.com' ); // If using Active Directory, with multiple Domain Controllers, the safe way to use DNS to look up your active LDAP server names. If set, it will be used to override the hostname portion of LDAPAUTH_HOST.
* define( 'LDAPAUTH_HOST', 'ldap://'); // LDAP protocol without hostname. You can use 'ldaps://' for LDAP with TLS.
NOTE: This will require config.php to be writable by your webserver user. This function is now largely unneeded because the database based cache offers similar benefits without the need to make config.php writeable. It is retained for backwards compatability
Troubleshooting

View File

@ -60,6 +60,61 @@ function ldapauth_environment_check() {
yourls_add_filter( 'is_valid_user', 'ldapauth_is_valid_user' );
function ldapauth_shuffle_assoc($list) {
if (!is_array($list)) return $list;
$keys = array_keys($list);
shuffle($keys);
$random = array();
foreach ($keys as $key) {
$random[$key] = $list[$key];
}
return $random;
}
// return list of Active Directory Ldap servers that are associated with a site and service
// example for $site = = '_ldap._tcp.corporate._sites.company.com'
function ldapauth_get_ad_servers_for_site() {
$results = [];
$ad_servers = dns_get_record(LDAPAUTH_DNS_SITES_AND_SERVICES, DNS_SRV, $authns, $addtl);
foreach ($ad_servers as $ad_server) {
array_push($results, $ad_server['target']);
}
$results = ldapauth_shuffle_assoc($results); #randomize the order
return $results;
}
// returns ldap connection
function ldapauth_get_ldap_connection() {
if (defined('LDAPAUTH_DNS_SITES_AND_SERVICES')) {
$connection = NULL;
$ldap_servers = ldapauth_get_ad_servers_for_site();
foreach ($ldap_servers as $ldap_server) {
$ldap_address = LDAPAUTH_HOST . $ldap_server;
try {
$temp_conn = ldap_connect($ldap_address, LDAPAUTH_PORT); # ldap_connect doesn't actually connect it just checks for plausiable parameters. Only ldap_bind connects
if ($temp_conn) {
$connection = $temp_conn;
break;
} else {
error_log('Warning, unable to connect to: ' . $ldap_address . ' on port ' . LDAPAUTH_PORT . '. ' . ldap_error($temp_conn));
}
} catch (Exception $e) {
error_log('Warning, unable to connect to: ' . $ldap_address . ' on port ' . LDAPAUTH_PORT . '. ' . __FILE__, __FUNCTION__,$e->getMessage());
}
}
if ($connection) {
return $connection;
} else {
die("Cannot connect to LDAP for site and service " . LDAPAUTH_DNS_SITES_AND_SERVICES);
}
} else {
return ldap_connect(LDAPAUTH_HOST, LDAPAUTH_PORT);
}
}
// returns true/false
function ldapauth_is_valid_user( $value ) {
global $yourls_user_passwords;
@ -106,7 +161,7 @@ function ldapauth_is_valid_user( $value ) {
&& !empty( $_REQUEST['username'] ) && !empty( $_REQUEST['password'] ) ) {
// try to authenticate
$ldapConnection = ldap_connect(LDAPAUTH_HOST, LDAPAUTH_PORT);
$ldapConnection = ldapauth_get_ldap_connection();
if (!$ldapConnection) die("Cannot connect to LDAP " . LDAPAUTH_HOST);
ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3);
//ldap_set_option($ldapConnection, LDAP_OPT_REFERRALS, 0);