From 6fee1e3e057e548b152a16befd2159446dee1a61 Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Mon, 27 Jul 2015 17:49:25 +0200 Subject: [PATCH] (auth) add ldap helper class --- .../mvc/app/library/OPNsense/Auth/LDAP.php | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php b/src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php new file mode 100644 index 000000000..5efeac373 --- /dev/null +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/LDAP.php @@ -0,0 +1,210 @@ +ldapHandle !== null) { + @ldap_close($this->ldapHandle); + } + } + + /** + * add additional query result attributes + * @param $attrName string attribute to append to result list + */ + private function addSearchAttribute($attrName) + { + if (!array_key_exists($attrName, $this->ldapSearchAttr)) { + $this->ldapSearchAttr[] = $attrName; + } + + } + + /** + * search ldap tree + * @param $filter ldap filter string to use + * @param string $ldap_scope scope either one or tree + * @return array|bool result list or false on errors + */ + private function search($filter, $ldap_scope = "tree") + { + $result = false; + if ($this->ldapHandle != null) { + foreach (explode(";", $this->baseSearchDN) as $baseDN) { + if ($ldap_scope == "one") { + $sr=@ldap_list($this->ldapHandle, $baseDN, $filter, $this->ldapSearchAttr); + } else { + $sr=@ldap_search($this->ldapHandle, $baseDN, $filter, $this->ldapSearchAttr); + } + if ($sr !== false) { + $info = @ldap_get_entries($this->ldapHandle, $sr); + if ($info !== false) { + if ($result === false) { + $result = array(); + $result['count'] = 0; + } + for ($i = 0; $i < $info["count"]; $i++) { + $result['count']++; + $result[] = $info[$i]; + } + } + } + } + } + return $result; + } + + /** + * @param null $baseSearchDN setup base searchDN or list of DN's separated by ; + * @param int $ldapVersion setup ldap version + */ + public function __construct($baseSearchDN = null, $ldapVersion = 3) + { + $this->ldapVersion = $ldapVersion; + $this->baseSearchDN = $baseSearchDN; + // setup ldap general search list, list gets updated by requested data + $this->addSearchAttribute("dn"); + $this->addSearchAttribute("name"); + } + + /** + * close ldap handle on destruction + */ + public function __destruct() + { + $this->closeLDAPHandle(); + } + + /** + * @param $bind_url string url to use + * @param null $userdn connect dn to use, leave empty for anonymous + * @param null $password password + * @return bool connect status (success/fail) + */ + public function connect($bind_url, $userdn = null, $password = null) + { + $this->closeLDAPHandle(); + $this->ldapHandle = @ldap_connect($bind_url); + + if ($this->ldapHandle !== false) { + ldap_set_option($this->ldapHandle, LDAP_OPT_REFERRALS, 0); + ldap_set_option($this->ldapHandle, LDAP_OPT_DEREF, LDAP_DEREF_SEARCHING); + ldap_set_option($this->ldapHandle, LDAP_OPT_PROTOCOL_VERSION, (int)$this->ldapVersion); + $bindResult = @ldap_bind($this->ldapHandle, $userdn, $password); + if ($bindResult) { + return true; + } + } + + $this->ldapHandle = null; + return false; + } + + /** + * search user by name or expression + * @param $username string username(s) to search + * @param $userNameAttribute string ldap attribute to use for the search + * @return array|bool + */ + public function searchUsers($username, $userNameAttribute) + { + if ($this->ldapHandle !== false) { + // add $userNameAttribute to search results + $this->addSearchAttribute($userNameAttribute); + $result = array(); + $searchResults = $this->search("({$userNameAttribute}={$username})"); + if ($searchResults !== false) { + for ($i = 0; $i < $searchResults["count"]; $i++) { + // fetch distinguished name and most likely username (try the search field first) + foreach (array($userNameAttribute, "name") as $ldapAttr) { + if (isset($searchResults[$i][$ldapAttr]) && $searchResults[$i][$ldapAttr]['count'] > 0) { + $result[] = array("name" => $searchResults[$i][$ldapAttr][0] + , "dn" => $searchResults[$i]['dn']); + break; + } + } + } + return $result; + } + } + return false; + } + + /** + * List organizational units + * @return array|bool list of OUs or false on failure + */ + public function listOUs() + { + $result = array(); + if ($this->ldapHandle !== false) { + $searchResults = $this->search("(|(ou=*)(cn=Users))"); + if ($searchResults !== false) { + for ($i = 0; $i < $searchResults["count"]; $i++) { + $result[] = $searchResults[$i]['dn']; + } + + return $result; + } + } + + return false; + } +}