$s)); include_spip('inc/modifier'); revision_auteur($id_auteur, array('bio'=>'')); include_spip('inc/session'); session_set('statut',$s); return $s; } // Fonction d'authentification. Retourne: // - URL de connexion si on ne sait rien (pas de cookie, pas Auth_user); // - un tableau si visiteur sans droit (tableau = sa ligne SQL) // - code numerique d'erreur SQL // - une chaine vide si autorisation a penetrer dans l'espace prive. // http://doc.spip.org/@inc_auth_dist function inc_auth_dist() { global $connect_login ; $row = auth_mode(); if ($row) return auth_init_droits($row); if (!$connect_login) return auth_a_loger(); // Cas ou l'auteur a ete identifie mais on n'a pas d'info sur lui // C'est soit parce que la base est inutilisable, // soit parce que la table des auteurs a changee (restauration etc) // Pas la peine d'insister. // Renvoyer le nom fautif et une URL de remise a zero if (spip_connect()) return array('login' => $connect_login, 'site' => generer_url_public('', "action=logout&logout=prive")); $n = intval(sql_errno()); spip_log("Erreur base de donnees $n " . sql_error()); return $n ? $n : 1; } // fonction appliquee par ecrire/index sur le resultat de la precedente // en cas de refus de connexion. // Retourne un message a afficher ou redirige illico. function auth_echec($raison) { include_spip('inc/minipres'); include_spip('inc/headers'); // pas authentifie. Pourquoi ? if (is_string($raison)) { // redirection vers une page d'authentification // on ne revient pas de cette fonction // sauf si pb de header $raison = redirige_formulaire($raison); } elseif (is_int($raison)) { // erreur SQL a afficher $raison = minipres(_T('info_travaux_titre'), _T('titre_probleme_technique'). "

".sql_errno()." ".sql_error()."

"); } elseif (@$raison['statut']) { // un simple visiteur n'a pas acces a l'espace prive spip_log("connexion refusee a " . @$raison['id_auteur']); $raison = minipres(_T('avis_erreur_connexion'),_T('avis_erreur_visiteur')); } else { // auteur en fin de droits ... $h = $raison['site']; $raison = minipres(_T('avis_erreur_connexion'), "

