Add cache of LDAP users, stored as option in YOURLS database. Add ability to bind using current user (useful for AD/Samba)
This commit is contained in:
parent
c431aca6c4
commit
a7fe07614a
75
plugin.php
75
plugin.php
@ -57,21 +57,35 @@ yourls_add_filter( 'is_valid_user', 'ldapauth_is_valid_user' );
|
|||||||
|
|
||||||
// returns true/false
|
// returns true/false
|
||||||
function ldapauth_is_valid_user( $value ) {
|
function ldapauth_is_valid_user( $value ) {
|
||||||
// doesn't work for API...
|
global $yourls_user_passwords;
|
||||||
if (yourls_is_API())
|
global $ydb;
|
||||||
|
|
||||||
|
$ldapauth_usercache = $ydb->option['ldapauth_usercache'];
|
||||||
|
|
||||||
|
// no point in continuing if the user has already been validated by core
|
||||||
|
if ($value) {
|
||||||
|
ldapauth_debug("Returning from ldapauth_is_valid_user as user is already validated");
|
||||||
return $value;
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@session_start();
|
@session_start();
|
||||||
|
|
||||||
|
|
||||||
// Always check & set early
|
// Always check & set early
|
||||||
if ( !ldapauth_environment_check() ) {
|
if ( !ldapauth_environment_check() ) {
|
||||||
die( 'Invalid configuration for YOURLS LDAP plugin. Check PHP error log.' );
|
die( 'Invalid configuration for YOURLS LDAP plugin. Check PHP error log.' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* is the cookie needed anymore? Since the user cache is merged with $yourls_user_passwords
|
||||||
|
* core's yourls_check_auth_cookie should work. If so, a logged in user will arrive in this
|
||||||
|
* function with $value true, the function returns early and we never get here
|
||||||
|
*/
|
||||||
if ( isset( $_SESSION['LDAPAUTH_AUTH_USER'] ) ) {
|
if ( isset( $_SESSION['LDAPAUTH_AUTH_USER'] ) ) {
|
||||||
// already authenticated...
|
// already authenticated...
|
||||||
$username = $_SESSION['LDAPAUTH_AUTH_USER'];
|
$username = $_SESSION['LDAPAUTH_AUTH_USER'];
|
||||||
if ( ldapauth_is_authorized_user( $username ) ) {
|
// why is this checked here, but not before the cookie is set?
|
||||||
|
if ( ldapauth_is_authorized_user( $username ) ) {
|
||||||
yourls_set_user( $_SESSION['LDAPAUTH_AUTH_USER'] );
|
yourls_set_user( $_SESSION['LDAPAUTH_AUTH_USER'] );
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@ -84,14 +98,24 @@ function ldapauth_is_valid_user( $value ) {
|
|||||||
$ldapConnection = ldap_connect(LDAPAUTH_HOST, LDAPAUTH_PORT);
|
$ldapConnection = ldap_connect(LDAPAUTH_HOST, LDAPAUTH_PORT);
|
||||||
if (!$ldapConnection) die("Cannot connect to LDAP " . LDAPAUTH_HOST);
|
if (!$ldapConnection) die("Cannot connect to LDAP " . LDAPAUTH_HOST);
|
||||||
ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||||
|
//ldap_set_option($ldapConnection, LDAP_OPT_REFERRALS, 0);
|
||||||
|
|
||||||
// Check if using a privileged user account to search
|
// should we to try and bind using the credentials being logged in with?
|
||||||
if (defined('LDAPAUTH_SEARCH_USER') && defined('LDAPAUTH_SEARCH_PASS')) {
|
if (defined('LDAPAUTH_BIND_WITH_USER_TEMPLATE')) {
|
||||||
|
$bindRDN = sprintf(LDAPAUTH_BIND_WITH_USER_TEMPLATE, $_REQUEST['username']);
|
||||||
|
if (!($ldapSuccess = @ldap_bind($ldapConnection, $bindRDN, $_REQUEST['password']))) {
|
||||||
|
error_log('Couldn\'t bind to LDAP server with user ' . $bindRDN);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if using a privileged user account to search - only if not already bound with current user
|
||||||
|
if (defined('LDAPAUTH_SEARCH_USER') && defined('LDAPAUTH_SEARCH_PASS') && empty($ldapSuccess)) {
|
||||||
if (!@ldap_bind($ldapConnection, LDAPAUTH_SEARCH_USER, LDAPAUTH_SEARCH_PASS)) {
|
if (!@ldap_bind($ldapConnection, LDAPAUTH_SEARCH_USER, LDAPAUTH_SEARCH_PASS)) {
|
||||||
die('Couldn\'t bind search user ' . LDAPAUTH_SEARCH_USER);
|
die('Couldn\'t bind search user ' . LDAPAUTH_SEARCH_USER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit the attrs to the ones we need
|
// Limit the attrs to the ones we need
|
||||||
$attrs = array('dn', LDAPAUTH_USERNAME_FIELD);
|
$attrs = array('dn', LDAPAUTH_USERNAME_FIELD);
|
||||||
if (defined('LDAPAUTH_GROUP_ATTR'))
|
if (defined('LDAPAUTH_GROUP_ATTR'))
|
||||||
@ -102,8 +126,10 @@ function ldapauth_is_valid_user( $value ) {
|
|||||||
$searchResult = ldap_get_entries($ldapConnection, $searchDn);
|
$searchResult = ldap_get_entries($ldapConnection, $searchDn);
|
||||||
if (!$searchResult) return $value;
|
if (!$searchResult) return $value;
|
||||||
$userDn = $searchResult[0]['dn'];
|
$userDn = $searchResult[0]['dn'];
|
||||||
if (!$userDn) return $value;
|
if (!$userDn && !$ldapSuccess) return $value;
|
||||||
$ldapSuccess = @ldap_bind($ldapConnection, $userDn, $_REQUEST['password']);
|
if (empty($ldapSuccess)) { // we don't need to do this if we already bound using username and LDAPAUTH_BIND_WITH_USER_TEMPLATE
|
||||||
|
$ldapSuccess = @ldap_bind($ldapConnection, $userDn, $_REQUEST['password']);
|
||||||
|
}
|
||||||
@ldap_close($ldapConnection);
|
@ldap_close($ldapConnection);
|
||||||
|
|
||||||
// success?
|
// success?
|
||||||
@ -119,18 +145,25 @@ function ldapauth_is_valid_user( $value ) {
|
|||||||
foreach($searchResult[0][LDAPAUTH_GROUP_ATTR] as $grps) {
|
foreach($searchResult[0][LDAPAUTH_GROUP_ATTR] as $grps) {
|
||||||
if (in_array(strtolower($grps), $groups_to_check)) { $in_group = true; break; }
|
if (in_array(strtolower($grps), $groups_to_check)) { $in_group = true; break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$in_group) die('Not in admin group');
|
if (!$in_group) die('Not in admin group');
|
||||||
}
|
}
|
||||||
|
|
||||||
$username = $searchResult[0][LDAPAUTH_USERNAME_FIELD][0];
|
$username = $searchResult[0][LDAPAUTH_USERNAME_FIELD][0];
|
||||||
|
if (empty($username)) {
|
||||||
|
// try with it lower cased
|
||||||
|
$username = $searchResult[0][strtolower(LDAPAUTH_USERNAME_FIELD)][0];
|
||||||
|
}
|
||||||
yourls_set_user($username);
|
yourls_set_user($username);
|
||||||
global $yourls_user_passwords;
|
|
||||||
|
|
||||||
if (LDAPAUTH_ADD_NEW && !array_key_exists($username, $yourls_user_passwords)) {
|
if (LDAPAUTH_ADD_NEW && !array_key_exists($username, $yourls_user_passwords)) {
|
||||||
ldapauth_create_user( $username, $_REQUEST['password'] );
|
ldapauth_create_user( $username, $_REQUEST['password'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store the current user credentials in our cache. This cuts down calls to the LDAP
|
||||||
|
// server, and allows API keys to work with LDAP users
|
||||||
|
$ldapauth_usercache[$username] = 'phpass:' . ldapauth_hash_password($_REQUEST['password']);
|
||||||
|
yourls_update_option('ldapauth_usercache', $ldapauth_usercache);
|
||||||
|
|
||||||
$yourls_user_passwords[$username] = ldapauth_hash_password($_REQUEST['password']);
|
$yourls_user_passwords[$username] = ldapauth_hash_password($_REQUEST['password']);
|
||||||
$_SESSION['LDAPAUTH_AUTH_USER'] = $username;
|
$_SESSION['LDAPAUTH_AUTH_USER'] = $username;
|
||||||
return true;
|
return true;
|
||||||
@ -166,6 +199,22 @@ function ldapauth_logout_hook( $args ) {
|
|||||||
setcookie('PHPSESSID', '', 0, '/');
|
setcookie('PHPSESSID', '', 0, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This action, called as early as possible, retrieves our cache of LDAP users and
|
||||||
|
* merges it with $yourls_user_passwords. This enables core to do the authorisation
|
||||||
|
* of previously seen LDAP users, and also means that API signatures for LDAP users
|
||||||
|
* will work. Users that exist in both users/config.php and LDAP will need to use
|
||||||
|
* their LDAP passwords
|
||||||
|
*/
|
||||||
|
yourls_add_action ('plugins_loaded', 'ldapauth_merge_users');
|
||||||
|
function ldapauth_merge_users() {
|
||||||
|
global $ydb;
|
||||||
|
global $yourls_user_passwords;
|
||||||
|
if(isset($ydb->option['ldapauth_usercache'])) {
|
||||||
|
ldapauth_debug("Merging text file users and cached LDAP users");
|
||||||
|
$yourls_user_passwords = array_merge($yourls_user_passwords, $ydb->option['ldapauth_usercache']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create user in config file
|
* Create user in config file
|
||||||
* Code reused from yourls_hash_passwords_now()
|
* Code reused from yourls_hash_passwords_now()
|
||||||
@ -209,3 +258,9 @@ function ldapauth_hash_password ($password) {
|
|||||||
|
|
||||||
return $pass_hash;
|
return $pass_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ldapauth_debug ($msg) {
|
||||||
|
if (defined('LDAPAUTH_DEBUG') && LDAPAUTH_DEBUG) {
|
||||||
|
error_log("yourls_ldap_auth: " . $msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user