diff --git a/ecrire/action/cookie.php b/ecrire/action/cookie.php
index a3b9b4b26bbbb2a7e7667dc2ffec490591e24796..0722c50ae2bce2bdd7760fb3c3abd3eb99aebde7 100644
--- a/ecrire/action/cookie.php
+++ b/ecrire/action/cookie.php
@@ -67,24 +67,12 @@ function action_spip_cookie_dist()
     $var_lang_ecrire;
 
 // rejoue le cookie pour renouveler spip_session
-if ($change_session == 'oui') {
-	if (verifier_session($spip_session)) {
-		// Attention : seul celui qui a le bon IP a le droit de rejouer,
-		// ainsi un eventuel voleur de cookie ne pourrait pas deconnecter
-		// sa victime, mais se ferait deconnecter par elle.
-		if ($auteur_session['hash_env'] == hash_env()) {
-			spip_log("rejoue session");
-			$auteur_session['ip_change'] = false;
-			$cookie = creer_cookie_session($auteur_session);
-			supprimer_session($spip_session);
-			spip_setcookie('spip_session', $cookie);
-		}
-		else
-			spip_log("session non rejouee, changement d'IP ?");
-	}
+  if ($change_session == 'oui') {
+	$var_f = charger_fonction('session', 'inc');
+	$var_f(true);
 	envoie_image_vide();
 	exit;
-}
+  }
 
 // tentative de connexion en auth_http
 if ($essai_auth_http AND !$ignore_auth_http) {
@@ -102,7 +90,8 @@ if ($logout) {
 	if ($auteur_session['login'] == $logout) {
 		spip_query("UPDATE spip_auteurs SET en_ligne = DATE_SUB(NOW(),INTERVAL 6 MINUTE) WHERE id_auteur = ".$auteur_session['id_auteur']);
 		if ($spip_session) {
-			zap_sessions($auteur_session['id_auteur'], true);
+			$var_f = charger_fonction('session', 'inc');
+			$var_f($auteur_session['id_auteur']);
 			spip_setcookie('spip_session', $spip_session, time() - 3600 * 24);
 		}
 		
@@ -160,14 +149,16 @@ if ($essai_login == "oui") {
 	} else {
 		spip_log("login de $session_login vers $redirect");
 		// Si on se connecte dans l'espace prive, 
-		// ajouter "bonjour" (inutilise)
+		// ajouter "bonjour" (repere a peu pres les cookies desactives)
 		if (ereg(_DIR_RESTREINT_ABS, $redirect)) {
 			$redirect .= ((false !== strpos($redirect, "?")) ? "&" : "?")
 				. 'bonjour=oui';
 		}
 		if ($row_auteur['statut'] == '0minirezo')
 			$cookie_admin = "@".$session_login;
-		$cookie_session = creer_cookie_session($row_auteur);
+	        
+		$var_f = charger_fonction('session', 'inc');
+		$cookie_session = $var_f($row_auteur);
 	}
 }
 
@@ -196,7 +187,8 @@ if ($cookie_session) {
 
 	$prefs = ($row_auteur['prefs']) ? unserialize($row_auteur['prefs']) : array();
 	$prefs['cnx'] = ($session_remember == 'oui') ? 'perma' : '';
-	update_prefs_session($prefs, $row_auteur['id_auteur']);
+
+	spip_query("UPDATE spip_auteurs SET prefs = " . spip_abstract_quote(serialize($prefs)) . " WHERE id_auteur = " . $row_auteur['id_auteur']);
  }
 
 // changement de langue espace public
@@ -217,11 +209,12 @@ if ($var_lang_ecrire) {
 	spip_setcookie('spip_lang_ecrire', $var_lang_ecrire, time() + 365 * 24 * 3600);
 	spip_setcookie('spip_lang', $var_lang_ecrire, time() + 365 * 24 * 3600);
 
-	// ce ajouter_session me semble deja fait si on arrive jusqu'ici
-	// avec id_auteur defini
 	if (_FILE_CONNECT AND $id_auteur) {
 		if (verifier_action_auteur("cookie-var_lang_ecrire", $hash, $id_auteur)) {
-			ajouter_session($auteur_session, $spip_session, $var_lang_ecrire);
+			spip_query("UPDATE spip_auteurs SET lang = " . spip_abstract_quote($var_lang_ecrire) . " WHERE id_auteur = " . intval($id_auteur));
+			$auteur_session['lang'] = $var_lang_ecrire;
+			$var_f = charger_fonction('session', 'inc');
+			$var_f($auteur_session);
 		}
 	}
 
diff --git a/ecrire/exec/auteur_infos.php b/ecrire/exec/auteur_infos.php
index 6dae335591a891e0ae0b535f051d300d72a54bb9..333f5769967e71b1b9c61dbdedb74963dba4b878 100644
--- a/ecrire/exec/auteur_infos.php
+++ b/ecrire/exec/auteur_infos.php
@@ -105,10 +105,8 @@ if (strval($nom)!='') {
 	}
 
 	if ($modif_login) {
-		include_spip('inc/session');
-		zap_sessions ($auteur['id_auteur'], true);
-		if ($connect_id_auteur == $auteur['id_auteur'])
-			supprimer_session($GLOBALS['spip_session']);
+		$var_f = charger_fonction('session', 'inc');
+		$var_f($auteur['id_auteur']);
 	}
 
 	// email
diff --git a/ecrire/inc/auth.php b/ecrire/inc/auth.php
index 44fe114ac9560e4e92de7ecffbab893c1d5dd72b..c08ce135bb0b805f6018ccde9453da512e86096a 100644
--- a/ecrire/inc/auth.php
+++ b/ecrire/inc/auth.php
@@ -91,7 +91,8 @@ function inc_auth_dist() {
 
 	// Authentification session
 	if ($cookie_session = $_COOKIE['spip_session']) {
-		if (verifier_session($cookie_session)) {
+		$var_f = charger_fonction('session', 'inc');
+		if ($var_f()) {
 			if ($auteur_session['statut'] == '0minirezo'
 			OR $auteur_session['statut'] == '1comite') {
 				$connect_login = $auteur_session['login'];
diff --git a/ecrire/inc/presentation.php b/ecrire/inc/presentation.php
index 207207103cecd8c3b6a346c8c0dc630ded92cdad..3b592fdc43fec516c1923e667ee8164c4da656ff 100644
--- a/ecrire/inc/presentation.php
+++ b/ecrire/inc/presentation.php
@@ -2857,17 +2857,7 @@ function debut_droite($rubrique="") {
 
 function fin_html() {
 
-	echo "</font>";
-
-	// rejouer le cookie de session si l'IP a change
-	if ($GLOBALS['spip_session'] && $GLOBALS['auteur_session']['ip_change']) {
-		echo 
-		  http_img_pack('rien.gif', " ", "name='img_session' width='0' height='0'"),
-		  http_script("\ndocument.img_session.src='" . generer_url_public('spip_cookie','change_session=oui') . "'");
-	}
-
-	echo "</body></html>\n";
-
+	echo "</font>", $GLOBALS['rejoue_session'], "</body></html>\n";
 }
 
 
diff --git a/ecrire/inc/session.php b/ecrire/inc/session.php
index ac3b59488ad3aac9cf345f2c5525e0bd58b9a8e5..cf53288bf199ebd5b625291d36ac404a5a1e194a 100644
--- a/ecrire/inc/session.php
+++ b/ecrire/inc/session.php
@@ -22,38 +22,38 @@ include_spip('inc/meta');
  */
 
 $GLOBALS['auteur_session'] = '';
+$GLOBALS['rejoue_session'] = '';
 
 //
-// On verifie l'IP et le nom du navigateur
+// 3 actions sur les sessions, selon le type de l'argument:
 //
-function hash_env() {
-	return md5($GLOBALS['ip'] . $_SERVER['HTTP_USER_AGENT']);
-}
-
-
-//
-// Calcule le nom du fichier session
-//
-function fichier_session($id_session, $alea) {
-	if (ereg("^([0-9]+_)", $id_session, $regs))
-		$id_auteur = $regs[1];
-	return _DIR_SESSIONS . 'session_'.$id_auteur.md5($id_session.' '.$alea). '.php';
+// - numérique: efface toutes les sessions de l'id_auteur (retour quelconque)
+// - tableau: cree une session pour l'auteur decrit et retourne l'identifiant
+// - autre: predicat de validite de la session indiquee par le cookie
 
+function inc_session_dist($auteur=false)
+{
+	if (is_numeric($auteur))
+		return supprimer_sessions($auteur);
+	else if (is_array($auteur))
+		return ajouter_session($auteur);
+	else return verifier_session($auteur);
 }
 
 //
-// Ajouter une session pour l'auteur specifie
+// Ajoute une session pour l'auteur decrit par un tableau issu d'un SELECT-SQL
 //
-function ajouter_session($auteur, $id_session, $lang='') {
 
-	global $auteur_session;
-	if ($lang) {
-		spip_query("UPDATE spip_auteurs SET lang = " . spip_abstract_quote($lang) . " WHERE id_auteur = " . intval($auteur['id_auteur']));
-		$auteur_session['lang'] = $lang;
-	}
+function ajouter_session($auteur) {
 
+	global $spip_session;
 	renouvelle_alea();
-	$fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere']);
+	if (!$spip_session) 
+		$spip_session = $auteur['id_auteur'].'_'.md5(creer_uniqid());
+
+	$fichier_session = fichier_session($spip_session, $GLOBALS['meta']['alea_ephemere']);
+
+	if (!isset($auteur['hash_env'])) $auteur['hash_env'] = hash_env();
 
 	$texte = "<"."?php\n";
 	foreach (array('id_auteur', 'nom', 'login', 'email', 'statut', 'lang', 'ip_change', 'hash_env') AS $var) {
@@ -64,73 +64,106 @@ function ajouter_session($auteur, $id_session, $lang='') {
 
 	if (!ecrire_fichier($fichier_session, $texte))
 		redirige_par_entete(generer_url_action('test_dirs','',true));
+	else return $spip_session;
 }
 
-function update_prefs_session($prefs, $id_auteur)
-{
-	$prefs = serialize($prefs);
-	spip_query("UPDATE spip_auteurs SET prefs = " . spip_abstract_quote($prefs) . " WHERE id_auteur = $id_auteur");
+//
+// Cette fonction efface toutes les sessions appartenant a l'auteur
+// On en profite pour effacer toutes les sessions creees il y a plus de 48 h
+//
+
+function supprimer_sessions($id_auteur) {
+
+	$dir = opendir(_DIR_SESSIONS);
+	$t = time()  - (48 * 3600);
+	while(($f = readdir($dir)) !== false) {
+
+		if (ereg("^session_([0-9]+)_[a-z0-9]+\.php[3]?$", $f, $regs)){
+			$f = _DIR_SESSIONS . $f;
+			if (($regs[1] == $id_auteur) OR ($t > filemtime($f)))
+				@unlink($f);
+		}
+	}
 }
 
 //
-// Verifier et inclure une session
+// Verifie et inclut une session. 
+// La rejoue si IP change puis accepte le changement si $change=true
 //
-function verifier_session($id_session) {
+
+function verifier_session($change=false) {
+
+	global $spip_session; // issu du cookie
 
 	// Tester avec alea courant
-	$ok = false;
-	if ($id_session) {
-		$fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere']);
-		if (@file_exists($fichier_session)) {
-			include($fichier_session);
-			$ok = true;
-		}
-		else {
-			// Sinon, tester avec alea precedent
-			$fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere_ancien']);
-			if (@file_exists($fichier_session)) {
-				// Renouveler la session (avec l'alea courant)
-				include($fichier_session);
-				supprimer_session($id_session);
-				ajouter_session($GLOBALS['auteur_session'], $id_session);
-				$ok = true;
-			}
-		}
+	if (!$spip_session) return false;
+
+	$fichier_session = fichier_session($spip_session, $GLOBALS['meta']['alea_ephemere']);
+	if (@file_exists($fichier_session)) {
+		include($fichier_session);
+	} else {
+		// Sinon, tester avec alea precedent
+		$fichier_session = fichier_session($spip_session, $GLOBALS['meta']['alea_ephemere_ancien']);
+		if (!@file_exists($fichier_session)) return false;
+
+		// Renouveler la session avec l'alea courant
+		include($fichier_session);
+		@unlink($fichier_session);
+		ajouter_session($GLOBALS['auteur_session']);
 	}
 
-	// marquer la session comme "ip-change" si le cas se presente
-	if ($ok AND (hash_env() != $GLOBALS['auteur_session']['hash_env']) AND !$GLOBALS['auteur_session']['ip_change']) {
+	// Si l'adresse IP change, inc/presentation mettra une balise image
+	// avec un URL de rappel demandant a changer le nom de la session.
+	// Seul celui qui a l'IP d'origine est rejoue
+	// ainsi un eventuel voleur de cookie ne pourrait pas deconnecter
+	// sa victime, mais se ferait deconnecter par elle.
+
+	if (hash_env() != $GLOBALS['auteur_session']['hash_env']) {
+	    if (!$GLOBALS['auteur_session']['ip_change']) {
+		$GLOBALS['rejoue_session'] = rejouer_session();
 		$GLOBALS['auteur_session']['ip_change'] = true;
-		ajouter_session($GLOBALS['auteur_session'], $id_session);
+		ajouter_session($GLOBALS['auteur_session']);
+	    } else if ($change)
+	      spip_log("session non rejouee, vol de cookie ?");
+	} else { if ($change) {
+		spip_log("rejoue session $fichier_session $spip_session");
+		@unlink($fichier_session);
+		$auteur_session['ip_change'] = false;
+		unset($spip_session);
+		$cookie= ajouter_session($auteur_session);
+		spip_setcookie('spip_session', $cookie);
+	  }
 	}
+	return 	true;
+}
+
+// Code a inserer par inc/presentation pour rejouer la session
+// Voir action/cookie qui sera appele.
 
-	return $ok;
+function rejouer_session()
+{
+	include_spip('inc/minipres');
+	return	  http_img_pack('rien.gif', " ", "id='img_session' width='0' height='0'") .
+		  http_script("\ndocument.img_session.src='" . generer_url_action('cookie','change_session=oui', true) .  "'");
 }
 
 //
-// Supprimer une session
+// Calcule le nom du fichier session
 //
-function supprimer_session($id_session) {
-	$fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere']);
-	if (@file_exists($fichier_session)) {
-		@unlink($fichier_session);
-	}
-	$fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere_ancien']);
-	if (@file_exists($fichier_session)) {
-		@unlink($fichier_session);
-	}
+function fichier_session($id_session, $alea) {
+	if (ereg("^([0-9]+_)", $id_session, $regs))
+		$id_auteur = $regs[1];
+	return _DIR_SESSIONS . 'session_'.$id_auteur.md5($id_session.' '.$alea). '.php';
 }
 
 //
-// Creer une session et retourne le cookie correspondant (a poser)
+// On verifie l'IP et le nom du navigateur
 //
-function creer_cookie_session($auteur) {
-	if ($id_auteur = $auteur['id_auteur']) {
-		$id_session = $id_auteur.'_'.md5(creer_uniqid());
-		$auteur['hash_env'] = hash_env();
-		ajouter_session($auteur, $id_session);
-		return $id_session;
-	}
+
+function hash_env() {
+  static $res ='';
+  if ($res) return $res;
+  return $res = md5($GLOBALS['ip'] . $_SERVER['HTTP_USER_AGENT']);
 }
 
 //
@@ -152,38 +185,6 @@ function creer_uniqid() {
 }
 
 
-//
-// Cette fonction efface toutes les sessions appartenant a l'auteur
-// On en profite pour effacer toutes les sessions creees il y a plus de 48 h
-//
-function zap_sessions ($id_auteur, $zap) {
-
-	// ne pas se zapper soi-meme
-	if ($s = $GLOBALS['spip_session'])
-		$fichier_session = fichier_session($s, $GLOBALS['meta']['alea_ephemere']);
-
-	$dir = opendir(_DIR_SESSIONS);
-	$t = time();
-	while(($item = readdir($dir)) !== false) {
-		$chemin = _DIR_SESSIONS . $item;
-		if (ereg("^session_([0-9]+_)?([a-z0-9]+)\.php[3]?$", $item, $regs)) {
-
-			// Si c'est une vieille session, on jette
-			if (($t - filemtime($chemin)) > 48 * 3600)
-				@unlink($chemin);
-
-			// sinon voir si c'est une session du meme auteur
-			else if ($regs[1] == $id_auteur.'_') {
-				$zap_num ++;
-				if ($zap)
-					@unlink($chemin);
-			}
-
-		}
-	}
-
-	return $zap_num;
-}
 
 //
 // reconnaitre un utilisateur authentifie en php_auth
@@ -222,14 +223,6 @@ function ask_php_auth($pb, $raison, $retour, $url='', $re='', $lien='') {
 	exit;
 }
 
-//
-// verifie si on a un cookie de session ou un auth_php correct
-// et charge ses valeurs dans $GLOBALS['auteur_session']
-//
-function verifier_session_visiteur() {
-	return verifier_session($_COOKIE['spip_session']) ? true : verifier_php_auth();
-}
-
 //
 // Renouvellement de l'alea utilise pour valider certaines operations
 // (session, ajouter une image, etc.)
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index d18c223aee840f2fc4a98b7759971ef9797c1754..017b052c1f2592fd15a8a4d35478efd196d7799f 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -1040,8 +1040,8 @@ function verifier_visiteur() {
 
 	if (isset($_COOKIE['spip_session']) OR
 	(isset($_SERVER['PHP_AUTH_USER'])  AND !$GLOBALS['ignore_auth_http'])) {
-		include_spip('inc/session');
-		verifier_session_visiteur();
+		$var_f = charger_fonction('session', 'inc');
+		if (!$var_f()) verifier_php_auth();
 	}
 }
 
diff --git a/ecrire/index.php b/ecrire/index.php
index f8ef2c80e69605ed94186517c2972d59eb683402..cf618cc6b424a09dbc52e8d53f469a817b21badc 100644
--- a/ecrire/index.php
+++ b/ecrire/index.php
@@ -106,7 +106,7 @@ if (isset($set_options) AND ($set_options == 'avancees' OR $set_options == 'basi
 	$prefs_mod = true;
 }
 if ($prefs_mod AND !$var_auth)
-	update_prefs_session($prefs, $connect_id_auteur);
+	spip_query("UPDATE spip_auteurs SET prefs = " . spip_abstract_quote(serialize($prefs)) . " WHERE id_auteur = $connect_id_auteur");
 
 if (isset($set_ecran)) {
 	// Poser un cookie, car ce reglage depend plus du navigateur que de l'utilisateur
@@ -149,7 +149,10 @@ if (isset($GLOBALS['_COOKIE']['spip_lang_ecrire'])) {
 	// si authentifie, changer definitivement si ce n'est fait
 	else {	if (($spip_lang_ecrire <> $auteur_session['lang'])
 		AND changer_langue($spip_lang_ecrire)) {
-		ajouter_session($auteur_session, $spip_session, $spip_lang_ecrire);
+			spip_query("UPDATE spip_auteurs SET lang = " . spip_abstract_quote($spip_lang_ecrire) . " WHERE id_auteur = " . intval($auteur_session['id_auteur']));
+			$auteur_session['lang'] = $var_lang_ecrire;
+			$var_f = charger_fonction('session', 'inc');
+			$var_f($auteur_session);
 	       }
 	}
  }