" . _T('texte_inc_auth_1', array('auth_login' => $raison['login'])) . " " . _T('texte_inc_auth_2') . "" . _T('texte_inc_auth_3')); } return $raison; } // Retourne la description d'un authentifie par cookie ou http_auth // Et affecte la globale $connect_login function auth_mode() { global $auth_can_disconnect, $ignore_auth_http, $ignore_remote_user; global $connect_login ; // // Initialiser variables (eviter hacks par URL) // $connect_login = ''; $id_auteur = NULL; $auth_can_disconnect = false; // // Recuperer les donnees d'identification // // Session valide en cours ? if (isset($_COOKIE['spip_session'])) { $session = charger_fonction('session', 'inc'); if ($id_auteur = $session() OR $id_auteur===0 // reprise sur restauration ) { $auth_can_disconnect = true; $connect_login = $GLOBALS['visiteur_session']['login']; } else unset($_COOKIE['spip_session']); } // Essayer auth http si significatif // (ignorer les login d'intranet independants de spip) if (!$ignore_auth_http) { if ( (isset($_SERVER['PHP_AUTH_USER']) AND isset($_SERVER['PHP_AUTH_PW']) AND $r = lire_php_auth($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) OR // Si auth http differtente de basic, PHP_AUTH_PW // est indisponible mais tentons quand meme pour // autocreation via LDAP (isset($_SERVER['REMOTE_USER']) AND $r = lire_php_auth($_SERVER['PHP_AUTH_USER'] = $_SERVER['REMOTE_USER'], '')) ) { if (!$id_auteur) { $_SERVER['PHP_AUTH_PW'] = ''; $auth_can_disconnect = true; $GLOBALS['visiteur_session'] = $r; $connect_login = $GLOBALS['visiteur_session']['login']; } else { // cas de la session en plus de PHP_AUTH /* if ($id_auteur != $r['id_auteur']){ spip_log("vol de session $id_auteur" . join(', ', $r)); unset($_COOKIE['spip_session']); $id_auteur = ''; } */ } } // Authentification .htaccess old style, car .htaccess semble // souvent definir *aussi* PHP_AUTH_USER et PHP_AUTH_PW else if (isset($_SERVER['REMOTE_USER'])) $connect_login = $_SERVER['REMOTE_USER']; } $where = (is_numeric($id_auteur) /*AND $id_auteur>0*/ // reprise lors des restaurations ) ? "id_auteur=$id_auteur" : (!strlen($connect_login) ? '' : "login=" . sql_quote($connect_login)); if (!$where) return ''; // Trouver les autres infos dans la table auteurs. // le champ 'quand' est utilise par l'agenda return sql_fetsel("*, en_ligne AS quand", "spip_auteurs", "$where AND statut!='5poubelle'"); } // // Init des globales pour tout l'espace prive si visiteur connu // Le tableau global visiteur_session contient toutes les infos pertinentes et // a jour (tandis que $visiteur_session peut avoir des valeurs un peu datees // s'il est pris dans le fichier de session) // Les plus utiles sont aussi dans les variables simples ci-dessus // si la globale est vide ce n'est pas un tableau, on la force pour empecher un warning function auth_init_droits($row) { global $connect_statut, $connect_toutes_rubriques, $connect_id_rubrique, $connect_login, $connect_id_auteur; $connect_id_auteur = $row['id_auteur']; $connect_login = $row['login']; $connect_statut = acces_statut($connect_id_auteur, $row['statut'], $row['bio']); $GLOBALS['visiteur_session'] = array_merge((array)$GLOBALS['visiteur_session'], $row); $r = @unserialize($row['prefs']); $GLOBALS['visiteur_session']['prefs'] = (@isset($r['couleur'])) ? $r : array('couleur' =>1, 'display'=>0); // au cas ou : ne pas memoriser les champs sensibles unset($GLOBALS['visiteur_session']['pass']); unset($GLOBALS['visiteur_session']['htpass']); unset($GLOBALS['visiteur_session']['alea_actuel']); unset($GLOBALS['visiteur_session']['alea_futur']); // rajouter les sessions meme en mode auth_http // pour permettre les connexions multiples et identifier les visiteurs if (!isset($_COOKIE['spip_session'])) { $session = charger_fonction('session', 'inc'); if ($spip_session = $session($row)) { include_spip('inc/cookie'); spip_setcookie( 'spip_session', $_COOKIE['spip_session'] = $spip_session, time() + 3600 * 24 * 14 ); } } // Etablir les droits selon le codage attendu // dans ecrire/index.php ecrire/prive.php // Pas autorise a acceder a ecrire ? renvoyer le tableau // A noter : le premier appel a autoriser() a le bon gout // d'initialiser $GLOBALS['visiteur_session']['restreint'], // qui ne figure pas dans le fichier de session include_spip('inc/autoriser'); if (!autoriser('ecrire')) return $row; // autoriser('ecrire') ne laisse passer que les Admin et les Redac auth_trace($row); // Administrateurs if ($connect_statut == '0minirezo') { if (is_array($GLOBALS['visiteur_session']['restreint'])) $connect_id_rubrique = $GLOBALS['visiteur_session']['restreint']; $connect_toutes_rubriques = !$connect_id_rubrique; } // Pour les redacteurs, inc_version a fait l'initialisation minimale return ''; // i.e. pas de pb. } function auth_a_loger() { $redirect = generer_url_public('login', "url=" . rawurlencode(self('&',true)), '&'); // un echec au "bonjour" (login initial) quand le statut est // inconnu signale sans doute un probleme de cookies if (isset($_GET['bonjour'])) $redirect = parametre_url($redirect, 'var_erreur', (!isset($GLOBALS['visiteur_session']['statut']) ? 'cookie' : 'statut' ), '&' ); return $redirect; } // http://doc.spip.org/@auth_trace function auth_trace($row, $date=null) { // Indiquer la connexion. A la minute pres ca suffit. if (!is_numeric($connect_quand = $row['quand'])) $connect_quand = strtotime($connect_quand); if (is_null($date)) $date = date('Y-m-d H:i:s'); if (abs(strtotime($date) - $connect_quand) >= 60) { sql_updateq("spip_auteurs", array("en_ligne" => $date), "id_auteur=" .$row['id_auteur']); } } /** ---------------------------------------------------------------------------- * API Authentification, gestion des identites centralisees */ /** * Fonction aiguillage, privee * @param string $fonction * @param array $args * @param mixed $defaut * @return mixed */ function auth_administrer($fonction,$args,$defaut=false){ $auth_methode = array_shift($args); $auth_methode = $auth_methode ? $auth_methode : 'spip'; // valeur par defaut au cas ou if ($auth = charger_fonction($auth_methode,'auth',true) AND function_exists($f="auth_{$auth_methode}_$fonction") ) return call_user_func_array($f, $args); else return $defaut; } /** * Pipeline pour inserer du contenu dans le formulaire de login * * @param array $flux * @return array */ function auth_formulaire_login($flux){ foreach ($GLOBALS['liste_des_authentifications'] as $methode) $flux = auth_administrer('formulaire_login',array($methode,$flux),$flux); return $flux; } /** * Retrouver le login interne lie a une info login saisie * la saisie peut correspondre a un login delegue * qui sera alors converti en login interne apres verification * * @param string $login * @param string $serveur * @return string/bool */ function auth_retrouver_login($login, $serveur=''){ if (!spip_connect($serveur)) { include_spip('inc/minipres'); echo minipres(_T('info_travaux_titre'), _T('titre_probleme_technique')); exit; } foreach ($GLOBALS['liste_des_authentifications'] as $methode) { if ($auteur = auth_administrer('retrouver_login',array($methode, $login, $serveur))) { return $auteur; } } return false; } /** * informer sur un login * Ce dernier transmet le tableau ci-dessous a la fonction JS informer_auteur * Il est invoque par la fonction JS actualise_auteur via la globale JS * page_auteur=#URL_PAGE{informer_auteur} dans le squelette login * N'y aurait-il pas plus simple ? * * @param string $login * @param string $serveur * @return array */ function auth_informer_login($login, $serveur=''){ if (!$login OR !$login = auth_retrouver_login($login, $serveur) OR !$row = sql_fetsel('*','spip_auteurs','login='.sql_quote($login),'','','','',$serveur) ) return array(); $prefs = unserialize($row['prefs']); $infos = array( 'id_auteur'=>$row['id_auteur'], 'login'=>$row['login'], 'cnx' => ($prefs['cnx'] == 'perma') ? '1' : '0', 'logo' => recuperer_fond('formulaires/inc-logo_auteur', $row), ); // desactiver le hash md5 si pas auteur spip ? if ($row['source']!=='spip'){ $row['alea_actuel']= ''; $row['alea_futur']= ''; } verifier_visiteur(); return auth_administrer('informer_login',array($row['source'],$infos, $row, $serveur),$infos); } /** * Essayer les differentes sources d'authenfication dans l'ordre specifie. * S'en souvenir dans visiteur_session['auth'] * * @param string $login * @param string $password * @param string $serveur * @return mixed */ function auth_identifier_login($login, $password, $serveur=''){ $erreur = ""; foreach ($GLOBALS['liste_des_authentifications'] as $methode) { if ($auth = charger_fonction($methode, 'auth',true)){ $auteur = $auth($login, $password, $serveur); if (is_array($auteur) AND count($auteur)) { spip_log("connexion de $login par methode $methode"); $auteur['auth'] = $methode; return $auteur; } elseif (is_string($auteur)) $erreur .= "$auteur "; } } return $erreur; } /** * Fournir une url de retour apres login par un SSO * pour finir l'authentification * * @param string $auth_methode * @param string $login * @param string $serveur * @return string */ function auth_url_retour_login($auth_methode, $login, $redirect='', $serveur=''){ $securiser_action = charger_fonction('securiser_action','inc'); return $securiser_action('auth', "$auth_methode/$login", $redirect, true); } function auth_terminer_identifier_login($auth_methode, $login, $serveur=''){ $args = func_get_args(); $auteur = auth_administrer('terminer_identifier_login',$args); return $auteur; } /** * Loger un auteur suite a son identification * * @param array $auteur */ function auth_loger($auteur, $refuse_cookie_admin=false){ if (!is_array($auteur) OR !count($auteur)) return false; $session = charger_fonction('session', 'inc'); $session($auteur); $p = ($auteur['prefs']) ? unserialize($auteur['prefs']) : array(); $p['cnx'] = ($auteur['cookie'] == 'oui') ? 'perma' : ''; $p = array('prefs' => serialize($p)); sql_updateq('spip_auteurs', $p, "id_auteur=" . $auteur['id_auteur']); if ($auteur['statut'] == 'nouveau') { $session(); // charger la session car on va la modifier $auteur['statut'] = acces_statut($auteur['id_auteur'], $auteur['statut'], $auteur['bio']); } // Si on est admin, poser le cookie de correspondance include_spip('inc/cookie'); if (!$refuse_cookie_admin AND $auteur['statut'] == '0minirezo') { spip_setcookie('spip_admin', '@'.$auteur['login'], time() + 7 * 24 * 3600); } // sinon le supprimer ... else { spip_setcookie('spip_admin', '',1); } // bloquer ici le visiteur qui tente d'abuser de ses droits verifier_visiteur(); return true; } function auth_deloger(){ $logout = charger_fonction('logout','action'); $logout(); } /** * Tester la possibilite de modifier le login d'authentification * pour la methode donnee * * @param string $auth_methode * @param string $serveur * @return bool */ function auth_autoriser_modifier_login($auth_methode, $serveur=''){ $args = func_get_args(); return auth_administrer('autoriser_modifier_login',$args); } /** * Verifier la validite d'un nouveau login pour modification * pour la methode donnee * * @param string $auth_methode * @param string $new_login * @param int $id_auteur * @param string $serveur * @return string * message d'erreur ou chaine vide si pas d'erreur */ function auth_verifier_login($auth_methode, $new_login, $id_auteur=0, $serveur=''){ $args = func_get_args(); return auth_administrer('verifier_login',$args,''); } /** * Modifier le login d'un auteur pour la methode donnee * * @param string $auth_methode * @param string $new_login * @param int $id_auteur * @param string $serveur * @return bool */ function auth_modifier_login($auth_methode, $new_login, $id_auteur, $serveur=''){ $args = func_get_args(); return auth_administrer('modifier_login',$args); } /** * Tester la possibilite de modifier le pass * pour la methode donnee * * @param string $auth_methode * @param string $serveur * @return bool * succes ou echec */ function auth_autoriser_modifier_pass($auth_methode, $serveur=''){ $args = func_get_args(); return auth_administrer('autoriser_modifier_pass',$args); } /** * Verifier la validite d'un pass propose pour modification * pour la methode donnee * * @param string $auth_methode * @param string $login * @param string $new_pass * @param int $id_auteur * @param string $serveur * @return string * message d'erreur ou chaine vide si pas d'erreur */ function auth_verifier_pass($auth_methode, $login, $new_pass, $id_auteur=0, $serveur=''){ $args = func_get_args(); return auth_administrer('verifier_pass',$args,''); } /** * Modifier le mot de passe d'un auteur * pour la methode donnee * * @param string $auth_methode * @param string $login * @param string $new_pass * @param int $id_auteur * @param string $serveur * @return bool * succes ou echec */ function auth_modifier_pass($auth_methode, $login, $new_pass, $id_auteur, $serveur=''){ $args = func_get_args(); return auth_administrer('modifier_pass',$args); } /** * Synchroniser un compte sur une base distante pour la methode * donnee lorsque des modifications sont faites dans la base auteur * * @param string $auth_methode * ici true permet de forcer la synchronisation de tous les acces pour toutes les methodes * @param int $id_auteur * @param array $champs * @param array $options * @param string $serveur * @return void */ function auth_synchroniser_distant($auth_methode=true, $id_auteur=0, $champs=array(), $options = array(), $serveur=''){ $args = func_get_args(); if ($auth_methode===true OR (isset($options['all']) AND $options['all']==true)){ $options['all'] = true; // ajouter une option all=>true pour chaque auth $args = array(true, $id_auteur, $champs, $options, $serveur); foreach ($GLOBALS['liste_des_authentifications'] as $methode) { array_shift($args); array_unshift($args,$methode); auth_administrer('synchroniser_distant',$args); } } else auth_administrer('synchroniser_distant',$args); } /** * * @param string $login * @param string $pw * @param string $serveur * @return array */ function lire_php_auth($login, $pw, $serveur=''){ $row = sql_fetsel('*', 'spip_auteurs', 'login=' . sql_quote($login),'','','','',$serveur); if (!$row) { if (spip_connect_ldap($serveur) AND $auth_ldap = charger_fonction('ldap', 'auth', true)) return $auth_ldap($login, $pw, $serveur); return false; } // su pas de source definie // ou auth/xxx introuvable, utiliser 'spip' if (!$auth_methode = $row['source'] OR !$auth = charger_fonction($auth_methode, 'auth', true)) $auth = charger_fonction('spip', 'auth', true); $auteur=''; if ($auth) $auteur = $auth($login, $pw, $serveur); // verifier que ce n'est pas un message d'erreur if (is_array($auteur) AND count($auteur)) return $auteur; return false; } /** * entete php_auth (est-encore utilise ?) * * @param $pb * @param $raison * @param $retour * @param $url * @param $re * @param $lien */ function ask_php_auth($pb, $raison, $retour, $url='', $re='', $lien='') { @Header("WWW-Authenticate: Basic realm=\"espace prive\""); @Header("HTTP/1.0 401 Unauthorized"); $ici = generer_url_ecrire(); echo "$pb

$raison

[$retour] "; if ($url) { echo "[$re]"; } if ($lien) echo " ["._T('login_espace_prive')."]"; exit; } ?>