From 39bcb09a367251bed7cfb445f546252547058e66 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 30 May 2024 13:05:46 -0400 Subject: many changes --- src/web/helpers/ldap.php | 135 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 28 deletions(-) (limited to 'src/web/helpers/ldap.php') 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 @@ 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; } - ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); - $bind_conn = @ldap_bind($conn, $bind, $password); - if (!$bind_conn) { - return 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; } - $search = @ldap_search($conn, $bound, $filter); + private function rebind(): int { + if ($this->bound != $this->env['bind']) { + return $this->bind( + $this->env['bind'], + $this->env['password']); + } + 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; + 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; } - if ($user == NULL) { - return FALSE; + /** + * @param array $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; + } + + 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; } -- cgit v1.2.3-freya