X-Git-Url: http://git.cyclocoop.org/?p=velocampus%2Fweb%2Fwww.git;a=blobdiff_plain;f=www%2Fecrire%2Fauth%2Fldap.php;fp=www%2Fecrire%2Fauth%2Fldap.php;h=bc59859f22d94aceb60d16a4ab08c8e26798da0c;hp=0000000000000000000000000000000000000000;hb=80b4d3e85f78d402ed2e73f8f5d1bf4c19962eed;hpb=aaf970bf4cdaf76689ecc10609048e18d073820c diff --git a/www/ecrire/auth/ldap.php b/www/ecrire/auth/ldap.php new file mode 100644 index 0000000..bc59859 --- /dev/null +++ b/www/ecrire/auth/ldap.php @@ -0,0 +1,184 @@ + array('sAMAccountName', 'uid', 'login', 'userid', 'cn','sn'), + 'nom' => "cn", + 'email' => "mail", + 'bio' => "description"); + +// http://doc.spip.org/@inc_auth_ldap_dist +function auth_ldap_dist ($login, $pass, $serveur='') { + + #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(); + + // 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); + + if ($r) return $r; + + // 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 + $desc['statut'] = $GLOBALS['meta']["ldap_statut_import"]; + $desc['login'] = $login; + $desc['source'] = 'ldap'; + $desc['pass'] = ''; + + $r = sql_insertq('spip_auteurs', $desc,'',$serveur); + } + + if ($r) + return 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 + * donc potentiellement indiquer un serveur + * meme si dans les fait cet argument est toujours vide + * + * @param string $serveur + * @return string + */ +function auth_ldap_connect($serveur='') { + include_spip('base/connect_sql'); + static $connexions_ldap = array(); + 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']; + 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'])) + $connexion['ldap']['attributes'] = $GLOBALS['ldap_champs']; + } else spip_log("connection LDAP $serveur inconnue"); + } + return $connexions_ldap[$serveur]=$connexion['ldap']; +} + +/** + * Retrouver un login, et verifier son pass si demande par $checkpass + * + * @param string $login + * @param sring $pass + * @param bool $checkpass + * @return string + * le login trouve ou chaine vide si non trouve + */ +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)) ) + return ''; + + // verifier la connexion + if (!$ldap = auth_ldap_connect($serveur)) + return ''; + + $ldap_link = $ldap['link']; + $ldap_base = $ldap['base']; + $desc = $ldap['attributes'] ? $ldap['attributes'] : $GLOBALS['ldap_attributes'] ; + + $logins = is_array($desc['login']) ? $desc['login'] : array($desc['login']); + + // Tenter une recherche pour essayer de retrouver le DN + 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) + + 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 AND !isset($dn)) { + // Si echec, essayer de deviner le DN + foreach($logins as $att) { + $dn = "$att=$login_search, $ldap_base"; + if (@ldap_bind($ldap_link, $dn, $pass)) + return "$att=$login_search, $ldap_base"; + } + } + return ''; +} + +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'] ; + unset($desc['login']); + } + $result = @ldap_read($ldap_link, $dn, "objectClass=*", array_values($desc)); + + 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(); + $val = $val[0]; + + // Convertir depuis UTF-8 (jeu de caracteres par defaut) + include_spip('inc/charsets'); + + 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 + * + * @param string $login + * @return string + */ +function auth_ldap_retrouver_login($login, $serveur='') +{ + return auth_ldap_search($login, '', false, $serveur) ? $login : ''; +} + +?>