@"; const USER_SEARCH_DEFAULT_FILTER = "(&(objectClass=user)(objectCategory=person))"; //ldap_search retourne toujours le dn quelque soit le filtre utilisé const USER_SEARCH_DEFAULT_ATTRIBUTES = "sn,givenname,mail,telephonenumber,mobile,title,samaccountname,department,thumbnailphoto,jpegphoto,accountexpires,memberof,manager,userprincipalname,whencreated"; public $server,$port,$login,$password,$userRoot,$groupRoot,$domain,$datasource,$protocolVersion; /** * Se connecte a l'annuaire ldap en mode authentifié si login et mdp sont précisés, * en mode anonyme le cas échéant, possibilité d'activer le mode debug pour obtenir * des echo etapes par etapes. * @param login [=false] * @param mot de passe [=false] * @param mode debug [=false] (true or false) * @return true si la connexion a reussie, false dans le cas contraire */ public function connect($login=false,$password=false){ putenv('LDAPTLS_REQCERT=never'); if($this->server==null || $this->port==null || $this->userRoot==null) throw new Exception('Paramètres de connexion manquants',400); $this->datasource = ldap_connect($this->server,$this->port); if(!$this->datasource) throw new Exception('Connexion échouée', 400); ldap_set_option($this->datasource,LDAP_OPT_PROTOCOL_VERSION,$this->protocolVersion); ldap_set_option($this->datasource, LDAP_OPT_REFERRALS, 0); if(@ldap_bind($this->datasource,$login,$password) == false) throw new Exception('Identifiant ou mot de passe incorrect', 401); } /** * Récupere un samaccountname depuis un CN (conversion des liaisons ad en liasons erp) * @param CN complet de la personne recherchée **/ public function userFromCn($cn){ $entries = $this->search($this->userRoot,'(distinguishedname='.$cn.')'); return $entries; } /** * Récupere un CN depuis le login * @param Login **/ public function cnFromLogin($login,$attribute){ $entries= $this->search($this->userRoot,$this->authentification_filter($login,$attribute)); return (isset($entries[0])) ? $entries[0]['dn'] : false; } /** * Récupere les groupes ancetres du groupe ciblés recusrivement et les ajoute a la liste passée en argument * @param liste des groupes à alimenter * @param CN du groupe concerné * @return */ function recursiveGroups(&$groups,$groupCN){ $entries = $this->search($this->groupRoot,"(member=".$groupCN.")",'name'); if(count($entries)!=0 && $entries['count']!=0) { if(isset($entries[0])){ $groups[] = $entries[0]['name'][0]; $parentCN = $entries[0]['dn'][0]; $this->recursiveGroups($groups,$parentCN); } } } /** * Recherche des valeurs dans la base de données en fonction du filter * @param Racine contexte de la recherche * @param Filtre contenant les éléments a rechercher * @param Liste des attributs à récupérer * @return tableau contenant les objets correspondants a la recherche */ public function search($dn, $filter=null, $attributes=null){ if(is_null($filter)) $filter = self::USER_SEARCH_DEFAULT_FILTER; if(is_null($attributes)) $attributes = self::USER_SEARCH_DEFAULT_ATTRIBUTES; $attributes = explode(',',$attributes); $dns = (substr_count($dn, ';') > 0) ? explode(';', $dn) : array($dn); $dataSources = array(); //Passage en tableau pour recherches parallèles foreach($dns as $dn) $dataSources[] = $this->datasource; $searches = ldap_search($dataSources, $dns, $filter, $attributes); $infos = array(); foreach($searches as $search){ if($search === false) continue; $info = ldap_get_entries($this->datasource, $search); for($i=0; $i<$info['count']; $i++) $infos[] = $info[$i]; } return $infos; } public function set($dn,$entry,$value){ putenv('LDAPTLS_REQCERT=never'); if($value != ''){ $attributes[$entry][0] = $value; return ldap_modify($this->datasource,$dn,$attributes); }else{ //evite le crash si l'attribut n'existe pas lors d'une supression $attributes[$entry] ='0'; ldap_modify($this->datasource,$dn,$attributes); $attributes[$entry] = array(); return ldap_mod_del($this->datasource,$dn,$attributes); } } public function change_password($userDn, $newPassword){ if (!ldap_mod_replace($this->datasource, $userDn , self::encrypt_password($newPassword))) throw new Exception("Impossible de modifier le mot de passe : ".ldap_error($this->datasource)); } public static function encrypt_password($newPassword){ $newPassword = "\"" . $newPassword . "\""; $len = strlen( $newPassword ); $newPassw = ""; for ( $i = 0; $i < $len; $i++ ){ $newPassw .= "{".$newPassword[$i]."}\000"; } return array("unicodePwd" => $newPassw); } public function authentification_filter($login,$attribute){ $attributeName = self::authentification_attribute($attribute); switch($attributeName){ case 'samaccountname': $authentification = "(".$attributeName."=".$login.")"; break; case 'userprincipalname': $authentification = "(".$attributeName."=".$login.$this->domain.")"; break; default: $authentification = "(".$attributeName."=".$login.$this->domain.")"; break; } return '(&'.$authentification.'(objectClass=user)(objectCategory=person))'; } public static function authentification_attribute($attribute){ return $attribute == '' ? $GLOBALS['setting']['activedirectory']['activedirectory_authentification']['default'] : $attribute; } public function attribute_to_login($attribute){ return str_replace(mb_strtolower($this->domain), '', $attribute); } /** * Deconnexion du LDAP */ public function disconnect(){ if($this->datasource!=null){ @ldap_close($this->datasource); } } } ?>