useLdap(); } public function useLdap() { $this->checkConfiguration(); return $this->LDAP_USED; } private function buildFakeLdapUsers() { return $this->buildFakeLdapUsersFromDB(); } private function buildFakeLdapUsersFromDB() { $users = TableRegistry::get('Users')->find(); $ldapUsers = []; foreach ($users as $user) { $names = explode(" ", $user['nom']); if (isset($names[1])) { $ldapUsers[] = [ 'sn' => [ $names[0] ], 'mail' => [ $user['email'] ], 'givenname' => [ $names[1] ], $this->authenticationType => [ $user['username'] ], 'userpassword' => [ $user['password'] ] ]; } else { $ldapUsers[] = [ 'sn' => [ $names[0] ], 'mail' => [ $user['email'] ], 'givenname' => " ", $this->authenticationType => [ $user['username'] ], 'userpassword' => [ $user['password'] ] ]; } } /* EP (aout 2017) * ATTENTION : Utilisateur IMPORTANT. * Avec cet utilisateur, on simule un utilisateur qui n'est PAS dans la table utilisateurs * Il devrait donc se voir attribuer un role "Utilisateur" sans pour autant que ça soit écrit dans la table !!! * login = '_NouvelUtilisateur_username' * pass = '_NouvelUtilisateur_password' * $prefix = "_NouvelUtilisateur_"; */ $ldapUsers[] = [ 'sn' => [ 'UTILISATEUR' ], 'givenname' => [ 'FAKE_LDAP' ], // 'mail' => [$login.'email'], 'mail' => [ 'fakeldapuser@domain.fr' ], // $this->authenticationType => [$prefix.'username'], $this->authenticationType => [ $this->getTheFakeLdapUser()['login'] ], // $this->authenticationType => ['usere'], 'userpassword' => [ $this->getTheFakeLdapUser()['pass'] ] // 'userpassword' => ['toto'], ]; return $ldapUsers; } private function checkConfiguration() { $config = TableRegistry::get('Configurations') ->find() ->where(['id =' => 1]) ->first(); $this->LDAP_USED = $config->ldap_used ? TRUE : FALSE; if ( ! $this->LDAP_USED ) { $this->authenticationType = $config->ldap_authenticationType; if (empty($this->fakeLDAPUsers)) $this->fakeLDAPUsers = $this->buildFakeLdapUsers(); return true; } // debug($this->fakeLDAPUsers); $ldapConfig = $config->toArray(); if (! empty($config->ldap_host) && ! empty($config->ldap_port) && ! empty($config->ldap_baseDn) && ! empty($config->ldap_authenticationType) && ! empty($config->ldap_filter)) { $this->host = $config->ldap_host; $this->port = $config->ldap_port; $this->baseDn = $config->ldap_baseDn; $this->filter = $config->ldap_filter; $this->authenticationType = $config->ldap_authenticationType; $this->ldap_authentified = $config->ldap_authentified; $this->bindDn = $config->ldap_bindDn; $this->bindPass = $config->ldap_bindPass; return true; } throw new Exception('The LDAP configuration is not valid :
'); } public function getAllLdapUsers() { try { if ($this->checkConfiguration()) { // REAL LDAP if ($this->LDAP_USED) { $ldapConnection = ldap_connect($this->host, $this->port); ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); $results = ldap_search($ldapConnection, $this->baseDn, $this->filter); $res = ldap_get_entries($ldapConnection, $results); } // FAKE LDAP else { $res = $this->fakeLDAPUsers; } return $res; } } catch (Exception $e) {} return false; } /* * @param unknown $userName (= login) * @param string $ldapConnection * @param string $filter * @param array $just_these * @return $info = ldap search result (user attributes) or FALSE */ public function getUserAttributes($userName, $ldapConnection='', $filter='', $just_these=[]) { try { if ($this->checkConfiguration()) { if ($this->LDAP_USED) { /* (EP) Fonction ldap_search ($link_identifier, $base_dn, $filter, array $attributes = null, $attrsonly = null, $sizelimit = null, $timelimit = null, $deref = null) Concernant le paramètre $attributes (ici, $just_these) : - An array of the required attributes, e.g. array("mail", "sn", "cn"). - Note that the "dn" is always returned irrespective of which attributes types are requested. Telle que notre connexion au LDAP est conçue, on s'attend à recevoir AU MINIMUM ces attributs dans la réponse de la fonction ldap_search(): - 'sn' - 'mail' - 'givenname' - 'uid' - 'userpassword' Pour récupérer tous ces attributs, il ne faut pas utiliser la variable $just_these, ou alors il faut qu'elle soit égale à un tableau vide ([]). (par exemple, si elle vaut "['cn']" ça signifie qu'on veut "seulement l'attribut 'cn'") Quand on n'utilise pas $just_these, la fonction ldap_search() retourne TOUS les attributs disponibles, donc c'est le comportement qu'on veut ici. */ $results = ldap_search($ldapConnection, $this->baseDn, $filter, $just_these) or die("Could not search to LDAP server response was: " . ldap_error($ldapConnection) ); $info = ldap_get_entries($ldapConnection, $results); //echo $info["count"]." entries returned\n"; return $info; } else return array( $this->getFakeLdapUser($userName) ); } } catch (Exception $e) { echo 'Exception LDAP : ', $e->getMessage(), "\n"; } return false; } public function getAuthenticationType() { return $this->authenticationType; } // EP added public function getFakeLdapUser($login) { foreach ($this->fakeLDAPUsers as $user) { if ($login == $user[$this->authenticationType][0]) return $user; } return FALSE; } /** * Return a list of Users with key = username & value = username */ public function getListUsers() { $u = $this->getAllLdapUsers(); $utilisateurs = []; if ($this->LDAP_USED) { for ($i = 0; $i < $u['count']; $i ++) { $utilisateurs[$u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]] = $u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]; } } else { for ($i = 0; $i < sizeof($u) - 1; $i ++) { $utilisateurs[$u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]] = $u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]; } } return $utilisateurs; } /** * Return a list of login ofUsers with key = username & value = login */ public function getListLoginUsers() { $u = $this->getAllLdapUsers(); $utilisateurs = []; if ($this->LDAP_USED) { for ($i = 0; $i < $u['count']; $i ++) { $utilisateurs[$u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]] = $u[$i][$this->authenticationType][0]; } } else { for ($i = 0; $i < sizeof($u) - 1; $i ++) { $utilisateurs[$u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]] = $u[$i][$this->authenticationType][0]; } } return $utilisateurs; } /** * Return a list of mail of Users with key = username & value = mail */ public function getListEmailUsers() { $u = $this->getAllLdapUsers(); $utilisateurs = []; if ($this->LDAP_USED) { for ($i = 0; $i < $u['count']; $i ++) { if (isset($u[$i]['mail'][0])) { $utilisateurs[$u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]] = $u[$i]['mail'][0]; } else { $utilisateurs[$u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]] = 'N/A'; } } } else { for ($i = 0; $i < sizeof($u) - 1; $i ++) { $utilisateurs[$u[$i]['sn'][0] . ' ' . $u[$i]['givenname'][0]] = $u[$i]['mail'][0]; } } return $utilisateurs; } /** * Return size of list users */ public function getNbUsers() { $u = $this->getAllLdapUsers(); if ($this->LDAP_USED) { $nbUsers = $u['count']; } else { $nbUsers = sizeof($u) - 1; } return $nbUsers; } // Utilisateur du ldap qui n'est pas dans la table utilisateurs // => il a donc le role "Utilisateur" PAR DEFAUT private function getTheFakeLdapUser() { return [ 'login' => '_fake_ldap_user_', 'pass' => '_fake_ldap_user_pass' ]; } /* * @param string $user_login * @param string $user_password * @return logged user LDAP attributes or FALSE if user not found in LDAP */ public function ldapAuthentication($user_login, $user_password) { try { if ($this->checkConfiguration()) { if ($this->LDAP_USED) { // We are using LDAP // No connexion allowed without password if (strlen(trim($user_password)) == 0) return FALSE; // Set LDAP parameters // - Liste des attributs à récupérer dans le ldap (vide = TOUS les attributs) $just_these = []; //$just_these = array("cn"); /* Examples : * * - ANONYMOUS LDAP (IRAP) : * $this->authenticationType = 'uid' * $this->baseDn = "ou=users,dc=irap,dc=omp,dc=eu" * * - AUTHENTIFIED LDAP connection (CRAL) : * $this->authenticationType = 'sAMAccountName' * $this->baseDn = "dc=univ-lyon1,dc=fr" * $binddn="CN=svc_ldap_cral,OU=users,OU=27,OU=sim,OU=univ-lyon1,DC=univ-lyon1,DC=fr"; * ($binddn = "CN=svc_ldap_cral,OU=users,OU=27,OU=sim,OU=univ-lyon1,".$this->baseDn;) * $filter = "(&(objectClass=person)(memberOf:1.2.840.113556.1.4.1941:=cn=ucbl.osu.cral,ou=groups,ou=27,ou=sim,ou=univ-lyon1,dc=univ-lyon1,dc=fr))"; */ // Construction du filtre avec le filtre de la base de données avec un & sur le login de l'utilisateur // Si aucun filtre n'est défini dans la base de données on aura juste (& ($this->authenticationType=$user_login)) // ex: "(&(objectClass=person)(memberOf:1.2.840.113556.1.4.1941:=cn=ucbl.osu.cral,ou=groups,ou=27,ou=sim,ou=univ-lyon1,dc=univ-lyon1,dc=fr)(sAMAccountName=$user_login))"; $filter = "(&".$this->filter."(".$this->authenticationType . '=' . $user_login."))"; //TODO: optimisation, refactoriser si comportement général //$binddn .= ','.$this->baseDn; // Connection $ldapConnection = ldap_connect($this->host, $this->port) or die("Could not connect to $this->host (port $this->port)"); if ($ldapConnection) { ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); // Binding optionnel if ($this->ldap_authentified) $ldapbind = ldap_bind($ldapConnection, $this->bindDn, $this->bindPass) or die("Could not bind to LDAP server.". ldap_error($ldapConnection) ); $search = $this->getUserAttributes($user_login, $ldapConnection, $filter, $just_these); if ($search === false) die("Could not get user attributes from LDAP server, response was: " . ldap_error($ldapConnection) ); return $search[0]; } } else { // We are not using LDAP (so, use FAKE LDAP instead) $user = $this->getFakeLdapUser($user_login); // debug($user); if ($user === false) return FALSE; // $this->authenticationType peut valoir "uid" ou "cn"... (par défaut "uid" pour le fake ldap, à confirmer...) // if ($user['uid'][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user; // if ($user[$this->authenticationType][0] == "_NouvelUtilisateur_username" && $user['userpassword'][0] == "_NouvelUtilisateur_password") return $user; if ($user[$this->authenticationType][0] == $this->getTheFakeLdapUser()['login'] && $user['userpassword'][0] == $this->getTheFakeLdapUser()['pass']) return $user; if ((new DefaultPasswordHasher())->check($user_password, $user['userpassword'][0])) return $user; // if ($user != false && $user['userpassword'][0] == $password) { } } } catch (Exception $e) { echo 'Exception LDAP : ', $e->getMessage(), "\n"; } return FALSE; } // end ldapAuthentication() } ?>