useLdap(); } public function useLdap() { $this->checkConfiguration(); return $this->USE_LDAP; } 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->USE_LDAP = $config->use_ldap ? TRUE : FALSE; if (! $this->USE_LDAP) { $this->authenticationType = $config->authentificationType_ldap; if (empty($this->fakeLDAPUsers)) $this->fakeLDAPUsers = $this->buildFakeLdapUsers(); return true; } // debug($this->fakeLDAPUsers); $ldapConfig = $config->toArray(); if (! empty($config->host_ldap) && ! empty($config->port_ldap) && ! empty($config->baseDn_ldap) && ! empty($config->authentificationType_ldap) && ! empty($config->filter_ldap)) { $this->host = $config->host_ldap; $this->port = $config->port_ldap; $this->baseDn = $config->baseDn_ldap; $this->filter = $config->filter_ldap; $this->authenticationType = $config->authentificationType_ldap; /*MCM*/ $NEW_CONF=FALSE; if ($NEW_CONF) { $this->anonymous_ldap = $config->anonymous_ldap; $this->bindDn = $config->bindDn_ldap; $this->bindPass = $config->bindPass_ldap; } else { $this->anonymous_ldap = TRUE; $this->bindDn = NULL; $this->bindPass = NULL; } /* fin MCM*/ return true; } throw new Exception('The ldap configuration is not valid :
'); } public function getAllLdapUsers() { try { if ($this->checkConfiguration()) { // REAL LDAP if ($this->USE_LDAP) { $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; } // $userName = login //public function getUserAttributes($userName, $ldapConnection='', $LDAP_ANONYMOUS=true, $filter='', $just_these=[]) public function getUserAttributes($userName, $ldapConnection='', $filter='', $just_these=[]) { try { if ($this->checkConfiguration()) { if ($this->USE_LDAP) { /* Code inutile car redondant: $ldapConnection = ldap_connect($this->host, $this->port); ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3); */ /* (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) {} 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->USE_LDAP) { 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->USE_LDAP) { 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->USE_LDAP) { 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->USE_LDAP) { $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' ]; } public function ldapAuthentication($user_login, $user_password) { try { if ($this->checkConfiguration()) { // We are using LDAP if ($this->USE_LDAP) { // CRAL must set this to FALSE //$LDAP_ANONYMOUS = TRUE; // 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 = []; /* // - Anonymous connection (IRAP, IAS, LATMOS) //if ($LDAP_ANONYMOUS) { if ($this->anonymous_ldap) { ///$auth_dn = ''; //= $this->authDn; // $this->authenticationType = 'uid' // $this->baseDn = "ou=users,dc=irap,dc=omp,dc=eu" //TODO: à virer, ca n'est pas nécessaire en anonymous $binddn = $this->authenticationType . '=' . $user_login; // ex: uid=epallier $ldappass = $user_password; //$filter = '('.$binddn.')'; // ex: "(uid=epallier)" ////$filter = $this->filter . '('.$binddn.')'; // ex: "(uid=epallier)" //TODO: refactoriser si comportement général ///$binddn .= ','.$this->baseDn; } // - Authentified connection (CRAL) else { //$dn = $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,".$dn; ///<*> EP version $auth_dn = "CN=svc_ldap_cral,OU=users,OU=27,OU=sim,OU=univ-lyon1"; //= $this->authDn; $binddn = $auth_dn; $ldappass = "lemotdepasse"; $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))"; //<*>/ ///$auth_dn = $this->baseDn; // dc=univ-lyon1,dc=fr // $this->authenticationType = 'sAMAccountName' // $this->baseDn = "dc=univ-lyon1,dc=fr" //$anonymous = $this->anonymous; //if ($anonymous == '0') { $binddn = $this->bindDn; // CN=svc_ldap_cral,OU=users,OU=27,OU=sim,OU=univ-lyon1,DC=univ-lyon1,DC=fr $ldappass = $this->bindPass; //} //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)) ////$filter = "(&".$this->filter."(".$this->authenticationType . '=' . $user_login."))"; //$just_these = array("cn"); ///<*> NEW version $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)(sAMAccountName=$user_login))"; $dn = "dc=univ-lyon1,dc=fr"; $binddn="CN=svc_ldap_cral,OU=users,OU=27,OU=sim,OU=univ-lyon1,DC=univ-lyon1,DC=fr"; //<*>/ } */ $filter = "(&".$this->filter."(".$this->authenticationType . '=' . $user_login."))"; //TODO: optimisation /////////$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 /*MCM*/ // bind optionnel //if ($anonymous == '0') if (! $this->anonymous_ldap) //$ldapbind = ldap_bind($ldapConnection, $binddn, $ldappass) or die("Could not bind to LDAP server.". ldap_error($ldapConnection) ); $ldapbind = ldap_bind($ldapConnection, $this->bindDn, $this->bindPass) or die("Could not bind to LDAP server.". ldap_error($ldapConnection) ); // EP: bind obligatoire //if ($ldapbind) { //$search = $this->getUserAttributes($user_login, $ldapConnection, $LDAP_ANONYMOUS, $filter, $just_these); //$search = $this->getUserAttributes($user_login, $ldapConnection, $this->anonymous_ldap, $filter, $just_these); $search = $this->getUserAttributes($user_login, $ldapConnection, $filter, $just_these); /* fin MCM*/ if ($search === false) die("Could not get user attributes from LDAP server, response was: " . ldap_error($ldapConnection) ); return $search[0]; /* * } else { * return false; */ //} } // We are not using LDAP (so, use FAKE LDAP instead) } else { $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) {} return FALSE; } } ?>