[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / auth / ldap.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 // Authentifie via LDAP et retourne la ligne SQL decrivant l'utilisateur si ok
16
17 // Attributs LDAP correspondants a ceux de SPIP, notamment pour le login
18 $GLOBALS['ldap_attributes'] = array(
19 'login' => array('sAMAccountName', 'uid', 'login', 'userid', 'cn','sn'),
20 'nom' => "cn",
21 'email' => "mail",
22 'bio' => "description");
23
24 // http://doc.spip.org/@inc_auth_ldap_dist
25 function auth_ldap_dist ($login, $pass, $serveur='') {
26
27 #spip_log("ldap $login " . ($pass ? "mdp fourni" : "mdp absent"));
28
29 // Utilisateur connu ?
30 // si http auth, inutile de reauthentifier: cela
31 // ne marchera pas avec auth http autre que basic.
32 $checkpass = isset($_SERVER["REMOTE_USER"])?false:true;
33 if (!($dn = auth_ldap_search($login, $pass, $checkpass, $serveur))) return array();
34
35 // Si l'utilisateur figure deja dans la base, y recuperer les infos
36 $r = sql_fetsel("*", "spip_auteurs", "login=" . sql_quote($login) . " AND source='ldap'",'','','','',$serveur);
37
38 if ($r) return $r;
39
40 // sinon importer les infos depuis LDAP,
41
42 if ($GLOBALS['meta']["ldap_statut_import"]
43 AND $desc = auth_ldap_retrouver($dn, array(), $serveur)) {
44 // rajouter le statut indique a l'install
45 $desc['statut'] = $GLOBALS['meta']["ldap_statut_import"];
46 $desc['login'] = $login;
47 $desc['source'] = 'ldap';
48 $desc['pass'] = '';
49
50 $r = sql_insertq('spip_auteurs', $desc,'',$serveur);
51 }
52
53 if ($r)
54 return sql_fetsel("*", "spip_auteurs", "id_auteur=".intval($r),'','','','',$serveur);
55
56 // sinon echec
57 spip_log("Creation de l'auteur '$login' impossible");
58 return array();
59 }
60
61 /**
62 * Connexion a l'annuaire LDAP
63 * Il faut passer par spip_connect() pour avoir les info
64 * donc potentiellement indiquer un serveur
65 * meme si dans les fait cet argument est toujours vide
66 *
67 * @param string $serveur
68 * @return string
69 */
70 function auth_ldap_connect($serveur='') {
71 include_spip('base/connect_sql');
72 static $connexions_ldap = array();
73 if (isset($connexions_ldap[$serveur])) return $connexions_ldap[$serveur];
74 $connexion = spip_connect($serveur);
75 if (!is_array($connexion['ldap'])) {
76 if ($connexion['authentification']['ldap']) {
77 $f = _DIR_CONNECT . $connexion['authentification']['ldap'];
78 unset($GLOBALS['ldap_link']);
79 if (is_readable($f)) include_once($f);
80 if (isset($GLOBALS['ldap_link']))
81 $connexion['ldap'] = array('link' => $GLOBALS['ldap_link'],
82 'base' => $GLOBALS['ldap_base']);
83 else spip_log("connection LDAP $serveur mal definie dans $f");
84 if (isset($GLOBALS['ldap_champs']))
85 $connexion['ldap']['attributes'] = $GLOBALS['ldap_champs'];
86 } else spip_log("connection LDAP $serveur inconnue");
87 }
88 return $connexions_ldap[$serveur]=$connexion['ldap'];
89 }
90
91 /**
92 * Retrouver un login, et verifier son pass si demande par $checkpass
93 *
94 * @param string $login
95 * @param sring $pass
96 * @param bool $checkpass
97 * @return string
98 * le login trouve ou chaine vide si non trouve
99 */
100 function auth_ldap_search($login, $pass, $checkpass=true, $serveur=''){
101 // Securite anti-injection et contre un serveur LDAP laxiste
102 $login_search = preg_replace("/[^-@._\s\d\w]/", "", $login);
103 if (!strlen($login_search) OR ($checkpass AND !strlen($pass)) )
104 return '';
105
106 // verifier la connexion
107 if (!$ldap = auth_ldap_connect($serveur))
108 return '';
109
110 $ldap_link = $ldap['link'];
111 $ldap_base = $ldap['base'];
112 $desc = $ldap['attributes'] ? $ldap['attributes'] : $GLOBALS['ldap_attributes'] ;
113
114 $logins = is_array($desc['login']) ? $desc['login'] : array($desc['login']);
115
116 // Tenter une recherche pour essayer de retrouver le DN
117 foreach($logins as $att) {
118 $result = @ldap_search($ldap_link, $ldap_base, "$att=$login_search", array("dn"));
119 $info = @ldap_get_entries($ldap_link, $result);
120 // Ne pas accepter les resultats si plus d'une entree
121 // (on veut un attribut unique)
122
123 if (is_array($info) AND $info['count'] == 1) {
124 $dn = $info[0]['dn'];
125 if (!$checkpass) return $dn;
126 if (@ldap_bind($ldap_link, $dn, $pass)) return $dn;
127 }
128 }
129
130 if ($checkpass AND !isset($dn)) {
131 // Si echec, essayer de deviner le DN
132 foreach($logins as $att) {
133 $dn = "$att=$login_search, $ldap_base";
134 if (@ldap_bind($ldap_link, $dn, $pass))
135 return "$att=$login_search, $ldap_base";
136 }
137 }
138 return '';
139 }
140
141 function auth_ldap_retrouver($dn, $desc=array(), $serveur='')
142 {
143 // Lire les infos sur l'utilisateur a partir de son DN depuis LDAP
144
145 if (!$ldap = spip_connect_ldap($serveur)) {
146 spip_log("ldap $serveur injoignable");
147 return array();
148 }
149
150 $ldap_link = $ldap['link'];
151 if (!$desc) {
152 $desc = $ldap['attributes'] ? $ldap['attributes'] : $GLOBALS['ldap_attributes'] ;
153 unset($desc['login']);
154 }
155 $result = @ldap_read($ldap_link, $dn, "objectClass=*", array_values($desc));
156
157 if (!$result) return array();
158
159 // Recuperer les donnees du premier (unique?) compte de l'auteur
160 $val = @ldap_get_entries($ldap_link, $result);
161 if (!is_array($val) OR !is_array($val[0])) return array();
162 $val = $val[0];
163
164 // Convertir depuis UTF-8 (jeu de caracteres par defaut)
165 include_spip('inc/charsets');
166
167 foreach ($desc as $k => $v)
168 $desc[$k] = importer_charset($val[strtolower($v)][0], 'utf-8');
169 return $desc;
170 }
171
172
173 /**
174 * Retrouver le login de quelqu'un qui cherche a se loger
175 *
176 * @param string $login
177 * @return string
178 */
179 function auth_ldap_retrouver_login($login, $serveur='')
180 {
181 return auth_ldap_search($login, '', false, $serveur) ? $login : '';
182 }
183
184 ?>