DEBUG_MODE) { //Configure::write('debug', true); debug($arg); if ($stop) exit(); } } public function __construct() { parent::__construct(); } // EP public function useFakeLdap() { return ! $this->useLdap(); } public function useLdap() { $this->checkConfiguration(); return $this->LDAP_USED; } // LDAP format ==> DB format // @param: array $user (LDAP-like formatted) // @return: object(App\Model\Entity\User) private function _getLDAPuserFormattedAsDB($user_from_LDAP) { /* (INPUT) Voici le format d'un user du LDAP : [ 'sn' => [ (int) 0 => 'Pallier' ], 'mail' => [ (int) 0 => 'Etienne.Pallier@irap.omp.eu' ], 'givenname' => [ (int) 0 => 'Etienne' ], 'uid' => [ (int) 0 => 'epallier' ], 'userpassword' => [ (int) 0 => '' ] ] */ /* (OUTPUT) Voici le format d'un user de la table users (BD) ( object(App\Model\Entity\User) ) : // - Champs de la table : 'id' => (int) 2, 'nom' => 'Pallier Etienne', 'username' => 'epallier', 'email' => 'Etienne.Pallier@irap.omp.eu', 'role' => 'Super Administrateur', 'groupes_metier_id' => (int) 3, 'password' => 'pass crypté...', 'groupe_thematique_id' => null, 'sur_categorie_id' => null, // - Champs ajoutés par CakePhp3: '[new]' => false, '[accessible]' => [ '*' => true, 'id' => false ], '[dirty]' => [], '[original]' => [], '[virtual]' => [], '[hasErrors]' => false, '[errors]' => [], '[invalid]' => [], '[repository]' => 'Users' */ $usersTable = TableRegistry::getTableLocator()->get('Users'); $user = $usersTable->newEntity(); $user->nom = $user_from_LDAP['sn'].' '.$user_from_LDAP['givenname']; //$user->username = $user_from_LDAP['uid']; $user->username = $user_from_LDAP[$this->authenticationType]; $user->email = $user_from_LDAP['mail']; // Par defaut, role = UTILISATEUR $user->role = 'Utilisateur'; // C'est la version "cryptée" qui doit etre stockée $user->password = $user_from_LDAP['userpassword']; return $user; } private function _getDBusersFormattedAsLDAP($usersfromDB) { foreach ($usersfromDB as $userfromDB) $userfromDB = $this->_getDBuserFormattedAsLDAP($userfromDB); return $usersfromDB; } // DB format ==> LDAP format private function _getDBuserFormattedAsLDAP($user) { $names = explode(" ", $user['nom']); $givenName = isset($names[1]) ? $names[1] : " "; return [ // Nom 'sn' => [ $names[0] ], // Email 'mail' => [ $user['email'] ], // Pnom 'givenname' => [ $givenName ], // Login ("uid" for IRAP, "samaccountname" for CRAL) $this->authenticationType => [ $user['username'] ], // Pass 'userpassword' => [ $user['password'] ] ]; } private function buildFakeLdapUsers() { return $this->buildFakeLdapUsersFromDB(); } private function buildFakeLdapUsersFromDB() { $users = TableRegistry::getTableLocator()->get('Users')->find(); $ldapUsers = []; foreach ($users as $user) { //debug($user); /* Voici le format d'un user de la table users (BD) // - Champs de la table : 'id' => (int) 2, 'nom' => 'Pallier Etienne', 'username' => 'epallier', 'email' => 'Etienne.Pallier@irap.omp.eu', 'role' => 'Super Administrateur', 'groupes_metier_id' => (int) 3, 'password' => 'pass crypté...', 'groupe_thematique_id' => null, 'sur_categorie_id' => null, // - Champs ajoutés par CakePhp3: '[new]' => false, '[accessible]' => [ '*' => true, 'id' => false ], '[dirty]' => [], '[original]' => [], '[virtual]' => [], '[hasErrors]' => false, '[errors]' => [], '[invalid]' => [], '[repository]' => 'Users' */ $ldapUsers[] = $this->_getDBuserFormattedAsLDAP($user); /* $names = explode(" ", $user['nom']); $givenName = isset($names[1]) ? $names[1] : " "; $ldapUsers[] = [ // Nom 'sn' => [ $names[0] ], // Email 'mail' => [ $user['email'] ], // Pnom 'givenname' => [ $givenName ], // Login ("uid" for IRAP, "samaccountname" for CRAL) $this->authenticationType => [ $user['username'] ], // Pass '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() { $this->CONF = TableRegistry::getTableLocator()->get('Configurations') ->find() ->where(['id =' => 1]) ->first(); $config = $this->CONF; $this->usersTable = TableRegistry::getTableLocator()->get('Users'); $this->DEBUG_MODE = $config->mode_debug; $this->LDAP_USED = $config->ldap_used; 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 :
'); } // REAL LDAP only /** * @return array or boolean : all users from DB (CACHE of the LDAP) or FALSE (if table emtpy or expired data) */ private function fetchAllUsersFromDB() { // On remet à jour tous les 7 jours $PEREMPTION_NB_DAYS = 7; // Doit aussi retourner FALSE si la ligne FAKE de la table users // (celle qui contient le user_name "FAKE_USER") // a une date "updated" périmée (now - updated > $PEREMPTION_NB_DAYS) // (update automatique de tous les users, chaque semaine, pour rester synced avec le LDAP) // By default, no user in CACHE return FALSE; } // REAL LDAP only // Sauvegarde de tous les users du LDAP en BD (avec un rythme de mise à jour hebdo) // Seulement les champs: nom, pnom, login, pass, email, create, updated, profile private function saveAllUsersInDB($users_fetched) { // START TRANSACTION // 1) Update (ou création) de la ligne FAKE (contient le user_name "FAKE_USER") => avec une date "updated" // 2) Update (ou création) de chaque user contenu dans $users_fetched // Attention à ne pas perdre l'attribut "profile", surtout pour les users privilégiés!!! (les autres ont un profile = "Utilisateur") // END TRANSACTION (COMMIT) // SAVE s'est bien passé return TRUE; } // @return ldap users from DB users table private function _getAllLdapUsersFromDB() { $this->_updateLdapCacheIfNeeded(); return $this->usersTable->find(); } /** * @return $users_fetched or FALSE */ // REAL or FAKE LDAP public function getAllLdapUsers() { if (! $this->checkConfiguration()) return FALSE; // LDAP optimized (cached) if ($this->CONF->ldap_cached) { $users_fetched = $this->_getAllLdapUsersFromDB(); return ($this->_getDBusersFormattedAsLDAP($users_fetched)); } // LDAP direct (no optimization) else { try { //if ($this->checkConfiguration()) { // REAL LDAP if ($this->LDAP_USED) { // 1) Search users in CACHE (DB) $users_fetched = $this->fetchAllUsersFromDB(); // 2) Not found in CACHE, so search users in LDAP if ($users_fetched === FALSE) { $users_fetched = $this->searchLdap($this->filter, []); // CACHE the new user in DB for next time if ($users_fetched !== FALSE) $this->saveAllUsersInDB($users_fetched); } } // FAKE LDAP else { $users_fetched = $this->fakeLDAPUsers; } // Noter que $user_fetched peut etre egal a FALSE (si rien trouvé) return $users_fetched; //} } catch (Exception $e) {} } // Pb, rien trouvé 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 = email */ public function getUsersLoginAndEmail() { $usersWithNameAndEmail = []; // Get all users (with ALL their attributes) $u = $this->getAllLdapUsers(); // Sort users //sort($u); //debug($u); $this->mydebugmsg("ldap users 0 and 1:"); $this->mydebugmsg($u[0]); $this->mydebugmsg($u[1]); // (EP) Refactorisation pour éviter code redondant du temps des stagiaires... $nb_users = $this->LDAP_USED ? $u['count'] : sizeof($u)-1; for ($i = 0; $i < $nb_users; $i ++) // $utilisateurs["Pallier Etienne"] = ["email"] ////$usersWithNameAndEmail[ $u[$i]['sn'][0].' '.$u[$i]['givenname'][0] ] = $u[$i]['mail'][0]; $usersWithNameAndEmail[ $u[$i]['sn'][0].' '.$u[$i]['givenname'][0] ] = array( //"login" => $u[$i]['uid'][0] // (IRAP) //"login" => $u[$i]['samaccountname'][0] // CRAL "login" => $u[$i][$this->authenticationType][0], "email" => $u[$i]['mail'][0] ); // Sort users (without modifying the keys, don't use sort() but asort() !!!!!!!!!!!!!) ksort($usersWithNameAndEmail); //debug($usersWithNameAndEmail); return $usersWithNameAndEmail; } /** * Return a list of Users with key = username & value = username */ public function getListUsers() { $utilisateurs = []; // Get all users (with ALL their attributes) $u = $this->getAllLdapUsers(); // Sort users //sort($u); //debug($u); // (EP) Refactorisation pour éviter code redondant ci-dessous, c'était pourtant pas compliqué, poil dans la main... $nb_users = $this->LDAP_USED ? $u['count'] : sizeof($u)-1; // $utilisateurs["Pallier Etienne"] = "Pallier Etienne" for ($i = 0; $i < $nb_users; $i ++) $utilisateurs[ $u[$i]['sn'][0].' '.$u[$i]['givenname'][0] ] = $u[$i]['sn'][0].' '.$u[$i]['givenname'][0]; //debug($utilisateurs); // Sort users (without modifying the keys, don't use sort() but asort() !!!!!!!!!!!!!) ksort($utilisateurs); //debug($utilisateurs); 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' ]; } // @return user from DB whith login = $userLogin (or NULL) private function _getUser($userLogin) { return $this->usersTable->find() //$ldapUser = TableRegistry::getTableLocator()->get('Users')->find() ->where([ 'username' => $userLogin ]) ->first(); } /** * @return boolean * - FALSE if cache is up to date * - TRUE if cache is expired (outdated or 1st special row is missing) */ private function _ldapCacheIsExpired() { // ldap_cache_last_update is not set OR is expired => return state as expired return ( is_null($this->CONF->ldap_cache_last_update) || ($this->CONF->ldap_cache_last_update + $this->ldap_cache_validity_duration < now()) ); } // REAL LDAP only // Save all LDAP users into "users" db table private function _updateLdapCacheIfNeeded() { // return if cache is not expired if (! $this->_ldapCacheIsExpired()) return; // Get all users from LDAP $ldapUsersFromLDAP = $this->getAllLdapUsers(); // Get all users from DB $ldapUsersFromDB = $this->_getAllLdapUsersFromDB(); // Add new users (only) and update existing users foreach ($ldapUsersFromLDAP as $ldapUserFromLDAP) { $ldapUserFromDB = $this->_getUser($ldapUserFromLDAP[$this->authenticationType]); // New user => add it to DB if (is_null($ldapUserFromDB)) $this->usersTable->save($this->_getLDAPuserFormattedAsDB($ldapUserFromLDAP)); // Existing user => update it (only email and password) else { $ldapUserFromDB->email = $ldapUserFromLDAP['mail']; $ldapUserFromDB->password = $ldapUserFromLDAP['userpassword']; $this->usersTable->save($ldapUserFromDB); } } // Delete old users (which are no more in LDAP) foreach ($ldapUsersFromDB as $ldapUserFromDB) { if (! in_array($ldapUserFromDB->username, $ldapUsersFromLDAP)) $ldapUserFromDB->delete(); } // Update LDAP cache last update time $this->CONF->ldap_cache_last_update = now(); $this->CONF->save(); } // REAL LDAP only // from DB ==> to LDAP // @return: ldap user if ok (else FALSE) //private function checkAndFetchLDAPUserFromDB($user_login, $user_password) { private function _getLdapUserFromDB($user_login) { // Doit aussi return false si ce user_login est "périmé" (sa date "created" est > 2 mois par exemple), // ce qui obligera à relire ses données dans le LDAP et donc se mettre à jour //if (! $this->LDAP_CACHED) return FALSE; // If LDAP cache (in users table) is expired, update it (save again ldap into DB) //if ($this->_ldapCacheIsExpired()) $this->_updateLdapCache(); $this->_updateLdapCacheIfNeeded(); // 1) Search user in DB $ldapUser = $this->_getUser($user_login); /* $ldapUser = TableRegistry::getTableLocator()->get('Users')->find() ->where([ 'username' => $user_login ]) ->first(); */ // User not found => fail if (is_null($ldapUser)) return FALSE; /* // 2) Check password // Bad password => fail if ( ! (new DefaultPasswordHasher())->check($user_password,$ldapUser['userpassword'][0]) ) return FALSE; // User found and password ok => return it */ // User found ok => return it formatted as ldap return $this->_getDBuserFormattedAsLDAP($ldapUser); } // TODO: implement // REAL LDAP only // from LDAP ==> to DB // SAVE new user in DB private function saveNewUserInDB($user_from_LDAP) { if (! $this->CONF->ldap_cached) return TRUE; // 1) Format LDAP user as for DB $user_from_LDAP_formatted_as_DB = $this->_getLDAPuserFormattedAsDB($user_from_LDAP); // 2) Save DB formatted user into DB $usersTable = TableRegistry::getTableLocator()->get('Users'); if ( ! $usersTable->save($user_from_LDAP_formatted_as_DB, [ //'checkRules' => false, 'checkExisting' => TRUE ])) return FALSE; // user has been saved (cached) ok return TRUE; } // REAL LDAP only // SEARCH en 4 étapes private function searchLdap($filter, $just_these, $user_login=NULL, $user_password=NULL) { // (1) CONNEXION $ldapConnection = ldap_connect($this->host, $this->port) or die("Could not connect to $this->host (port $this->port)"); if ($ldapConnection) { // (2) SET OPTIONS ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); // (3) BINDING OPTIONNEL (true by default if not done) $ldapbind = TRUE; // - Authentified LDAP // (EP) ATTENTION: Ne pas faire die() ici car ça stopperait net la mauvaise connexion d'un utilisateur, avec ce message d'erreur ! // Il vaut mieux retourner FALSE et afficher un joli message de refus sur la page d'accueil if ($this->ldap_authentified) //$ldapbind = @ldap_bind($ldapConnection, $this->bindDn, $this->bindPass); $ldapbind = @ldap_bind($ldapConnection, $this->bindDn, $this->bindPass); //or die("Could not bind to LDAP server.". ldap_error($ldapConnection) ); // - Anonymous LDAP // (EP) En cas de LDAP anonyme, binding uniquement si login session (pour vérifier le mot de passe de l'utilisateur). // Car sans cette ligne, on passe avec n'importe quel password !!! // NB: pas de die() ici, voir remarque juste au-dessus else if ($user_login && $user_password) //$ldapbind = @ldap_bind($ldapConnection, $this->authenticationType . '=' . $user_login . ',' . $this->baseDn, $user_password); $ldapbind = @ldap_bind($ldapConnection, $this->authenticationType . '=' . $user_login . ',' . $this->baseDn, $user_password); // or die("Could not bind to LDAP server: ". ldap_error($ldapConnection) ); // (4) SEARCH if ($ldapbind) { // $filter = "(&".$this->filter."(".$this->authenticationType . '=' . $user_login."))"; // ex: (&(compteinfo=Oui)(uid=epallier)) $results = ldap_search($ldapConnection, $this->baseDn, $filter, $just_these) or die("Could not search to LDAP server response was: " . ldap_error($ldapConnection) ); $search = ldap_get_entries($ldapConnection, $results); //echo $results["count"]." entries returned\n"; if ($search === FALSE) die("Could not get user attributes from LDAP server, response was: " . ldap_error($ldapConnection) ); //return $search[0]; return $search; } } // Il y a eu un pb, utilisateur non reconnu return FALSE; } // searchLdap() public function ldapAuthentication($user_login, $user_password) { try { if ($this->checkConfiguration()) { // REAL LDAP if ($this->LDAP_USED) { // No connexion allowed without password if (strlen(trim($user_password)) == 0) return FALSE; // TODO: optimisation possible // 1) Search user in CACHE (DB) //$user_fetched = $this->checkAndFetchLDAPUserFromDB($user_login, $user_password); // 2) If not CACHED, search user in LDAP $user_fetched = FALSE; if ($user_fetched === FALSE) { //$user_fetched = $this->checkAndFetchUserFromLdap($user_login, $user_password); $just_these = []; // TODO: vérifier si cette ligne est bien utile ou pas... (avant on faisait ça) //if (! $this->ldap_authentified) $just_these = array("cn"); // 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; $user_fetched = $this->searchLdap($filter, $just_these, $user_login, $user_password); // CACHE the new user in DB for next time if ($user_fetched != FALSE) { //$this->saveNewUserInDB($user_fetched[0]); return $user_fetched[0]; } } else { debug("user found in DB"); debug($user_fetched); } //return $user_fetched; // Noter que $user_fetched peut etre egal a FALSE (si pas trouvé) } // FAKE LDAP else { //debug($this->USE_LDAP); //debug($this->baseDn); $user = $this->getFakeLdapUser($user_login); // debug($user); //if ($user === false) return FALSE; if ($user !== 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"; } // Il y a eu un problème, l'utilisateur n'est pas reconnu return FALSE; } // end ldapAuthentication() // MAIN ENTRY POINT of this class /* * @param string $user_login * @param string $user_password * @return logged user LDAP attributes (FALSE if user not found in LDAP) */ public function ldapAuthenticationNEW($user_login, $user_password) { // Bad configuration => FAIL if (! $this->checkConfiguration()) return FALSE; // LDAP optimized if ($this->CONF->ldap_cached) { $ldap_user = $this->_getLdapUserFromDB($user_login); // login FAIL because user not found if ($ldap_user === FALSE) return FALSE; // check password and return user if ok or FALSE if fail return ( (new DefaultPasswordHasher())->check($user_password,$ldap_user['userpassword'][0]) ); } // normal LDAP (no optimization) else { try { //if ($this->checkConfiguration()) { // REAL LDAP if ($this->LDAP_USED) { // No connexion allowed without password if (strlen(trim($user_password)) == 0) return FALSE; /* // TODO: optimisation possible // 1) Search user in CACHE (DB) $user_fetched = $this->checkAndFetchLDAPUserFromDB($user_login, $user_password); $this->mydebugmsg("(1) user found in DB is:"); $this->mydebugmsg($user_fetched); //TODO: A VIRER !!! //$user_fetched = FALSE; // 2) If not CACHED, search user in LDAP if ($user_fetched === FALSE) { */ //$user_fetched = $this->checkAndFetchUserFromLdap($user_login, $user_password); $just_these = []; // TODO: vérifier si cette ligne est bien utile ou pas... (avant on faisait ça) //if (! $this->ldap_authentified) $just_these = array("cn"); // 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; $user_fetched = $this->searchLdap($filter, $just_these, $user_login, $user_password); //$this->mydebugmsg("(1) user found in LDAP is:"); //$this->mydebugmsg($user_fetched); //$this->mydebugmsg($user_fetched[0]); /* Voici un exemple de ce qui est dans $user_fetched[0] (structure LDAP IRAP) : // ce qui est retourné par le fake ldap (imitation bien faite non ?) [ 'sn' => [ (int) 0 => 'Pallier' ], 'mail' => [ (int) 0 => 'Etienne.Pallier@irap.omp.eu' ], 'givenname' => [ (int) 0 => 'Etienne' ], 'uid' => [ (int) 0 => 'epallier' ], 'userpassword' => [ (int) 0 => '' ] ] // VRAI LDAP, juste un extrait utile : [ 'sn' => [ 'count' => (int) 1, (int) 0 => 'Pallier' ], (int) 14 => 'sn', 'givenname' => [ 'count' => (int) 1, (int) 0 => 'Etienne' ], ] // VRAI LDAP, au complet : [ 'cn' => [ 'count' => (int) 1, (int) 0 => 'Etienne Pallier' ], (int) 0 => 'cn', 'homedirectory' => [ 'count' => (int) 1, (int) 0 => '/home/epallier' ], (int) 1 => 'homedirectory', 'uidnumber' => [ 'count' => (int) 1, (int) 0 => '20172' ], (int) 2 => 'uidnumber', 'objectclass' => [ 'count' => (int) 9, (int) 0 => 'top', (int) 1 => 'person', (int) 2 => 'organizationalPerson', (int) 3 => 'inetOrgPerson', (int) 4 => 'posixAccount', (int) 5 => 'shadowAccount', (int) 6 => 'irap', (int) 7 => 'hostObject', (int) 8 => 'sambaSamAccount' ], (int) 3 => 'objectclass', 'sambasid' => [ 'count' => (int) 1, (int) 0 => 'S-1-5-21-3149873848-2002230563-1027543705-41344' ], (int) 4 => 'sambasid', 'mail' => [ 'count' => (int) 1, (int) 0 => 'Etienne.Pallier@irap.omp.eu' ], (int) 5 => 'mail', 'olddn' => [ 'count' => (int) 1, (int) 0 => 'uid=pallier,ou=users,ou=laboratoire,dc=cesr,dc=fr' ], (int) 6 => 'olddn', 'userpassword' => [ 'count' => (int) 1, (int) 0 => '{SASL}epallier@IRAP.OMP.EU' ], (int) 7 => 'userpassword', 'sambantpassword' => [ 'count' => (int) 1, (int) 0 => 'ED9A0ECE0C6C7560A8DDF6A23B2C7C36' ], (int) 8 => 'sambantpassword', 'sambapwdlastset' => [ 'count' => (int) 1, (int) 0 => '1317291687' ], (int) 9 => 'sambapwdlastset', 'loginshell' => [ 'count' => (int) 1, (int) 0 => '/bin/bash' ], (int) 10 => 'loginshell', 'shadowexpire' => [ 'count' => (int) 1, (int) 0 => '-1' ], (int) 11 => 'shadowexpire', 'host' => [ 'count' => (int) 3, (int) 0 => 'gitlab1.irap.omp.eu', (int) 1 => 'gw.irap.omp.eu', (int) 2 => 'version2.irap.omp.eu' ], (int) 12 => 'host', 'uid' => [ 'count' => (int) 1, (int) 0 => 'epallier' ], (int) 13 => 'uid', 'sn' => [ 'count' => (int) 1, (int) 0 => 'Pallier' ], (int) 14 => 'sn', 'givenname' => [ 'count' => (int) 1, (int) 0 => 'Etienne' ], (int) 15 => 'givenname', 'gecos' => [ 'count' => (int) 1, (int) 0 => 'Etienne.Pallier' ], (int) 16 => 'gecos', 'gidnumber' => [ 'count' => (int) 1, (int) 0 => '2001' ], (int) 17 => 'gidnumber', 'tagmail' => [ 'count' => (int) 1, (int) 0 => 'Oui' ], (int) 18 => 'tagmail', 'compteinfo' => [ 'count' => (int) 1, (int) 0 => 'Oui' ], (int) 19 => 'compteinfo', 'arrivaldate' => [ 'count' => (int) 1, (int) 0 => '01/01/1933' ], (int) 20 => 'arrivaldate', 'birthday' => [ 'count' => (int) 1, (int) 0 => '07/08/1968' ], (int) 21 => 'birthday', 'telephonenumber' => [ 'count' => (int) 1, (int) 0 => '0561556648' ], (int) 22 => 'telephonenumber', 'roomnumber' => [ 'count' => (int) 1, (int) 0 => 'J039' ], (int) 23 => 'roomnumber', 'mailperso' => [ 'count' => (int) 1, (int) 0 => 'N/A' ], (int) 24 => 'mailperso', 'title' => [ 'count' => (int) 1, (int) 0 => 'M' ], (int) 25 => 'title', 'site' => [ 'count' => (int) 1, (int) 0 => 'Roche' ], (int) 26 => 'site', 'manager' => [ 'count' => (int) 1, (int) 0 => 'uid=mgiard,ou=users,dc=irap,dc=omp,dc=eu' ], (int) 27 => 'manager', 'statut1' => [ 'count' => (int) 1, (int) 0 => 'ITA' ], (int) 28 => 'statut1', 'o' => [ 'count' => (int) 1, (int) 0 => 'UPS' ], (int) 29 => 'o', 'gt1' => [ 'count' => (int) 1, (int) 0 => 'PEPS' ], (int) 30 => 'gt1', 'gt2' => [ 'count' => (int) 1, (int) 0 => 'GAHEC' ], (int) 31 => 'gt2', 'statut2' => [ 'count' => (int) 1, (int) 0 => 'GT2I' ], (int) 32 => 'statut2', 'affichageannuaire' => [ 'count' => (int) 1, (int) 0 => 'Oui' ], (int) 33 => 'affichageannuaire', 'count' => (int) 34, 'dn' => 'uid=epallier,ou=users,dc=irap,dc=omp,dc=eu' ] */ // CACHE the new user in DB for next time if ($user_fetched !== FALSE) { //$this->saveNewUserInDB($user_fetched[0]); return $user_fetched[0]; } /* } // user from LDAP // user from LDAP-cache (DB) else { $this->mydebugmsg("(2) user found in DB is:"); $this->mydebugmsg($user_fetched); } */ //return $user_fetched; // Noter que $user_fetched peut etre egal a FALSE (si pas trouvé) } // FAKE LDAP used else { //debug($this->USE_LDAP); //debug($this->baseDn); $user_fetched = $this->getFakeLdapUser($user_login); $this->mydebugmsg("(1) user found in FAKE LDAP is:"); $this->mydebugmsg($user_fetched); /* Voici un exemple de ce qui est dans $user_fetched (fake ldap) : [ 'sn' => [ (int) 0 => 'Pallier' ], 'mail' => [ (int) 0 => 'Etienne.Pallier@irap.omp.eu' ], 'givenname' => [ (int) 0 => 'Etienne' ], 'uid' => [ (int) 0 => 'epallier' ], 'userpassword' => [ (int) 0 => '' ] ] */ // debug($user); //if ($user === false) return FALSE; if ($user_fetched !== 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_fetched[$this->authenticationType][0] == $this->getTheFakeLdapUser()['login'] && $user_fetched['userpassword'][0] == $this->getTheFakeLdapUser()['pass']) return $user_fetched; if ( (new DefaultPasswordHasher())->check($user_password,$user_fetched['userpassword'][0]) ) return $user_fetched; // if ($user != false && $user['userpassword'][0] == $password) { } } //} // check config } catch (Exception $e) { //echo 'Exception LDAP : ', $e->getMessage(), "\n"; } } // if LDAP_CACHED // Il y a eu un problème, l'utilisateur n'est pas reconnu return FALSE; } // end ldapAuthentication() } ?>