[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / ecrire / auth / ldap.php
index 3ceec10..a251e41 100644 (file)
@@ -3,25 +3,34 @@
 /***************************************************************************\
  *  SPIP, Systeme de publication pour l'internet                           *
  *                                                                         *
- *  Copyright (c) 2001-2016                                                *
+ *  Copyright (c) 2001-2017                                                *
  *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
  *                                                                         *
  *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
  *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
 \***************************************************************************/
 
-if (!defined('_ECRIRE_INC_VERSION')) return;
+/**
+ * Gestion de l'authentification par LDAP
+ *
+ * @package SPIP\Core\Authentification\Ldap
+ **/
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+       return;
+}
 
 // Authentifie via LDAP et retourne la ligne SQL decrivant l'utilisateur si ok
 
 // Attributs LDAP correspondants a ceux de SPIP, notamment pour le login
 // ne pas ecraser une definition perso dans mes_options
-if (!isset($GLOBALS['ldap_attributes']) OR !is_array($GLOBALS['ldap_attributes'])){
+if (!isset($GLOBALS['ldap_attributes']) or !is_array($GLOBALS['ldap_attributes'])) {
        $GLOBALS['ldap_attributes'] = array(
-               'login' => array('sAMAccountName', 'uid', 'login', 'userid', 'cn','sn'),
+               'login' => array('sAMAccountName', 'uid', 'login', 'userid', 'cn', 'sn'),
                'nom' => "cn",
                'email' => "mail",
-               'bio' => "description");
+               'bio' => "description"
+       );
 }
 
 /**
@@ -45,96 +54,117 @@ if (!isset($GLOBALS['ldap_attributes']) OR !is_array($GLOBALS['ldap_attributes']
  * @param bool $phpauth
  * @return string
  */
-// http://doc.spip.org/@inc_auth_ldap_dist
-function auth_ldap_dist ($login, $pass, $serveur='', $phpauth=false) {
+function auth_ldap_dist($login, $pass, $serveur = '', $phpauth = false) {
 
        #spip_log("ldap $login " . ($pass ? "mdp fourni" : "mdp absent"));
 
        // Utilisateur connu ?
        // si http auth, inutile de reauthentifier: cela
-       // ne marchera pas avec auth http autre que basic.
-       $checkpass = isset($_SERVER["REMOTE_USER"])?false:true;
-       if (!($dn = auth_ldap_search($login, $pass, $checkpass, $serveur))) return array();
+       // ne marchera pas avec auth http autre que basic.
+       $checkpass = isset($_SERVER["REMOTE_USER"]) ? false : true;
+       if (!($dn = auth_ldap_search($login, $pass, $checkpass, $serveur))) {
+               return array();
+       }
        $credentials_ldap = array('ldap_dn' => $dn, 'ldap_password' => $pass);
 
        // Si l'utilisateur figure deja dans la base, y recuperer les infos
-       $r = sql_fetsel("*", "spip_auteurs", "login=" . sql_quote($login) . " AND source='ldap'",'','','','',$serveur);
+       $r = sql_fetsel("*", "spip_auteurs", "login=" . sql_quote($login) . " AND source='ldap'", '', '', '', '', $serveur);
 
-       if ($r) return array_merge($r, $credentials_ldap);
+       if ($r) {
+               return array_merge($r, $credentials_ldap);
+       }
 
        // sinon importer les infos depuis LDAP, 
 
        if ($GLOBALS['meta']["ldap_statut_import"]
-       AND $desc = auth_ldap_retrouver($dn, array(), $serveur)) {
-         // rajouter le statut indique  a l'install
+               and $desc = auth_ldap_retrouver($dn, array(), $serveur)
+       ) {
+               // rajouter le statut indique  a l'install
                $desc['statut'] = $GLOBALS['meta']["ldap_statut_import"];
                $desc['login'] = $login;
                $desc['source'] = 'ldap';
                $desc['pass'] = '';
 
-               $r = sql_insertq('spip_auteurs', $desc,'',$serveur);
-       }                               
+               $r = sql_insertq('spip_auteurs', $desc, '', $serveur);
+       }
 
-       if ($r)
+       if ($r) {
                return array_merge(
                        $credentials_ldap,
-                       sql_fetsel("*", "spip_auteurs", "id_auteur=".intval($r),'','','','',$serveur)
-                       );
+                       sql_fetsel("*", "spip_auteurs", "id_auteur=" . intval($r), '', '', '', '', $serveur)
+               );
+       }
 
        // sinon echec
        spip_log("Creation de l'auteur '$login' impossible");
