diff --git a/htdocs/admin/tools/listevents.php b/htdocs/admin/tools/listevents.php
index c5e6065a86555ea1762eee13983af3d48f2fec49..02f052e83da697634da2dd4796da85f12e0cd1f5 100644
--- a/htdocs/admin/tools/listevents.php
+++ b/htdocs/admin/tools/listevents.php
@@ -17,9 +17,9 @@
  */
 
 /**
-        \file       htdocs/compta/clients.php
-        \ingroup    compta
-        \brief      Page accueil des clients
+        \file       htdocs/admin/tools/listevents.php
+        \ingroup    core
+        \brief      List of security events
         \version    $Id$
 */
  
@@ -58,8 +58,8 @@ llxHeader();
 
 $userstatic=new User($db);
 
-$sql = "SELECT e.rowid, e.type, ".$db->pdate("e.dateevent")." as dateevent,";
-$sql.= " e.fk_user, e.label, e.description,";
+$sql = "SELECT e.rowid, e.type, e.ip, ".$db->pdate("e.dateevent")." as dateevent,";
+$sql.= " e.fk_user, e.description,";
 $sql.= " u.login";
 $sql.= " FROM ".MAIN_DB_PREFIX."events as e";
 $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = e.fk_user";
@@ -77,9 +77,10 @@ if ($result)
 	print '<table class="liste" width="100%">';
 	print '<tr class="liste_titre">';
 	print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"e.dateevent","","",'align="left"',$sortfield,$sortorder);
-	print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"e.type","","",'align="left"',$sortfield,$sortorder);
+	print_liste_field_titre($langs->trans("Code"),$_SERVER["PHP_SELF"],"e.type","","",'align="left"',$sortfield,$sortorder);
+	print_liste_field_titre($langs->trans("IP"),$_SERVER["PHP_SELF"],"e.ip","","",'align="left"',$sortfield,$sortorder);
 	print_liste_field_titre($langs->trans("User"),$_SERVER["PHP_SELF"],"u.login","","",'align="left"',$sortfield,$sortorder);
-	print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"e.label","","",'align="left"',$sortfield,$sortorder);
+	print_liste_field_titre($langs->trans("Description"),$_SERVER["PHP_SELF"],"e.description","","",'align="left"',$sortfield,$sortorder);
 	print '<td>&nbsp;</td>';
 	print "</tr>\n";
 
@@ -96,10 +97,6 @@ if ($result)
 	print '<input class="flat" type="text" size="10" name="search_compta" value="'.$_GET["search_user"].'">';
 	print '</td>';
 
-	print '<td align="left" class="liste_titre">';
-	print '<input class="flat" type="text" size="10" name="search_compta" value="'.$_GET["search_label"].'">';
-	print '</td>';
-
 	print '<td align="right" class="liste_titre">';
 	print '<input type="image" class="liste_titre" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png" name="button_search" alt="'.$langs->trans("Search").'">';
 	print '</td>';
@@ -116,14 +113,32 @@ if ($result)
 		$var=!$var;
 
 		print "<tr $bc[$var]>";
-		print '<td align="left" nowrap="nowrap">'.dolibarr_print_date($obj->dateevent,'dayhour').'</td>';
+	
+		// Date
+		print '<td align="left" nowrap="nowrap">'.dolibarr_print_date($obj->dateevent,'%Y-%m-%d %H:%M:%S').'</td>';
+
+		// Code
 		print '<td>'.$obj->type.'</td>';
-		$userstatic->id=$obj->fk_user;
-		$userstatic->login=$obj->login;
-		print '<td>'.$userstatic->getLoginUrl(1).'</td>';
-		print '<td>'.$obj->label.'</td>';
-//		print '<td>'.$obj->description.'</td>';
+
+		// IP
+		print '<td>'.$obj->ip.'</td>';
+
+		// Login
+		print '<td>';
+		if ($obj->fk_user)
+		{
+			$userstatic->id=$obj->fk_user;
+			$userstatic->login=$obj->login;
+			print $userstatic->getLoginUrl(1);
+		}
+		else print '&nbsp;';
+		print '</td>';
+
+		// Description
+		print '<td>'.$obj->description.'</td>';
+		
 		print '<td>&nbsp;</td>';
+
 		print "</tr>\n";
 		$i++;
 	}
diff --git a/htdocs/core/events.class.php b/htdocs/core/events.class.php
index c43dd7db134b87a11bfc7f83c265771aa648b943..7f35d11f66db50cacec2911eddb5ad3020a288cf 100644
--- a/htdocs/core/events.class.php
+++ b/htdocs/core/events.class.php
@@ -49,7 +49,6 @@ class Events // extends CommonObject
 	var $tms;
 	var $type;
 	var $dateevent;
-	var $label;
 	var $description;
 
     
