diff --git a/admin/inc/class.admin_account.inc.php b/admin/inc/class.admin_account.inc.php
index 913e7f0e3d..5e56c68749 100644
--- a/admin/inc/class.admin_account.inc.php
+++ b/admin/inc/class.admin_account.inc.php
@@ -86,6 +86,12 @@ class admin_account
$readonlys = array();
+ // at least ADS does not allow to unset it and SQL backend does not implement it either
+ if ($account['mustchangepassword'])
+ {
+ $readonlys['mustchangepassword'] = true;
+ }
+
if ($deny_edit)
{
foreach(array_keys($account) as $key)
diff --git a/etemplate/templates/default/etemplate2.css b/etemplate/templates/default/etemplate2.css
index c64e6a448b..9f481f2b40 100644
--- a/etemplate/templates/default/etemplate2.css
+++ b/etemplate/templates/default/etemplate2.css
@@ -901,7 +901,7 @@ td.et2_required {
border: 1px solid #E1E16D;
color: #000000;
font-size: 11px;
- height: 15px;
+ min-height: 15px;
padding: 4px 10px;
}
.error p {
diff --git a/login.php b/login.php
index e1934232e4..969ed78d89 100755
--- a/login.php
+++ b/login.php
@@ -132,11 +132,13 @@ else
return lang('Sorry, your login has expired');
case 4:
return lang('Cookies are required to login to this site');
- case 5:
+ case egw_session::CD_BAD_LOGIN_OR_PASSWORD:
return lang('Bad login or password');
- case 98:
+ case egw_session::CD_FORCE_PASSWORD_CHANGE:
+ return lang('You must change your password!');
+ case egw_session::CD_ACCOUNT_EXPIRED:
return lang('Account is expired');
- case 99:
+ case egw_session::CD_BLOCKED:
return lang('Blocked, too many attempts');
case 10:
$GLOBALS['egw']->session->egw_setcookie('sessionid');
@@ -272,9 +274,32 @@ else
$login .= '@'.$GLOBALS['egw_info']['server']['default_domain'];
}
}
- $GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($login,$passwd,$passwd_type);
+ $GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($login, $passwd,
+ $passwd_type, false, true, true); // true = let session fail on forced password change
- if(!isset($GLOBALS['sessionid']) || ! $GLOBALS['sessionid'])
+ if (!$GLOBALS['sessionid'] && $GLOBALS['egw']->session->cd_reason == egw_session::CD_FORCE_PASSWORD_CHANGE)
+ {
+ if (isset($_POST['new_passwd']))
+ {
+ if (($errors = preferences_password::do_change($passwd, $_POST['new_passwd'], $_POST['new_passwd2'])))
+ {
+ $force_password_change = implode("\n", $errors);
+ }
+ else
+ {
+ $GLOBALS['sessionid'] = $GLOBALS['egw']->session->create($login,$_POST['new_passwd'],$passwd_type);
+ }
+ }
+ else
+ {
+ $force_password_change = $GLOBALS['egw']->session->reason;
+ }
+ }
+ if (isset($force_password_change))
+ {
+ // will show new login-screen incl. new password field below
+ }
+ elseif (!isset($GLOBALS['sessionid']) || ! $GLOBALS['sessionid'])
{
$GLOBALS['egw']->session->egw_setcookie('eGW_remember','',0,'/');
egw::redirect_link('/login.php?cd=' . $GLOBALS['egw']->session->cd_reason);
@@ -363,52 +388,49 @@ else
}
}
}
- else
+ // show login screen
+ if(isset($_COOKIE['last_loginid']))
{
- if(isset($_COOKIE['last_loginid']))
- {
- $accounts =& CreateObject('phpgwapi.accounts');
- $prefs =& CreateObject('phpgwapi.preferences', $accounts->name2id($_COOKIE['last_loginid']));
+ $prefs = new preferences($GLOBALS['egw']->accounts->name2id($_COOKIE['last_loginid']));
- if($prefs->account_id)
- {
- $GLOBALS['egw_info']['user']['preferences'] = $prefs->read_repository();
- }
- }
- if ($_GET['lang'] && preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_GET['lang']))
+ if($prefs->account_id)
{
- $GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $_GET['lang'];
+ $GLOBALS['egw_info']['user']['preferences'] = $prefs->read_repository();
}
- elseif(!isset($_COOKIE['last_loginid']) || !$prefs->account_id)
+ }
+ if ($_GET['lang'] && preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$_GET['lang']))
+ {
+ $GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $_GET['lang'];
+ }
+ elseif(!isset($_COOKIE['last_loginid']) || !$prefs->account_id)
+ {
+ // If the lastloginid cookies isn't set, we will default to the first language,
+ // the users browser accepts.
+ list($lang) = explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
+ if(strlen($lang) > 2)
{
- // If the lastloginid cookies isn't set, we will default to the first language,
- // the users browser accepts.
- list($lang) = explode(',',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
- if(strlen($lang) > 2)
- {
- $lang = substr($lang,0,2);
- }
- $GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $lang;
+ $lang = substr($lang,0,2);
}
- if ($_COOKIE['eGW_cookie_test'] !== 'enabled')
- {
- egw_session::egw_setcookie('eGW_cookie_test','enabled',0);
- }
- #print 'LANG:' . $GLOBALS['egw_info']['user']['preferences']['common']['lang'] . '
';
- translation::init(); // this will set the language according to the (new) set prefs
- translation::add_app('login');
- translation::add_app('loginscreen');
+ $GLOBALS['egw_info']['user']['preferences']['common']['lang'] = $lang;
+ }
+ if ($_COOKIE['eGW_cookie_test'] !== 'enabled')
+ {
+ egw_session::egw_setcookie('eGW_cookie_test','enabled',0);
+ }
+ #print 'LANG:' . $GLOBALS['egw_info']['user']['preferences']['common']['lang'] . '
';
+ translation::init(); // this will set the language according to the (new) set prefs
+ translation::add_app('login');
+ translation::add_app('loginscreen');
+ $GLOBALS['loginscreenmessage'] = translation::translate('loginscreen_message',false,'');
+ if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
+ {
+ translation::add_app('loginscreen','en'); // trying the en one
$GLOBALS['loginscreenmessage'] = translation::translate('loginscreen_message',false,'');
- if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
- {
- translation::add_app('loginscreen','en'); // trying the en one
- $GLOBALS['loginscreenmessage'] = translation::translate('loginscreen_message',false,'');
- }
- if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
- {
- // remove the global var since the lang loginscreen message and its fallback (en) is empty or not set
- unset($GLOBALS['loginscreenmessage']);
- }
+ }
+ if($GLOBALS['loginscreenmessage'] == 'loginscreen_message' || empty($GLOBALS['loginscreenmessage']))
+ {
+ // remove the global var since the lang loginscreen message and its fallback (en) is empty or not set
+ unset($GLOBALS['loginscreenmessage']);
}
foreach($_GET as $name => $value)
@@ -424,5 +446,5 @@ else
$extra_vars = '?' . substr($extra_vars,1);
}
- $GLOBALS['egw']->framework->login_screen($extra_vars);
+ $GLOBALS['egw']->framework->login_screen($extra_vars, $force_password_change);
}
diff --git a/phpgwapi/inc/class.auth.inc.php b/phpgwapi/inc/class.auth.inc.php
index d1044789e8..e10ea2251c 100644
--- a/phpgwapi/inc/class.auth.inc.php
+++ b/phpgwapi/inc/class.auth.inc.php
@@ -59,19 +59,19 @@ class auth
* check if users are supposed to change their password every x sdays, then check if password is of old age
* or the devil-admin reset the users password and forced the user to change his password on next login.
*
- * @param string $app to know where you are/ or where you want to go
- * @param string $class to know where you are/ or where you want to go
- * @param string $method to know where you are/ or where you want to go
- * @return boolean true if check determined, that you passed the test, otherwise void, as we get redirected
+ * @param string& $message =null on return false: message why password needs to be changed
+ * @return boolean true: all good, false: password change required, null: password expires in N days
*/
- static function check_password_age($app='', $class='', $method='')
+ static function check_password_change(&$message=null)
{
// dont check anything for anonymous sessions/ users that are flagged as anonymous
if (is_object($GLOBALS['egw']->session) && $GLOBALS['egw']->session->session_flags == 'A') return true;
+
// some statics (and initialisation to make information and timecalculation a) more readable in conditions b) persistent per request
// if user has to be warned about an upcomming passwordchange, remember for the session, that he was informed
static $UserKnowsAboutPwdChange=null;
if (is_null($UserKnowsAboutPwdChange)) $UserKnowsAboutPwdChange =& egw_cache::getSession('phpgwapi','auth_UserKnowsAboutPwdChange');
+
// retrieve the timestamp regarding the last change of the password from auth system and store it with the session
static $alpwchange_val=null;
static $pwdTsChecked=null;
@@ -87,7 +87,7 @@ class auth
// on the other side, if your auth system does not require an forcedPasswordChange, you will not be asked.
if (method_exists($backend,'getLastPwdChange'))
{
- $alpwchange_val = $backend->getLastPwdChange($GLOBALS['egw_info']['user']['account_lid']);
+ $alpwchange_val = $backend->getLastPwdChange($GLOBALS['egw']->session->account_lid);
$pwdTsChecked = true;
}
// if your authsystem does not provide that information, its likely, that you cannot change your password there,
@@ -101,19 +101,13 @@ class auth
}
static $passwordAgeBorder=null;
static $daysLeftUntilChangeReq=null;
- // some debug output and develop options to move the horizons and warn levels around
- //$GLOBALS['egw_info']['server']['change_pwd_every_x_days'] =35;
- //$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change']=5;
- //echo egw_time::to('now','ts').'
';
- //echo "User changed password at:".egw_time::to($GLOBALS['egw_info']['user'][$alpwchange]).'
';
- //echo "User password is ".((egw_time::to('now','ts')-$GLOBALS['egw_info']['user'][$alpwchange])/86400)." days old
";
- //echo "Users must change passwords every ".$GLOBALS['egw_info']['server']['change_pwd_every_x_days'].' days ('.($GLOBALS['egw_info']['server']['change_pwd_every_x_days']*86400).') seconds.
';
- //error_log(__METHOD__.__LINE__.'#'.$alpwchange_val.'# is null:'.is_null($alpwchange_val).'# is empty:'.empty($alpwchange_val).'# is set:'.isset($alpwchange_val));
- //echo egw_time::to('now','ts')-($GLOBALS['egw_info']['server']['change_pwd_every_x_days']*86400).'
';
+
// if neither timestamp isset return true, nothing to do (exept this means the password is too old)
if (is_null($alpwchange_val) &&
- empty($GLOBALS['egw_info']['server']['change_pwd_every_x_days'])
- ) return true;
+ empty($GLOBALS['egw_info']['server']['change_pwd_every_x_days']))
+ {
+ return true;
+ }
if (is_null($passwordAgeBorder) && $GLOBALS['egw_info']['server']['change_pwd_every_x_days'])
{
$passwordAgeBorder = (egw_time::to('now','ts')-($GLOBALS['egw_info']['server']['change_pwd_every_x_days']*86400));
@@ -123,60 +117,55 @@ class auth
// maxage - passwordage = days left until change is required
$daysLeftUntilChangeReq = ($GLOBALS['egw_info']['server']['change_pwd_every_x_days'] - ((egw_time::to('now','ts')-($alpwchange_val?$alpwchange_val:0))/86400));
}
- //echo "Warn about the upcomming change ".$GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'].' days before that time is reached
';
- //$result = $GLOBALS['egw_info']['server']['change_pwd_every_x_days'] - $daysLeftUntilChangeReq;
- //echo $GLOBALS['egw_info']['server']['change_pwd_every_x_days'].' - '.$daysLeftUntilChangeReq.'='. $result.'
';
- if (!($app == 'preferences' && $class == 'preferences_password' && $method == 'change') &&
- (
- ($GLOBALS['egw_info']['server']['change_pwd_every_x_days'] &&
- ($GLOBALS['egw_info']['user']['apps']['preferences'] || $GLOBALS['egw_info']['user']['apps']['password']) &&
- (
- ($passwordAgeBorder > $alpwchange_val) ||
- (
- $GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] &&
- $GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] > $daysLeftUntilChangeReq
- )
- )
- ) || $alpwchange_val==0
- )
- )
+ if ($alpwchange_val == 0 || // admin requested password change
+ $passwordAgeBorder > $alpwchange_val || // change password every N days policy requests change
+ // user should be warned N days in advance about change and is not yet
+ $GLOBALS['egw_info']['server']['change_pwd_every_x_days'] &&
+ $GLOBALS['egw_info']['user']['apps']['preferences'] &&
+ $GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] &&
+ $GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] > $daysLeftUntilChangeReq &&
+ $UserKnowsAboutPwdChange !== true)
{
- if ($GLOBALS['egw']->acl->check('nopasswordchange', 1, 'preferences')) return true; // user has no rights to change password
- if ($UserKnowsAboutPwdChange === true && !($passwordAgeBorder > $alpwchange_val || $alpwchange_val==0)) return true; // user has already been informed about the upcomming password expiration
- if (!is_null($alpwchange_val))
+ if ($alpwchange_val == 0)
{
- if ($alpwchange_val == 0)
- {
- $message = lang('an admin required that you must change your password upon login.');
- }
- elseif (($passwordAgeBorder < $alpwchange_val) ||
- (
- $GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] &&
- $GLOBALS['egw_info']['server']['warn_about_upcoming_pwd_change'] > $daysLeftUntilChangeReq &&
- $daysLeftUntilChangeReq > 0
- )
- )
+ $message = lang('An admin required that you must change your password upon login.');
+ }
+ elseif ($passwordAgeBorder > $alpwchange_val && $alpwchange_val > 0)
+ {
+ error_log(__METHOD__.' Password of '.$GLOBALS['egw_info']['user']['account_lid'].' ('.$GLOBALS['egw_info']['user']['account_fullname'].') is of old age.'.array2string(array(
+ 'ts'=> $alpwchange_val,
+ 'date'=>egw_time::to($alpwchange_val))));
+ $message = lang('It has been more then %1 days since you changed your password',$GLOBALS['egw_info']['server']['change_pwd_every_x_days']);
+ }
+ else
+ {
+ // login page does not inform user about passwords about to expire
+ if ($GLOBALS['egw_info']['flags']['currentapp'] != 'login' &&
+ ($GLOBALS['egw_info']['flags']['currentapp'] != 'home' ||
+ strpos($_SERVER['SCRIPT_NAME'], '/home/') !== false))
{
$UserKnowsAboutPwdChange = true;
- $message = lang('your password is about to expire in %1 days, you may change your password now',round($daysLeftUntilChangeReq));
}
- elseif ($passwordAgeBorder > $alpwchange_val && $alpwchange_val > 0)
- {
- error_log(__METHOD__.' Password of '.$GLOBALS['egw_info']['user']['account_lid'].' ('.$GLOBALS['egw_info']['user']['account_fullname'].') is of old age.'.array2string(array(
- 'ts'=> $alpwchange_val,
- 'date'=>egw_time::to($alpwchange_val))));
- $message = lang('it has been more then %1 days since you changed your password',$GLOBALS['egw_info']['server']['change_pwd_every_x_days']);
- }
- egw::redirect_link('/index.php',array(
- 'menuaction' => 'preferences.preferences_password.change',
- 'message' => $message,
- 'nopopup' => true,
- ));
+ $message = lang('Your password is about to expire in %1 days, you may change your password now',round($daysLeftUntilChangeReq));
+ // user has no rights to change password --> do NOT warn, as only forced check ignores rights
+ if ($GLOBALS['egw']->acl->check('nopasswordchange', 1, 'preferences')) return true;
+ return null;
}
+ return false;
}
return true;
}
+ /**
+ * Retired password check method called all over the place
+ *
+ * @deprecated use check_password_change
+ */
+ static function check_password_age()
+ {
+ return true; // no change
+ }
+
/**
* fetch the last pwd change for the user
*
@@ -234,7 +223,7 @@ class auth
}
if (($ret = $this->backend->change_password($old_passwd, $new_passwd, $account_id)))
{
- if ($account_id == $GLOBALS['egw_info']['user']['account_id'])
+ if ($account_id == $GLOBALS['egw']->session->account_id)
{
// need to change current users password in session
egw_cache::setSession('phpgwapi', 'password', base64_encode($new_passwd));
diff --git a/phpgwapi/inc/class.auth_sql.inc.php b/phpgwapi/inc/class.auth_sql.inc.php
index 288b1b537a..695cd08313 100644
--- a/phpgwapi/inc/class.auth_sql.inc.php
+++ b/phpgwapi/inc/class.auth_sql.inc.php
@@ -200,7 +200,7 @@ class auth_sql implements auth_backend
{
$admin = True;
// Don't allow password changes for other accounts when using XML-RPC
- if(!$account_id || $GLOBALS['egw_info']['flags']['currentapp'] == 'login')
+ if(!$account_id)
{
$admin = False;
$account_id = $GLOBALS['egw_info']['user']['account_id'];
diff --git a/phpgwapi/inc/class.egw_framework.inc.php b/phpgwapi/inc/class.egw_framework.inc.php
index 1477587096..730450f89e 100644
--- a/phpgwapi/inc/class.egw_framework.inc.php
+++ b/phpgwapi/inc/class.egw_framework.inc.php
@@ -572,11 +572,12 @@ abstract class egw_framework
abstract function footer();
/**
- * displays a login screen
- *
- * @param string $extra_vars for login url
+ * Displays the login screen
+ *
+ * @param string $extra_vars for login url
+ * @param string $change_passwd =null string with message to render input fields for password change
*/
- function login_screen($extra_vars)
+ function login_screen($extra_vars, $change_passwd=null)
{
self::csp_frame_src_attrs(array()); // array() no external frame-sources
@@ -587,8 +588,32 @@ abstract class egw_framework
$tmpl->set_var('lang_message',$GLOBALS['loginscreenmessage']);
- $last_loginid = $_COOKIE['last_loginid'];
-
+ // hide change-password fields, if not requested
+ if (!$change_passwd)
+ {
+ $tmpl->set_block('login_form','change_password');
+ $tmpl->set_var('change_password', '');
+ $tmpl->set_var('lang_password',lang('password'));
+ $tmpl->set_var('cd',check_logoutcode($_GET['cd']));
+ $tmpl->set_var('cd_class', isset($_GET['cd']) && $_GET['cd'] != 1 ? 'error' : '');
+ $last_loginid = $_COOKIE['last_loginid'];
+ $last_domain = $_COOKIE['last_domain'];
+ $tmpl->set_var('passwd', '');
+ $tmpl->set_var('autofocus_login', 'autofocus');
+ }
+ else
+ {
+ $tmpl->set_var('lang_password',lang('Old password'));
+ $tmpl->set_var('lang_new_password',lang('New password'));
+ $tmpl->set_var('lang_repeat_password',lang('Repeat password'));
+ $tmpl->set_var('cd', $change_passwd);
+ $tmpl->set_var('cd_class', 'error');
+ $last_loginid = $_POST['login'];
+ $last_domain = $_POST['domain'];
+ $tmpl->set_var('passwd', $_POST['passwd']);
+ $tmpl->set_var('autofocus_login', '');
+ $tmpl->set_var('autofocus_new_passwd', 'autofocus');
+ }
if($GLOBALS['egw_info']['server']['show_domain_selectbox'])
{
foreach(array_keys($GLOBALS['egw_domain']) as $domain)
@@ -597,7 +622,7 @@ abstract class egw_framework
}
$tmpl->set_var(array(
'lang_domain' => lang('domain'),
- 'select_domain' => html::select('logindomain',$_COOKIE['last_domain'],$domains,true,'tabindex="2"',0,false),
+ 'select_domain' => html::select('logindomain',$last_domain,$domains,true,'tabindex="2"',0,false),
));
}
else
@@ -612,9 +637,9 @@ abstract class egw_framework
reset($GLOBALS['egw_domain']);
list($default_domain) = each($GLOBALS['egw_domain']);
- if($_COOKIE['last_domain'] != $default_domain && !empty($_COOKIE['last_domain']))
+ if(!empty ($last_domain) && $last_domain != $default_domain)
{
- $last_loginid .= '@' . $_COOKIE['last_domain'];
+ $last_loginid .= '@' . $last_domain;
}
}
}
@@ -654,12 +679,10 @@ abstract class egw_framework
}
$tmpl->set_var('login_url', $GLOBALS['egw_info']['server']['webserver_url'] . '/login.php' . $extra_vars);
- $tmpl->set_var('version',$GLOBALS['egw_info']['server']['versions']['phpgwapi']);
- $tmpl->set_var('cd',check_logoutcode($_GET['cd']));
- $tmpl->set_var('cookie',$last_loginid);
+ $tmpl->set_var('version', $GLOBALS['egw_info']['server']['versions']['phpgwapi']);
+ $tmpl->set_var('login', $last_loginid);
$tmpl->set_var('lang_username',lang('username'));
- $tmpl->set_var('lang_password',lang('password'));
$tmpl->set_var('lang_login',lang('login'));
$tmpl->set_var('website_title', $GLOBALS['egw_info']['server']['site_title']);
@@ -825,6 +848,14 @@ abstract class egw_framework
*/
protected function _get_header(array $extra=array())
{
+ // display password expires in N days message once per session
+ $message = null;
+ if ($GLOBALS['egw_info']['flags']['currentapp'] != 'login' &&
+ auth::check_password_change($message) !== true)
+ {
+ self::message($message, 'info');
+ }
+
// get used language code (with a little xss check, if someone tries to sneak something in)
if (preg_match('/^[a-z]{2}(-[a-z]{2})?$/',$GLOBALS['egw_info']['user']['preferences']['common']['lang']))
{
diff --git a/phpgwapi/inc/class.egw_session.inc.php b/phpgwapi/inc/class.egw_session.inc.php
index 5449be0914..1cab173efb 100644
--- a/phpgwapi/inc/class.egw_session.inc.php
+++ b/phpgwapi/inc/class.egw_session.inc.php
@@ -166,6 +166,24 @@ class egw_session
*/
var $required_files;
+ /**
+ * Nummeric code why session creation failed
+ *
+ * @var int
+ */
+ var $cd_reason;
+ const CD_BAD_LOGIN_OR_PASSWORD = 5;
+ const CD_FORCE_PASSWORD_CHANGE = 97;
+ const CD_ACCOUNT_EXPIRED = 98;
+ const CD_BLOCKED = 99; // to many failed attempts to loing
+
+ /**
+ * Verbose reason why session creation failed
+ *
+ * @var string
+ */
+ var $reason;
+
/**
* Constructor just loads up some defaults from cookies
*
@@ -422,9 +440,10 @@ class egw_session
* @param string $passwd_type type of password being used, ie plaintext, md5, sha1
* @param boolean $no_session =false dont create a real session, eg. for GroupDAV clients using only basic auth, no cookie support
* @param boolean $auth_check =true if false, the user is loged in without checking his password (eg. for single sign on), default = true
+ * @param boolean $fail_on_forced_password_change =false true: do NOT create session, if password change requested
* @return string session id
*/
- function create($login,$passwd = '',$passwd_type = '',$no_session=false,$auth_check=true)
+ function create($login,$passwd = '',$passwd_type = '',$no_session=false,$auth_check=true,$fail_on_forced_password_change=false)
{
if (is_array($login))
{
@@ -492,7 +511,7 @@ class egw_session
$this->account_id && $GLOBALS['egw']->accounts->get_type($this->account_id) == 'g')
{
$this->reason = $blocked ? 'blocked, too many attempts' : 'bad login or password';
- $this->cd_reason = $blocked ? 99 : 5;
+ $this->cd_reason = $blocked ? self::CD_BLOCKED : self::CD_BAD_LOGIN_OR_PASSWORD;
// we dont log anon users as it would block the website
if (!$GLOBALS['egw']->acl->get_specific_rights_for_account($this->account_id,'anonymous','phpgwapi'))
@@ -502,6 +521,11 @@ class egw_session
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__."($this->login,$this->passwd,$this->passwd_type,$no_session,$auth_check) UNSUCCESSFULL ($this->reason)");
return false;
}
+ if ($fail_on_forced_password_change && auth::check_password_change($this->reason) === false)
+ {
+ $this->cd_reason = self::CD_FORCE_PASSWORD_CHANGE;
+ return false;
+ }
if (!$this->account_id && $GLOBALS['egw_info']['server']['auto_create_acct'])
{
if ($GLOBALS['egw_info']['server']['auto_create_acct'] == 'lowercase')
@@ -543,7 +567,7 @@ class egw_session
if ($GLOBALS['egw']->accounts->is_expired($GLOBALS['egw_info']['user']))
{
$this->reason = 'account is expired';
- $this->cd_reason = 98;
+ $this->cd_reason = self::CD_ACCOUNT_EXPIRED;
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__."($this->login,$this->passwd,$this->passwd_type,$no_session,$auth_check) UNSUCCESSFULL ($this->reason)");
return false;
diff --git a/phpgwapi/lang/egw_de.lang b/phpgwapi/lang/egw_de.lang
index d16dad7a1b..ccf087bb8b 100644
--- a/phpgwapi/lang/egw_de.lang
+++ b/phpgwapi/lang/egw_de.lang
@@ -70,7 +70,7 @@ alphabet common de a,ä,b,c,d,e,f,g,h,i,j,k,l,m,n,o,ö,p,q,r,s,t,u,ü,v,w,x,y,z
alt common de Alt
alternate style-sheet: common de Alternatives Style-sheet
american samoa common de AMERICANISCH SAMOA
-an admin required that you must change your password upon login. common de Sie werden hiermit aufgefordert Ihr Passwort zu ändern. (Dies wurde von einem Administrator veranlasst.)
+an admin required that you must change your password upon login. common de Sie werden hiermit aufgefordert Ihr Passwort zu ändern. Dies wurde von einem Administrator veranlasst.
an error happened common de Ein Fehler ist aufgetreten.
an existing and by the webserver readable directory enables the image browser and upload. common de Ein existierendes, und vom Webserver lesbares Verzeichnis, schaltet den Bild Browser und Upload ein.
and common de und
@@ -940,7 +940,7 @@ your message has been sent common de Ihre Nachricht wurde versendet
your password does not have required strength of %1 character classes and minimum length of %2 characters. common de Ihr Passwort hat nicht die benötigte Qualität von %1 Zeichenklassen und Mindestanzahl von %2 Zeichen.
your password does not have required strength: common de Ihr Passwort hat nicht die erforderliche Stärke:
your password failed the following criteria: common de Ihr Passwort entspricht nicht den folgenden Kriterien:
-your password is about to expire in %1 days, you may change your password now common de Ihr Passwort läuft in %1 Tagen ab. Sie können nun hier Ihr Passwort ändern, oder warten bis Sie es ändern müssen.
+your password is about to expire in %1 days, you may change your password now common de Ihr Passwort läuft in %1 Tagen ab. Sie können jetzt Ihr Passwort ändern, oder warten bis Sie es ändern müssen.
your password might not match the password policy. common de Ihr Passwort könnte den Richtlinien nicht entsprechen.
your search returned %1 matchs common de Ihre Suche ergab %1 Treffer
your search returned 1 match common de Ihre Suche ergab einen Treffer
diff --git a/phpgwapi/templates/default/login.tpl b/phpgwapi/templates/default/login.tpl
index 3b40c26d41..723a8ae38f 100644
--- a/phpgwapi/templates/default/login.tpl
+++ b/phpgwapi/templates/default/login.tpl
@@ -5,12 +5,16 @@