+
        return array();
 }
 
 /**
- * Connexion a l'annuaire LDAP
- * Il faut passer par spip_connect() pour avoir les info
+ * Connexion à l'annuaire LDAP
+ *
+ * Il faut passer par `spip_connect()` pour avoir les info
  * donc potentiellement indiquer un serveur
  * meme si dans les fait cet argument est toujours vide
  *
  * @param string $serveur
- * @return string
+ * @return array
  */
-function auth_ldap_connect($serveur='') {
+function auth_ldap_connect($serveur = '') {
        include_spip('base/connect_sql');
        static $connexions_ldap = array();
-       if (isset($connexions_ldap[$serveur])) return $connexions_ldap[$serveur]; 
+       if (isset($connexions_ldap[$serveur])) {
+               return $connexions_ldap[$serveur];
+       }
        $connexion = spip_connect($serveur);
        if (!is_array($connexion['ldap'])) {
                if ($connexion['authentification']['ldap']) {
-                       $f =  _DIR_CONNECT . $connexion['authentification']['ldap'];
+                       $f = _DIR_CONNECT . $connexion['authentification']['ldap'];
                        unset($GLOBALS['ldap_link']);
-                       if (is_readable($f)) { include_once($f); };
-                       if (isset($GLOBALS['ldap_link']))
-                               $connexion['ldap'] = array('link' => $GLOBALS['ldap_link'],
-                                       'base' => $GLOBALS['ldap_base']);
-                       else spip_log("connection LDAP $serveur mal definie dans $f");
-                       if (isset($GLOBALS['ldap_champs']))
+                       if (is_readable($f)) {
+                               include_once($f);
+                       };
+                       if (isset($GLOBALS['ldap_link'])) {
+                               $connexion['ldap'] = array(
+                                       'link' => $GLOBALS['ldap_link'],
+                                       'base' => $GLOBALS['ldap_base']
+                               );
+                       } else {
+                               spip_log("connection LDAP $serveur mal definie dans $f");
+                       }
+                       if (isset($GLOBALS['ldap_champs'])) {
                                $connexion['ldap']['attributes'] = $GLOBALS['ldap_champs'];
-               } else spip_log("connection LDAP $serveur inconnue");
+                       }
+               } else {
+                       spip_log("connection LDAP $serveur inconnue");
+               }
        }
-       return $connexions_ldap[$serveur]=$connexion['ldap'];
+
+       return $connexions_ldap[$serveur] = $connexion['ldap'];
 }
 
 /**
- * Retrouver un login, et verifier son pass si demande par $checkpass
+ * Retrouver un login, et vérifier son pass si demandé par `$checkpass`
  *
  * @param string $login
  * @param string $pass
  * @param bool $checkpass
  * @param string $serveur
  * @return string
- *     le login trouve ou chaine vide si non trouve
+ *    Le login trouvé ou chaine vide si non trouvé
  */