@@ -78,30 +77,28 @@ class Events // extends CommonObject
 		// Clean parameters
 		$this->id=trim($this->id);
 		$this->fk_action=trim($this->fk_action);
-		$this->label=trim($this->label);
 		$this->description=trim($this->description);
 
 		// Check parameters
-		if (! $user->id) { $this->error='ErrorBadValueForParameter'; return -1; }
+		if (! $this->description) { $this->error='ErrorBadValueForParameter'; return -1; }
 		
         // Insert request
 		$sql = "INSERT INTO ".MAIN_DB_PREFIX."events(";
 		
 		$sql.= "type,";
+		$sql.= "ip,";
 		$sql.= "dateevent,";
 		$sql.= "fk_user,";
-		$sql.= "label,";
 		$sql.= "description";
 
         $sql.= ") VALUES (";
        
 		$sql.= " '".$this->type."',";
+		$sql.= " '".$_SERVER['REMOTE_ADDR']."',";
 		$sql.= " ".$this->db->idate($this->dateevent).",";
-		$sql.= " '".$user->id."',";
-		$sql.= " '".$this->label."',";
+		$sql.= " ".($user->id?"'".$user->id."'":'NULL').",";
 		$sql.= " '".$this->description."'";
 
-        
 		$sql.= ")";
 
 	   	dolibarr_syslog("Events::create sql=".$sql, LOG_DEBUG);
@@ -134,7 +131,6 @@ class Events // extends CommonObject
         
 		$this->id=trim($this->id);
 		$this->type=trim($this->type);
-		$this->label=trim($this->label);
 		$this->description=trim($this->description);
 
         
@@ -147,7 +143,6 @@ class Events // extends CommonObject
         
 		$sql.= " type='".$this->type."',";
 		$sql.= " dateevent=".$this->db->idate($this->dateevent).",";
-		$sql.= " label='".addslashes($this->label)."',";
 		$sql.= " description='".addslashes($this->description)."'";
         
         $sql.= " WHERE rowid=".$this->id;
@@ -180,7 +175,6 @@ class Events // extends CommonObject
 		$sql.= " ".$this->db->pdate('t.tms').",";
 		$sql.= " t.type,";
 		$sql.= " ".$this->db->pdate('t.dateevent').",";
-		$sql.= " t.label,";
 		$sql.= " t.description";
 
 		
@@ -200,7 +194,6 @@ class Events // extends CommonObject
 				$this->tms = $obj->tms;
 				$this->type = $obj->type;
 				$this->dateevent = $obj->dateevent;
-				$this->label = $obj->label;
 				$this->description = $obj->description;
 
                 
@@ -254,7 +247,6 @@ class Events // extends CommonObject
 		$this->tms=time();
 		$this->type='';
 		$this->dateevent=time();
-		$this->label='Speciment event';
 		$this->description='This is a specimen event';
 	}
 
diff --git a/htdocs/includes/login/functions_dolibarr.php b/htdocs/includes/login/functions_dolibarr.php
index 91b6a1ebe92d52c89d9edf5c8dcb1f04b3c8e5ec..aa56cf80aab0a19d0e66fa780d5633b8aeeaf4d0 100644
--- a/htdocs/includes/login/functions_dolibarr.php
+++ b/htdocs/includes/login/functions_dolibarr.php
@@ -1,5 +1,5 @@
 <?php
-/* Copyright (C) 2007 Laurent Destailleur  <eldy@users.sourceforge.net>
+/* Copyright (C) 2007-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,14 +14,13 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id$
  */
 
 /**
         \file       htdocs/includes/login/functions_dolibarr.php
         \ingroup    core
         \brief      Authentication functions for Dolibarr mode
+		\version	$Id$
 */
 
 
diff --git a/htdocs/includes/triggers/interface_all_Logevents.class.php b/htdocs/includes/triggers/interface_all_Logevents.class.php
index 5055183156777cb00da0d57005ec034bb3f690ed..d2b107bc9e8b107540670438f3d612c761bc2197 100644
--- a/htdocs/includes/triggers/interface_all_Logevents.class.php
+++ b/htdocs/includes/triggers/interface_all_Logevents.class.php
@@ -49,7 +49,7 @@ class InterfaceLogevents
     
         $this->name = "Logevents";
         $this->family = "core";
-        $this->description = "Les triggers de ce composant permettent de logguer les evenements Dolibarr (modification status des objets).";
+        $this->description = "Les triggers de ce composant permettent de logguer les evenements de securite Dolibarr.";
         $this->version = 'dolibarr';                        // 'experimental' or 'dolibarr' or version
     }
 
@@ -116,6 +116,17 @@ class InterfaceLogevents
             $this->texte=$langs->transnoentities("UserLogged",$object->login);
             $this->desc=$langs->transnoentities("UserLogged",$object->login);
 		}
