mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Bind user before fetching (#9312)
* Bind user before fetching * fix style
This commit is contained in:
committed by
Neil Lathwood
parent
7c45cd5f69
commit
44747fda25
@@ -59,17 +59,19 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
|
||||
protected function userInGroup($username, $groupname)
|
||||
{
|
||||
$connection = $this->getConnection();
|
||||
|
||||
// check if user is member of the given group or nested groups
|
||||
$search_filter = "(&(objectClass=group)(cn=$groupname))";
|
||||
|
||||
// get DN for auth_ad_group
|
||||
$search = ldap_search(
|
||||
$this->ldap_connection,
|
||||
$connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
$search_filter,
|
||||
array("cn")
|
||||
);
|
||||
$result = ldap_get_entries($this->ldap_connection, $search);
|
||||
$result = ldap_get_entries($connection, $search);
|
||||
|
||||
if ($result == false || $result['count'] !== 1) {
|
||||
if (Config::get('auth_ad_debug', false)) {
|
||||
@@ -89,29 +91,29 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
$group_dn = $result[0]["dn"];
|
||||
|
||||
$search = ldap_search(
|
||||
$this->ldap_connection,
|
||||
$connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
// add 'LDAP_MATCHING_RULE_IN_CHAIN to the user filter to search for $username in nested $group_dn
|
||||
// limiting to "DN" for shorter array
|
||||
"(&" . $this->userFilter($username) . "(memberOf:1.2.840.113556.1.4.1941:=$group_dn))",
|
||||
array("DN")
|
||||
);
|
||||
$entries = ldap_get_entries($this->ldap_connection, $search);
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
|
||||
return ($entries["count"] > 0);
|
||||
}
|
||||
|
||||
public function userExists($username, $throw_exception = false)
|
||||
{
|
||||
$this->bind(); // make sure we called bind
|
||||
$connection = $this->getConnection();
|
||||
|
||||
$search = ldap_search(
|
||||
$this->ldap_connection,
|
||||
$connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
$this->userFilter($username),
|
||||
array('samaccountname')
|
||||
);
|
||||
$entries = ldap_get_entries($this->ldap_connection, $search);
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
|
||||
|
||||
if ($entries['count']) {
|
||||
@@ -124,8 +126,6 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
$this->bind(); // make sure we called bind
|
||||
|
||||
$userlevel = 0;
|
||||
if (!Config::get('auth_ad_require_groupmembership', true)) {
|
||||
if (Config::get('auth_ad_global_read', false)) {
|
||||
@@ -149,16 +149,16 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
$this->bind(); // make sure we called bind
|
||||
$connection = $this->getConnection();
|
||||
|
||||
$attributes = array('objectsid');
|
||||
$search = ldap_search(
|
||||
$this->ldap_connection,
|
||||
$connection,
|
||||
Config::get('auth_ad_base_dn'),
|
||||
$this->userFilter($username),
|
||||
$attributes
|
||||
);
|
||||
$entries = ldap_get_entries($this->ldap_connection, $search);
|
||||
$entries = ldap_get_entries($connection, $search);
|
||||
|
||||
if ($entries['count']) {
|
||||
return $this->getUseridFromSid($this->sidFromLdap($entries[0]['objectsid'][0]));
|
||||
@@ -170,49 +170,15 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
|
||||
/**
|
||||
* Bind to AD with the bind user if available, otherwise anonymous bind
|
||||
* @internal
|
||||
*
|
||||
* @param bool $allow_anonymous attempt anonymous bind if bind user isn't available
|
||||
* @param bool $force force rebind
|
||||
* @return bool success or failure
|
||||
*/
|
||||
protected function bind($allow_anonymous = true, $force = false)
|
||||
protected function init()
|
||||
{
|
||||
if ($this->is_bound && !$force) {
|
||||
return true; // bind already attempted
|
||||
if ($this->ldap_connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->connect(); // make sure we are connected
|
||||
|
||||
// set timeout
|
||||
ldap_set_option(
|
||||
$this->ldap_connection,
|
||||
LDAP_OPT_NETWORK_TIMEOUT,
|
||||
Config::get('auth_ad_timeout', 5)
|
||||
);
|
||||
|
||||
// With specified bind user
|
||||
if (Config::has('auth_ad_binduser') && Config::has('auth_ad_bindpassword')) {
|
||||
$this->is_bound = true;
|
||||
$bind = ldap_bind(
|
||||
$this->ldap_connection,
|
||||
Config::get('auth_ad_binduser') . '@' . Config::get('auth_ad_domain'),
|
||||
Config::get('auth_ad_bindpassword')
|
||||
);
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
return $bind;
|
||||
}
|
||||
|
||||
$bind = false;
|
||||
|
||||
// Anonymous
|
||||
if ($allow_anonymous) {
|
||||
$this->is_bound = true;
|
||||
$bind = ldap_bind($this->ldap_connection);
|
||||
}
|
||||
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
return $bind;
|
||||
$this->connect();
|
||||
$this->bind();
|
||||
}
|
||||
|
||||
protected function connect()
|
||||
@@ -242,9 +208,34 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
}
|
||||
|
||||
public function bind($username = null, $password = null)
|
||||
{
|
||||
if (!$this->ldap_connection) {
|
||||
$this->connect();
|
||||
}
|
||||
|
||||
if (Config::has('auth_ad_binduser') && Config::has('auth_ad_bindpassword')) {
|
||||
$username = Config::get('auth_ad_binduser');
|
||||
$password = Config::get('auth_ad_bindpassword');
|
||||
}
|
||||
$username .= '@' . Config::get('auth_ad_domain');
|
||||
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, Config::get('auth_ad_timeout', 5));
|
||||
$bind_result = ldap_bind($this->ldap_connection, $username, $password);
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
|
||||
if ($bind_result) {
|
||||
return;
|
||||
}
|
||||
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, Config::get('auth_ad_timeout', 5));
|
||||
ldap_bind($this->ldap_connection);
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
}
|
||||
|
||||
protected function getConnection()
|
||||
{
|
||||
$this->bind(); // make sure connected and bound
|
||||
$this->init(); // make sure connected and bound
|
||||
return $this->ldap_connection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,6 +267,37 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
return $this->ldap_connection; // bind already attempted
|
||||
}
|
||||
|
||||
if ($skip_bind) {
|
||||
$this->connect();
|
||||
} else {
|
||||
$this->bind();
|
||||
}
|
||||
|
||||
return $this->ldap_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $entry ldap entry array
|
||||
* @return array
|
||||
*/
|
||||
private function ldapToUser($entry)
|
||||
{
|
||||
$uid_attr = strtolower(Config::get('auth_ldap_uid_attribute', 'uidnumber'));
|
||||
return [
|
||||
'username' => $entry['uid'][0],
|
||||
'realname' => $entry['cn'][0],
|
||||
'user_id' => (int)$entry[$uid_attr][0],
|
||||
'email' => $entry[Config::get('auth_ldap_emailattr', 'mail')][0],
|
||||
'level' => $this->getUserlevel($entry['uid'][0]),
|
||||
];
|
||||
}
|
||||
|
||||
private function connect()
|
||||
{
|
||||
if ($this->ldap_connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!function_exists('ldap_connect')) {
|
||||
throw new AuthenticationException("PHP does not support LDAP, please install or enable the PHP LDAP extension.");
|
||||
}
|
||||
@@ -287,65 +318,43 @@ class LdapAuthorizer extends AuthorizerBase
|
||||
throw new AuthenticationException("Fatal error: LDAP TLS required but not successfully negotiated: $error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($skip_bind) {
|
||||
return $this->ldap_connection;
|
||||
}
|
||||
|
||||
public function bind($username = null, $password = null)
|
||||
{
|
||||
if (Config::get('auth_ldap_debug')) {
|
||||
ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
|
||||
}
|
||||
|
||||
// set timeout
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, Config::get('auth_ldap_timeout', 5));
|
||||
$this->connect();
|
||||
|
||||
if ((Config::has('auth_ldap_binduser') || Config::has('auth_ldap_binddn')) && Config::has('auth_ldap_bindpassword')) {
|
||||
$username = Config::get('auth_ldap_binddn', $this->getFullDn(Config::get('auth_ldap_binduser')));
|
||||
$password = Config::get('auth_ldap_bindpassword');
|
||||
} elseif ($username) {
|
||||
$username = $this->getFullDn($username);
|
||||
}
|
||||
|
||||
// With specified bind user
|
||||
if ((Config::has('auth_ldap_binduser') || Config::has('auth_ldap_binddn'))
|
||||
&& Config::has('auth_ldap_bindpassword')
|
||||
) {
|
||||
if (Config::has('auth_ldap_binddn')) {
|
||||
$bind_dn = Config::get('auth_ldap_binddn');
|
||||
} else {
|
||||
$bind_dn = $this->getFullDn(Config::get('auth_ldap_binduser'));
|
||||
}
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, Config::get('auth_ldap_timeout', 5));
|
||||
$bind_result = ldap_bind($this->ldap_connection, $username, $password);
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
|
||||
if (Config::get('auth_ldap_debug')) {
|
||||
echo "Bind result: " . ldap_error($this->ldap_connection) . PHP_EOL;
|
||||
}
|
||||
|
||||
$bind_result = ldap_bind($this->ldap_connection, $bind_dn, Config::get('auth_ldap_bindpassword'));
|
||||
|
||||
if (Config::get('auth_ldap_debug')) {
|
||||
echo "Bind result: " . ldap_error($this->ldap_connection) . PHP_EOL;
|
||||
}
|
||||
|
||||
if ($bind_result) {
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
return $this->ldap_connection;
|
||||
}
|
||||
if ($bind_result) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Anonymous
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, Config::get('auth_ldap_timeout', 5));
|
||||
ldap_bind($this->ldap_connection);
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
|
||||
if (Config::get('auth_ldap_debug')) {
|
||||
echo "Anonymous bind result: " . ldap_error($this->ldap_connection) . PHP_EOL;
|
||||
}
|
||||
|
||||
ldap_set_option($this->ldap_connection, LDAP_OPT_NETWORK_TIMEOUT, -1); // restore timeout
|
||||
return $this->ldap_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $entry ldap entry array
|
||||
* @return array
|
||||
*/
|
||||
private function ldapToUser($entry)
|
||||
{
|
||||
$uid_attr = strtolower(Config::get('auth_ldap_uid_attribute', 'uidnumber'));
|
||||
return [
|
||||
'username' => $entry['uid'][0],
|
||||
'realname' => $entry['cn'][0],
|
||||
'user_id' => (int)$entry[$uid_attr][0],
|
||||
'email' => $entry[Config::get('auth_ldap_emailattr', 'mail')][0],
|
||||
'level' => $this->getUserlevel($entry['uid'][0]),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@ class LegacyUserProvider implements UserProvider
|
||||
* Fetch user by username from legacy auth, update it or add it to the db then return it.
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @return User|null
|
||||
*/
|
||||
protected function fetchUserByName($username, $password = null)
|
||||
@@ -180,6 +181,11 @@ class LegacyUserProvider implements UserProvider
|
||||
$auth = LegacyAuth::get();
|
||||
$type = LegacyAuth::getType();
|
||||
|
||||
// ldap based auth we should bind before using, otherwise searches may fail due to anonymous bind
|
||||
if (method_exists($auth, 'bind')) {
|
||||
$auth->bind($username, $password);
|
||||
}
|
||||
|
||||
$auth_id = $auth->getUserid($username);
|
||||
$new_user = $auth->getUser($auth_id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user