-function auth_ldap_search($login, $pass, $checkpass=true, $serveur=''){
+function auth_ldap_search($login, $pass, $checkpass = true, $serveur = '') {
        // Securite anti-injection et contre un serveur LDAP laxiste
-       $login_search = preg_replace("/[^-@._\s\d\w]/", "", $login); 
-       if (!strlen($login_search) OR ($checkpass AND !strlen($pass)) )
+       $login_search = preg_replace("/[^-@._\s\d\w]/", "", $login);
+       if (!strlen($login_search) or ($checkpass and !strlen($pass))) {
                return '';
+       }
 
        // verifier la connexion
-       if (!$ldap = auth_ldap_connect($serveur))
+       if (!$ldap = auth_ldap_connect($serveur)) {
                return '';
+       }
 
        $ldap_link = isset($ldap['link']) ? $ldap['link'] : null;
        $ldap_base = isset($ldap['base']) ? $ldap['base'] : null;
@@ -143,152 +173,168 @@ function auth_ldap_search($login, $pass, $checkpass=true, $serveur=''){
        $logins = is_array($desc['login']) ? $desc['login'] : array($desc['login']);
 
        // Tenter une recherche pour essayer de retrouver le DN
-       foreach($logins as $att) {
+       foreach ($logins as $att) {
                $result = @ldap_search($ldap_link, $ldap_base, "$att=$login_search", array("dn"));
                $info = @ldap_get_entries($ldap_link, $result);
-                       // Ne pas accepter les resultats si plus d'une entree
-                       // (on veut un attribut unique)
+               // Ne pas accepter les resultats si plus d'une entree
+               // (on veut un attribut unique)
 
-               if (is_array($info) AND $info['count'] == 1) {
+               if (is_array($info) and $info['count'] == 1) {
                        $dn = $info[0]['dn'];
-                       if (!$checkpass) return $dn;
-                       if (@ldap_bind($ldap_link, $dn, $pass)) return $dn;
+                       if (!$checkpass) {
+                               return $dn;
+                       }
+                       if (@ldap_bind($ldap_link, $dn, $pass)) {
+                               return $dn;
+                       }
                }
        }
 
-       if ($checkpass AND !isset($dn)) {
+       if ($checkpass and !isset($dn)) {
                // Si echec, essayer de deviner le DN
-               foreach($logins as $att) {
+               foreach ($logins as $att) {
                        $dn = "$att=$login_search, $ldap_base";
-                       if (@ldap_bind($ldap_link, $dn, $pass))
+                       if (@ldap_bind($ldap_link, $dn, $pass)) {
                                return "$att=$login_search, $ldap_base";
+                       }
                }
        }
+
        return '';
 }
 
 /**
- * Retrouver un dn
+ * Retrouver un DN depuis LDAP
+ *
  * @param string $dn
  * @param array $desc
  * @param string $serveur
  * @return array
  */
-function auth_ldap_retrouver($dn, $desc=array(), $serveur='')
-{
+function auth_ldap_retrouver($dn, $desc = array(), $serveur = '') {
        // Lire les infos sur l'utilisateur a partir de son DN depuis LDAP
 
        if (!$ldap = spip_connect_ldap($serveur)) {
                spip_log("ldap $serveur injoignable");
+
                return array();
        }
 
        $ldap_link = $ldap['link'];
        if (!$desc) {
-               $desc = $ldap['attributes'] ? $ldap['attributes'] : $GLOBALS['ldap_attributes'] ;
+               $desc = $ldap['attributes'] ? $ldap['attributes'] : $GLOBALS['ldap_attributes'];
                unset($desc['login']);
        }
        $result = @ldap_read($ldap_link, $dn, "objectClass=*", array_values($desc));
 
-       if (!$result) return array();
+       if (!$result) {
+               return array();
+       }
 
        // Recuperer les donnees du premier (unique?) compte de l'auteur
        $val = @ldap_get_entries($ldap_link, $result);
-       if (!is_array($val) OR !is_array($val[0])) return array();
+       if (!is_array($val) or !is_array($val[0])) {
+               return array();
+       }
        $val = $val[0];
 
        // Convertir depuis UTF-8 (jeu de caracteres par defaut)
        include_spip('inc/charsets');
 
-       foreach ($desc as $k => $v)
+       foreach ($desc as $k => $v) {
                $desc[$k] = importer_charset($val[strtolower($v)][0], 'utf-8');
+       }
+
        return $desc;
 }
 
 
 /**
- * Retrouver le login de quelqu'un qui cherche a se loger
+ * Retrouver le login de quelqu'un qui cherche à se loger
  *
  * @param string $login
  * @param string $serveur
  * @return string
  */
-function auth_ldap_retrouver_login($login, $serveur='')
-{
+function auth_ldap_retrouver_login($login, $serveur = '') {
        return auth_ldap_search($login, '', false, $serveur) ? $login : '';
 }
 
 /**
- * Verification de la validite d'un mot de passe pour le mode d'auth concerne
- * c'est ici que se font eventuellement les verifications de longueur mini/maxi
+ * Vérification de la validité d'un mot de passe pour le mode d'auth concerné
+ *
+ * C'est ici que se font éventuellement les vérifications de longueur mini/maxi
  * ou de force.
  *
- * @param string $new_pass
  * @param string $login
- *  le login de l'auteur : permet de verifier que pass et login sont differents
- *  meme a la creation lorsque l'auteur n'existe pas encore
+ *   Le login de l'auteur : permet de vérifier que pass et login sont différents
+ *   même à la creation lorsque l'auteur n'existe pas encore
+ * @param string $new_pass
  * @param int $id_auteur
- *  si auteur existant deja
+ *   Si auteur existant déjà
  * @param string $serveur
  * @return string
- *  message d'erreur si login non valide, chaine vide sinon
+ *   Message d'erreur si login non valide, chaîne vide sinon
  */
-function auth_ldap_verifier_pass($login, $new_pass, $id_auteur=0, $serveur=''){
-    include_spip('auth/spip');
-    return auth_spip_verifier_pass($login, $new_pass, $id_auteur, $serveur);
+function auth_ldap_verifier_pass($login, $new_pass, $id_auteur = 0, $serveur = '') {
+       include_spip('auth/spip');
+
+       return auth_spip_verifier_pass($login, $new_pass, $id_auteur, $serveur);
 }
 
 /**
  * Informer du droit de modifier ou non le pass
  *
- * On ne peut pas détecter a l'avance si l'autorisation sera donnee, il
+ * On ne peut pas détecter à l'avance si l'autorisation sera donnée, il
  * faudra informer l'utilisateur a posteriori si la modif n'a pas pu se
  * faire.
+ *
  * @param string $serveur
  * @return bool
- *  pour un auteur LDAP, a priori toujours true, a conditiion que le serveur
- *  l'autorise: par exemple, pour OpenLDAP il faut avoir dans slapd.conf:
+ *   Pour un auteur LDAP, a priori toujours true, à conditiion que le serveur
+ *   l'autorise: par exemple, pour OpenLDAP il faut avoir dans slapd.conf:
+ *   ```
  *    access to attr=userPassword
  *       by self write
  *       ...
+ *   ```
  */
-function auth_ldap_autoriser_modifier_pass($serveur=''){
-    return true;
+function auth_ldap_autoriser_modifier_pass($serveur = '') {
+       return true;
 }
 
 /**
  * Fonction de modification du mot de passe
  *
- * On se bind au LDAP cette fois sous l'identite de l'utilisateur, car le
- * compte generique defini dans config/ldap.php n'a generalement pas (et
+ * On se bind au LDAP cette fois sous l'identité de l'utilisateur, car le
+ * compte générique defini dans config/ldap.php n'a généralement pas (et
  * ne devrait pas avoir) les droits suffisants pour faire la modification.
+ *
  * @param $login
  * @param $new_pass
  * @param $id_auteur
  * @param string $serveur
  * @return bool
- *  informe du succes ou de l'echec du changement du mot de passe
+ *    Informe du succès ou de l'echec du changement du mot de passe
  */
-function auth_ldap_modifier_pass($login, $new_pass, $id_auteur, $serveur=''){
-    if (is_null($new_pass) OR auth_ldap_verifier_pass($login, $new_pass,$id_auteur,$serveur)!='') {
-        return false;
-    }
-    if (!$ldap = auth_ldap_connect($serveur))
-       return '';
-    $link = $ldap['link'];
-    include_spip("inc/session");
-    $dn = session_get('ldap_dn');
-    if ('' == $dn) {
-        return false;
-    }
-    if (!ldap_bind($link, $dn, session_get('ldap_password'))) {
-       return false;
-    }
-    $encoded_pass = "{MD5}".base64_encode(pack("H*",md5($new_pass)));
-    $success = ldap_mod_replace($link, $dn, array('userPassword' => $encoded_pass));
-    return $success;
-}
-
-
+function auth_ldap_modifier_pass($login, $new_pass, $id_auteur, $serveur = '') {
+       if (is_null($new_pass) or auth_ldap_verifier_pass($login, $new_pass, $id_auteur, $serveur) != '') {
+               return false;
+       }
+       if (!$ldap = auth_ldap_connect($serveur)) {
+               return '';
+       }
+       $link = $ldap['link'];
+       include_spip("inc/session");
+       $dn = session_get('ldap_dn');
+       if ('' == $dn) {
+               return false;
+       }
+       if (!ldap_bind($link, $dn, session_get('ldap_password'))) {
+               return false;
+       }
+       $encoded_pass = "{MD5}" . base64_encode(pack("H*", md5($new_pass)));
+       $success = ldap_mod_replace($link, $dn, array('userPassword' => $encoded_pass));
 
-?>
+       return $success;
+}