+        if ($action == 'USER_LOGIN_FAILED')
+        {
+            dolibarr_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
+            $langs->load("users");
+		
+            // Initialisation donnees (date,duree,texte,desc)
+            $this->date=time();
+            $this->duree=0;
+            $this->texte=$object->trigger_mesg;	// Message direct
+            $this->desc=$object->trigger_mesg;	// Message direct
+		}
         if ($action == 'USER_CREATE')
         {
             dolibarr_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
@@ -496,10 +507,10 @@ class InterfaceLogevents
             }
             else
             {
-                $error ="Failed to insert : ".$webcal->error." ";
+                $error ="Failed to insert security event: ".$event->error;
                 $this->error=$error;
 
-                //dolibarr_syslog("interface_webcal.class.php: ".$this->error);
+                dolibarr_syslog("interface_all_Logevents.class.php: ".$this->error);
                 return -1;
             }
         }
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 2c886e701bcb8d6d5080ac3b75e5cdd871d175bf..6bffe53c02b0f1863d41f726140f41addd02c8b0 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -111,7 +111,6 @@ if ($conf->main_force_https)
 }
 
 // Chargement des includes complementaire de presentation
-
 if (! defined('NOREQUIREMENU')) require_once(DOL_DOCUMENT_ROOT ."/menu.class.php");			// Need 11ko memory (11ko in 2.2)
 if (! defined('NOREQUIREHTML')) require_once(DOL_DOCUMENT_ROOT ."/html.form.class.php");	// Need 690ko memory (800ko in 2.2)
 if (! defined('NOREQUIREAJAX') && $conf->use_javascript_ajax) require_once(DOL_DOCUMENT_ROOT.'/lib/ajax.lib.php');	// Need 20ko memory
@@ -123,9 +122,6 @@ session_name($sessionname);
 session_start();
 dolibarr_syslog("Session name=".$sessionname." Session id()=".session_id().", _SESSION['dol_login']=".$_SESSION["dol_login"]);
 
-$bc[0]="class=\"impair\"";
-$bc[1]="class=\"pair\"";
-
 /*
  * Phase identification
  */
@@ -177,40 +173,70 @@ if (! isset($_SESSION["dol_login"]))
 			dolibarr_syslog('Bad value for code, connexion refused');
 			$langs->load('main');
 			$langs->load('other');
+			
+			$user->trigger_mesg='ErrorBadValueForCode - login='.$_POST["username"];
 			$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadValueForCode");
 			$test=false;
+			
+			// Appel des triggers
+			include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
+			$interface=new Interfaces($db);
+			$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
+			if ($result < 0) { $error++; }
+			// Fin appel triggers
 		}
 	}
     
 	// Tests de validation user/mot de passe
 	// Si ok, la variable login doit avoir ete initialisee
 	// Si erreur, on a place message erreur dans session sous le nom dol_loginmesg
-	foreach($authmode as $mode)
+	if ($test)
 	{
-		if ($test && $mode && ! $login)
+		foreach($authmode as $mode)
 		{
-			$authfile=DOL_DOCUMENT_ROOT.'/includes/login/functions_'.$mode.'.php';
-			$result=include_once($authfile);
-			if ($result)
-			{
-				// Call function to check user/password
-			    $usertotest=$_POST["username"];
-			    $passwordtotest=$_POST["password"];
-				$function='check_user_password_'.$mode;
-				$login=$function($usertotest,$passwordtotest);
-				if ($login) $test=false;
-			}
-			else
+			if ($test && $mode && ! $login)
 			{
-				dolibarr_syslog("Authentification ko - failed to load file '".$authfile."'");
-				sleep(1);
-				$langs->load('main');
-				$langs->load('other');
-				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode",$mode);
+				$authfile=DOL_DOCUMENT_ROOT.'/includes/login/functions_'.$mode.'.php';
+				$result=include_once($authfile);
+				if ($result)
+				{
+					// Call function to check user/password
+				    $usertotest=$_POST["username"];
+				    $passwordtotest=$_POST["password"];
+					$function='check_user_password_'.$mode;
+					$login=$function($usertotest,$passwordtotest);
+					if ($login) $test=false;
+				}
+				else
+				{
+					dolibarr_syslog("Authentification ko - failed to load file '".$authfile."'",LOG_ERR);
+					sleep(1);
+					$langs->load('main');
+					$langs->load('other');
+					$_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode",$mode);
+				}
 			}
 		}
-	}
 
