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; } private function rebind(): int { if ($this->bound != $this->env['bind']) { return $this->bind( $this->env['bind'], $this->env['password']); } return 0; } 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; } /** * @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; } }