ActiveDirectory.class.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. /*
  3. @nom: ldap
  4. @auteur: Valentin CARRUESCO (valentincarruesco@yahoo.fr)
  5. @date de création: 31/05/2013 02:47:27
  6. @description: Gestion des connexions aux annuaires ldap
  7. */
  8. class ActiveDirectory{
  9. const FORBIDDEN_CHARS = "/\\[]:;|=,+*?<>@";
  10. const USER_SEARCH_DEFAULT_FILTER = "(&(objectClass=user)(objectCategory=person))";
  11. //ldap_search retourne toujours le dn quelque soit le filtre utilisé
  12. const USER_SEARCH_DEFAULT_ATTRIBUTES = "sn,givenname,mail,telephonenumber,mobile,title,samaccountname,department,thumbnailphoto,jpegphoto,accountexpires,memberof,manager,userprincipalname,whencreated";
  13. public $server,$port,$login,$password,$userRoot,$groupRoot,$domain,$datasource,$protocolVersion;
  14. /**
  15. * Se connecte a l'annuaire ldap en mode authentifié si login et mdp sont précisés,
  16. * en mode anonyme le cas échéant, possibilité d'activer le mode debug pour obtenir
  17. * des echo etapes par etapes.
  18. * @param <String> login [=false]
  19. * @param <String> mot de passe [=false]
  20. * @param <String> mode debug [=false] (true or false)
  21. * @return <Boolean> true si la connexion a reussie, false dans le cas contraire
  22. */
  23. public function connect($login=false,$password=false){
  24. putenv('LDAPTLS_REQCERT=never');
  25. if($this->server==null || $this->port==null || $this->userRoot==null) throw new Exception('Paramètres de connexion manquants',400);
  26. $this->datasource = ldap_connect($this->server,$this->port);
  27. if(!$this->datasource) throw new Exception('Connexion échouée', 400);
  28. ldap_set_option($this->datasource,LDAP_OPT_PROTOCOL_VERSION,$this->protocolVersion);
  29. ldap_set_option($this->datasource, LDAP_OPT_REFERRALS, 0);
  30. if(@ldap_bind($this->datasource,$login,$password) == false) throw new Exception('Identifiant ou mot de passe incorrect', 401);
  31. }
  32. /**
  33. * Récupere un samaccountname depuis un CN (conversion des liaisons ad en liasons erp)
  34. * @param <Strong> CN complet de la personne recherchée
  35. **/
  36. public function userFromCn($cn){
  37. $entries = $this->search($this->userRoot,'(distinguishedname='.$cn.')');
  38. return $entries;
  39. }
  40. /**
  41. * Récupere un CN depuis le login
  42. * @param <String> Login
  43. **/
  44. public function cnFromLogin($login,$attribute){
  45. $entries= $this->search($this->userRoot,$this->authentification_filter($login,$attribute));
  46. return (isset($entries[0])) ? $entries[0]['dn'] : false;
  47. }
  48. /**
  49. * Récupere les groupes ancetres du groupe ciblés recusrivement et les ajoute a la liste passée en argument
  50. * @param <String> liste des groupes à alimenter
  51. * @param <String> CN du groupe concerné
  52. * @return <void>
  53. */
  54. function recursiveGroups(&$groups,$groupCN){
  55. $entries = $this->search($this->groupRoot,"(member=".$groupCN.")",'name');
  56. if(count($entries)!=0 && $entries['count']!=0) {
  57. if(isset($entries[0])){
  58. $groups[] = $entries[0]['name'][0];
  59. $parentCN = $entries[0]['dn'][0];
  60. $this->recursiveGroups($groups,$parentCN);
  61. }
  62. }
  63. }
  64. /**
  65. * Recherche des valeurs dans la base de données en fonction du filter
  66. * @param <String> Racine contexte de la recherche
  67. * @param <String> Filtre contenant les éléments a rechercher
  68. * @param <Array> Liste des attributs à récupérer
  69. * @return <Array> tableau contenant les objets correspondants a la recherche
  70. */
  71. public function search($dn, $filter=null, $attributes=null){
  72. if(is_null($filter)) $filter = self::USER_SEARCH_DEFAULT_FILTER;
  73. if(is_null($attributes)) $attributes = self::USER_SEARCH_DEFAULT_ATTRIBUTES;
  74. $attributes = explode(',',$attributes);
  75. $dns = (substr_count($dn, ';') > 0) ? explode(';', $dn) : array($dn);
  76. $dataSources = array();
  77. //Passage en tableau pour recherches parallèles
  78. foreach($dns as $dn)
  79. $dataSources[] = $this->datasource;
  80. $searches = ldap_search($dataSources, $dns, $filter, $attributes);
  81. $infos = array();
  82. foreach($searches as $search){
  83. if($search === false) continue;
  84. $info = ldap_get_entries($this->datasource, $search);
  85. for($i=0; $i<$info['count']; $i++)
  86. $infos[] = $info[$i];
  87. }
  88. return $infos;
  89. }
  90. public function set($dn,$entry,$value){
  91. putenv('LDAPTLS_REQCERT=never');
  92. if($value != ''){
  93. $attributes[$entry][0] = $value;
  94. return ldap_modify($this->datasource,$dn,$attributes);
  95. }else{
  96. //evite le crash si l'attribut n'existe pas lors d'une supression
  97. $attributes[$entry] ='0';
  98. ldap_modify($this->datasource,$dn,$attributes);
  99. $attributes[$entry] = array();
  100. return ldap_mod_del($this->datasource,$dn,$attributes);
  101. }
  102. }
  103. public function change_password($userDn, $newPassword){
  104. 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));
  105. }
  106. public static function encrypt_password($newPassword){
  107. $newPassword = "\"" . $newPassword . "\"";
  108. $len = strlen( $newPassword );
  109. $newPassw = "";
  110. for ( $i = 0; $i < $len; $i++ ){
  111. $newPassw .= "{".$newPassword[$i]."}\000";
  112. }
  113. return array("unicodePwd" => $newPassw);
  114. }
  115. public function authentification_filter($login,$attribute){
  116. $attributeName = self::authentification_attribute($attribute);
  117. switch($attributeName){
  118. case 'samaccountname':
  119. $authentification = "(".$attributeName."=".$login.")";
  120. break;
  121. case 'userprincipalname':
  122. $authentification = "(".$attributeName."=".$login.$this->domain.")";
  123. break;
  124. default:
  125. $authentification = "(".$attributeName."=".$login.$this->domain.")";
  126. break;
  127. }
  128. return '(&'.$authentification.'(objectClass=user)(objectCategory=person))';
  129. }
  130. public static function authentification_attribute($attribute){
  131. return $attribute == '' ? $GLOBALS['setting']['activedirectory']['activedirectory_authentification']['default'] : $attribute;
  132. }
  133. public function attribute_to_login($attribute){
  134. return str_replace(mb_strtolower($this->domain), '', $attribute);
  135. }
  136. /**
  137. * Deconnexion du LDAP
  138. */
  139. public function disconnect(){
  140. if($this->datasource!=null){
  141. @ldap_close($this->datasource);
  142. }
  143. }
  144. }
  145. ?>