+		if (! $login)
+		{
+			dolibarr_syslog('Bad password, connexion refused',LOG_DEBUG);
+			$langs->load('main');
+			$langs->load('other');
+
+			// Bad password. No authmode has found a good password.
+			$user->trigger_mesg=$langs->trans("ErrorBadLoginPassword").' - login='.$_POST["username"];
+			$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
+			
+			// Appel des triggers
+			include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
+			$interface=new Interfaces($db);
+			$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
+			if ($result < 0) { $error++; }
+			// Fin appel triggers
+		}
+	}
+	
 	// Fin des tests de login/passwords
     if (! $login)
     {
@@ -228,8 +254,27 @@ if (! isset($_SESSION["dol_login"]))
 		session_start();
 
 		$langs->load('main');
-		if ($resultFetchUser == 0) $_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
-		if ($resultFetchUser < 0)  $_SESSION["dol_loginmesg"]=$user->error;
+		if ($resultFetchUser == 0) 
+		{
+			$langs->load('main');
+			$langs->load('other');
+
+			$user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login;
+			$_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
+		}
+		if ($resultFetchUser < 0)
+		{
+			$user->trigger_mesg=$user->error;
+			$_SESSION["dol_loginmesg"]=$user->error;
+		}
+
+		// Appel des triggers
+		include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
+		$interface=new Interfaces($db);
+		$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
+		if ($result < 0) { $error++; }
+		// Fin appel triggers
+
 		header('Location: '.DOL_URL_ROOT.'/index.php');
 		exit;
 	}
@@ -250,8 +295,27 @@ else
 		session_start();
 
 		$langs->load('main');
-		if ($resultFetchUser == 0) $_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
-		if ($resultFetchUser < 0)  $_SESSION["dol_loginmesg"]=$user->error;
+		if ($resultFetchUser == 0) 
+		{
+			$langs->load('main');
+			$langs->load('other');
+
+			$user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login;
+			$_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login);
+		}
+		if ($resultFetchUser < 0)
+		{
+			$user->trigger_mesg=$user->error;
+			$_SESSION["dol_loginmesg"]=$user->error;
+		}
+
+		// Appel des triggers
+		include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
+		$interface=new Interfaces($db);
+		$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf);
+		if ($result < 0) { $error++; }
+		// Fin appel triggers
+
 		header('Location: '.DOL_URL_ROOT.'/index.php');
 		exit;
 	}
@@ -273,13 +337,15 @@ if (! isset($_SESSION["dol_login"]))
 	include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php");
 	$interface=new Interfaces($db);
 	$result=$interface->run_triggers('USER_LOGIN',$user,$user,$langs,$conf);
-	if ($result < 0) { $error++; $this->errors=$interface->errors; }
+	if ($result < 0) { $error++; }
 	// Fin appel triggers
 	
 	if ($error)
 	{
-		dolibarr_print_errors($db,$this->errors);
 		$db->rollback();
+		session_destroy();
+		dolibarr_print_error($db,'Error in some triggers on action USER_LOGIN',LOG_ERR);
+		exit;
 	}
 	else
 	{
diff --git a/mysql/migration/2.2.0-2.4.0.sql b/mysql/migration/2.2.0-2.4.0.sql
index 8facc488e1b5c9da945a5c940bae6eb5419dd4a0..ac40c7d5bb5d1ad179e24507becb265ffb3b1ae4 100644
--- a/mysql/migration/2.2.0-2.4.0.sql
+++ b/mysql/migration/2.2.0-2.4.0.sql
@@ -192,8 +192,8 @@ create table llx_events
   type			 varchar(32)  NOT NULL, 
   dateevent      datetime,             
   fk_user        integer,              
-  label          varchar(50)  NOT NULL, 
-  description    varchar(200) NOT NULL,        
+  description    varchar(250) NOT NULL,        
+  ip			 varchar(32) NOT NULL,
   fk_object      integer               
 ) type=innodb;
 
diff --git a/mysql/tables/llx_events.sql b/mysql/tables/llx_events.sql
index 48d59f5827a4dbbd46e67d08136e4feae2782368..2798cb356f59d18b98d7a90dedc8bdb0c896f708 100644
--- a/mysql/tables/llx_events.sql
+++ b/mysql/tables/llx_events.sql
@@ -17,8 +17,9 @@
 --
 -- $Id$
 -- ========================================================================
--- This table logs all dolibarr events
--- Content of this table is not managed by users but by Dolibarr triggers.
+-- This table logs all dolibarr security events
+-- Content of this table is not managed by users but by Dolibarr
+-- trigger interface_all_LogEvent.
 -- ========================================================================
 
 create table llx_events
@@ -28,8 +29,8 @@ create table llx_events
   type			 varchar(32)  NOT NULL, -- action type
   dateevent      datetime,              -- date event
   fk_user        integer,               -- id user
-  label          varchar(50)  NOT NULL, -- label of action
-  description    varchar(200) NOT NULL, -- full description of action
+  description    varchar(250) NOT NULL, -- full description of action
+  ip			 varchar(32) NOT NULL,  -- ip
   fk_object      integer                -- id of related object
 ) type=innodb;