diff options
author | Freya Murphy <freya@freyacat.org> | 2024-05-30 13:05:46 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-05-30 13:05:46 -0400 |
commit | 39bcb09a367251bed7cfb445f546252547058e66 (patch) | |
tree | a1bb8e2c137e16202836ea6df8d7004b5e48e8a6 /src/web/helpers/ldap.php | |
parent | am dumb (diff) | |
download | ldap_forwardauth-39bcb09a367251bed7cfb445f546252547058e66.tar.gz ldap_forwardauth-39bcb09a367251bed7cfb445f546252547058e66.tar.bz2 ldap_forwardauth-39bcb09a367251bed7cfb445f546252547058e66.zip |
many changes
Diffstat (limited to 'src/web/helpers/ldap.php')
-rw-r--r-- | src/web/helpers/ldap.php | 133 |
1 files changed, 106 insertions, 27 deletions
diff --git a/src/web/helpers/ldap.php b/src/web/helpers/ldap.php index f3697cc..46bbe69 100644 --- a/src/web/helpers/ldap.php +++ b/src/web/helpers/ldap.php @@ -1,41 +1,120 @@ <?php /* Copyright (c) 2024 Freya Murphy */ -function ldap_auth($auth_username, $auth_password) { - $url = getenv("LDAP_URL"); - $bind = getenv("LDAP_BIND_DN"); - $password = getenv("LDAP_BIND_PASSWORD"); - $bound = getenv("LDAP_BASE_DN"); - $filter = getenv("LDAP_FILTER"); - $uid = getenv("LDAP_UID"); +class LDAPHelper { - $conn = @ldap_connect($url); - if (!$conn) { - return NULL; + private ?\LDAP\Connection $conn; + private array $env; + private array $matchers; + + private ?string $bound; + + function __construct() { + $this->env = array( + # ldap host + 'url' => getenv("LDAP_URL"), + # ldap credentials + 'bind' => getenv("LDAP_BIND_DN"), + 'password' => getenv("LDAP_BIND_PASSWORD"), + # ldap search + 'base' => getenv("LDAP_BASE_DN"), + 'filter' => getenv("LDAP_FILTER"), + 'uid' => getenv("LDAP_UID"), + ); + + $this->matchers = array( + 'username' => getenv("LDAP_USERNAME_MATCHER"), + 'email' => getenv("LDAP_EMAIL_MATCHER"), + 'first_name' => getenv("LDAP_FIRST_NAME_MATCHER"), + 'last_name' => getenv("LDAP_LAST_NAME_MATCHER"), + ); + + $this->bound = NULL; + $this->conn = NULL; + } + + private function connect(): int { + if (($this->conn = @ldap_connect($this->env['url'])) == FALSE) { + $this->conn = NULL; + return 1; + } + @ldap_set_option($this->conn, LDAP_OPT_PROTOCOL_VERSION, 3); + return 0; } - ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); - $bind_conn = @ldap_bind($conn, $bind, $password); - if (!$bind_conn) { - return NULL; + private function rebind(): int { + if ($this->bound != $this->env['bind']) { + return $this->bind( + $this->env['bind'], + $this->env['password']); + } + return 0; } - $search = @ldap_search($conn, $bound, $filter); + public function bind( + string $dn, + #[\SensitiveParameter] string $password + ): int { + if ($this->conn == NULL && $this->connect()) { + return 1; + } + if (@ldap_bind($this->conn, $dn, $password) == FALSE) { + return 1; + } + $this->bound = $dn; + return 0; + } - $info = @ldap_get_entries($conn, $search); - $user = NULL; - for ($i=0; $i<$info['count']; $i++) { - $user = $info[$i]; - if (!array_key_exists($uid, $user)) - continue; - if ($user[$uid][0] == $auth_username) - break; + /** + * @param array<int,mixed> $user + */ + private function find_entry(array $user, string $field): mixed { + if (!isset($user[$field])) + return NULL; + $data = $user[$field]; + if (is_array($data)) + $data = $data[0]; + return $data; } - if ($user == NULL) { - return FALSE; + public function search( + string ...$usernames + ): ?array { + if ($this->rebind()) + return NULL; + + $search = @ldap_search( + $this->conn, + $this->env['base'], + $this->env['filter'] + ); + if ($search == FALSE) + return NULL; + + $info = @ldap_get_entries($this->conn, $search); + + $users = array(); + + for ($i=0; $i<$info['count']; $i++) { + $user_arr = $info[$i]; + $user_data = array ( + 'dn' => $user_arr['dn'], + 'username' => $this->find_entry($user_arr, $this->matchers['username']), + 'email' => $this->find_entry($user_arr, $this->matchers['email']), + 'first_name' => $this->find_entry($user_arr, $this->matchers['first_name']), + 'last_name' => $this->find_entry($user_arr, $this->matchers['last_name']) + ); + $user = new User(); + if ($user->from_array($user_data)) { + continue; + } + if (count($usernames) && !in_array($user->username, $usernames)) { + continue; + } + $users[] = $user; + } + + return $users; } - $succ = @ldap_bind($conn, $user['dn'], $auth_password); - return !!$succ; } |