diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php index d5362f4ac56..0b8d3e64828 100644 --- a/htdocs/api/class/api_login.class.php +++ b/htdocs/api/class/api_login.class.php @@ -121,6 +121,9 @@ class Login include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; $login = checkLoginPassEntity($login, $password, $entity, $authmode, 'api'); // Check credentials. + if ($login === '--bad-login-validity--') { + $login = ''; + } if (empty($login)) { throw new RestException(403, 'Access denied'); } diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index b33ad1333ef..5e4d58103d8 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -52,12 +52,11 @@ function dol_getwebuser($mode) * @param string $entitytotest Instance of data we must check * @param array $authmode Array list of selected authentication mode array('http', 'dolibarr', 'xxx'...) * @param string $context Context checkLoginPassEntity was created for ('api', 'dav', 'ws', '') - * @return string Login or '' + * @return string Login or '' or '--bad-login-validity--' */ function checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $authmode, $context = '') { global $conf, $langs; - //global $dolauthmode; // To return authentication finally used // Check parameters if ($entitytotest == '') { @@ -100,10 +99,10 @@ function checkLoginPassEntity($usertotest, $passwordtotest, $entitytotest, $auth if ($login && $login != '--bad-login-validity--') { // Login is successfull $test = false; // To stop once at first login success $conf->authmode = $mode; // This properties is defined only when logged to say what mode was successfully used - $dol_tz = GETPOST('tz'); + /*$dol_tz = GETPOST('tz'); $dol_dst = GETPOST('dst'); $dol_screenwidth = GETPOST('screenwidth'); - $dol_screenheight = GETPOST('screenheight'); + $dol_screenheight = GETPOST('screenheight');*/ } } else { dol_syslog("Authentication KO - failed to load file '".$authfile."'", LOG_ERR); diff --git a/htdocs/core/lib/ws.lib.php b/htdocs/core/lib/ws.lib.php index ad4688f9134..a26604b18bc 100644 --- a/htdocs/core/lib/ws.lib.php +++ b/htdocs/core/lib/ws.lib.php @@ -86,6 +86,10 @@ function check_authentication($authentication, &$error, &$errorcode, &$errorlabe include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; $login = checkLoginPassEntity($authentication['login'], $authentication['password'], $authentication['entity'], $authmode, 'ws'); + if ($login === '--bad-login-validity--') { + $login = ''; + } + if (empty($login)) { $error++; $errorcode = 'BAD_CREDENTIALS'; diff --git a/htdocs/core/login/functions_dolibarr.php b/htdocs/core/login/functions_dolibarr.php index e8c3ab38e46..b732d2ef64b 100644 --- a/htdocs/core/login/functions_dolibarr.php +++ b/htdocs/core/login/functions_dolibarr.php @@ -28,6 +28,7 @@ /** * Check validity of user/password/entity * If test is ko, reason must be filled into $_SESSION["dol_loginmesg"] + * Note: On critical error (hack attempt), we put a log "functions_dolibarr::check_user_password_dolibarr authentication KO" * * @param string $usertotest Login * @param string $passwordtotest Password @@ -56,7 +57,7 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes $usernamecol2 = 'email'; $entitycol = 'entity'; - $sql = "SELECT rowid, login, entity, pass, pass_crypted, datestartvalidity, dateendvalidity"; + $sql = "SELECT rowid, login, entity, pass, pass_crypted, datestartvalidity, dateendvalidity, flagdelsessionsbefore"; $sql .= " FROM ".$table; $sql .= " WHERE (".$usernamecol1." = '".$db->escape($usertotest)."'"; if (preg_match('/@/', $usertotest)) { @@ -74,18 +75,34 @@ function check_user_password_dolibarr($usertotest, $passwordtotest, $entitytotes $obj = $db->fetch_object($resql); if ($obj) { $now = dol_now(); + // Check date start validity if ($obj->datestartvalidity && $db->jdate($obj->datestartvalidity) > $now) { // Load translation files required by the page $langs->loadLangs(array('main', 'errors')); $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorLoginDateValidity"); + dol_syslog("functions_dolibarr::check_user_password_dolibarr bad datestart validity", LOG_WARNING); return '--bad-login-validity--'; } + // Check date end validity if ($obj->dateendvalidity && $db->jdate($obj->dateendvalidity) < dol_get_first_hour($now)) { // Load translation files required by the page $langs->loadLangs(array('main', 'errors')); $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorLoginDateValidity"); + dol_syslog("functions_dolibarr::check_user_password_dolibarr bad date end validity", LOG_WARNING); return '--bad-login-validity--'; } + // If there is an invalidation date, check that the current session date is not before this date + if ($obj->flagdelsessionsbefore && !empty($_SESSION["dol_logindate"])) { + dol_syslog("functions_dolibarr::check_user_password_dolibarr user has a date for session invalidation = ".$obj->flagdelsessionsbefore." and session date = ".$_SESSION["dol_logindate"]); + $datetmp = $db->jdate($obj->flagdelsessionsbefore, 'gmt'); + if ($datetmp > $now) { + // Load translation files required by the page + $langs->loadLangs(array('main', 'errors')); + $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorSessionInvalidatedAfterPasswordChange"); + dol_syslog("functions_dolibarr::check_user_password_dolibarr session was invalidated", LOG_WARNING); + return '--bad-login-validity--'; + } + } $passclear = $obj->pass; $passcrypted = $obj->pass_crypted; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 549c72157a6..7d764d4a105 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1048,6 +1048,7 @@ if (!defined('NOLOGIN')) { // Store value into session (values always stored) $_SESSION["dol_login"] = $user->login; + $_SESSION["dol_logindate"] = dol_now('gmt'); $_SESSION["dol_authmode"] = isset($dol_authmode) ? $dol_authmode : ''; $_SESSION["dol_tz"] = isset($dol_tz) ? $dol_tz : ''; $_SESSION["dol_tz_string"] = isset($dol_tz_string) ? $dol_tz_string : ''; diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 67ea2174322..0af78cc208f 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -71,6 +71,10 @@ $group = GETPOST("group", "int", 3); $cancel = GETPOST('cancel', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'useracard'; // To manage different context of search +if (empty($id)) { + $id = $user->id; +} + $dateemployment = dol_mktime(0, 0, 0, GETPOST('dateemploymentmonth', 'int'), GETPOST('dateemploymentday', 'int'), GETPOST('dateemploymentyear', 'int')); $dateemploymentend = dol_mktime(0, 0, 0, GETPOST('dateemploymentendmonth', 'int'), GETPOST('dateemploymentendday', 'int'), GETPOST('dateemploymentendyear', 'int')); $datestartvalidity = dol_mktime(0, 0, 0, GETPOST('datestartvaliditymonth', 'int'), GETPOST('datestartvalidityday', 'int'), GETPOST('datestartvalidityyear', 'int')); diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 9e208ff3e37..7e342e64337 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2298,7 +2298,7 @@ class User extends CommonObject $sql = "UPDATE ".$this->db->prefix()."user"; $sql .= " SET pass_crypted = '".$this->db->escape($password_crypted)."',"; $sql .= " pass_temp = null"; - if (empty($flagdelsessionsbefore)) { + if (!empty($flagdelsessionsbefore)) { $sql .= ", flagdelsessionsbefore = '".$this->db->idate(dol_now() - 5, 'gmt')."'"; } if (!empty($conf->global->DATABASE_PWD_ENCRYPTED)) {