From c340daef871482f83a1746f50c98df6c61e6aeab Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 15 Jan 2012 19:34:14 +0000 Subject: [PATCH] allow to force password change in password dialog --- lam/help/help.inc | 2 ++ lam/lib/modules.inc | 35 +++++++++++++++++++++------ lam/lib/modules/asteriskAccount.inc | 12 ++++++++- lam/lib/modules/asteriskVoicemail.inc | 14 +++++++++-- lam/lib/modules/inetOrgPerson.inc | 12 ++++++++- lam/lib/modules/phpGroupwareUser.inc | 14 +++++++++-- lam/lib/modules/posixAccount.inc | 12 ++++++++- lam/lib/modules/posixGroup.inc | 14 +++++++++-- lam/lib/modules/sambaSamAccount.inc | 19 ++++++++++++--- lam/lib/modules/shadowAccount.inc | 17 +++++++++++-- lam/templates/lib/500_lam.js | 7 +++++- 11 files changed, 136 insertions(+), 22 deletions(-) diff --git a/lam/help/help.inc b/lam/help/help.inc index b18da6c1..3bd72517 100644 --- a/lam/help/help.inc +++ b/lam/help/help.inc @@ -167,6 +167,8 @@ $helpArray = array ( "Text" => _("Please enter the password which you want to set for this account. You may also generate a random password (12 characters) which will be displayed on your screen.")), "405" => array ("Headline" => _("PDF structure"), "Text" => _("The PDF structure defines what information is exported as PDF file and how the pages are structured. You can manage the PDF structures in the PDF editor (under \"Tools\").")), + "406" => array ("Headline" => _("Force password change"), + "Text" => _("If you set this option then the user has to change his password at the next login.")), // 500 - 599 // LAM Pro "501" => array ("Headline" => _("LDAP suffix"), diff --git a/lam/lib/modules.inc b/lam/lib/modules.inc index 1019261b..a75b55df 100644 --- a/lam/lib/modules.inc +++ b/lam/lib/modules.inc @@ -3,7 +3,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2003 - 2011 Roland Gruber + Copyright (C) 2003 - 2012 Roland Gruber 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 @@ -983,6 +983,18 @@ class accountContainer { $pwdInput2 = new htmlInputField('newPassword2'); $pwdInput2->setIsPassword(true); $container->addElement($pwdInput2, true); + // print force password change option + $forceChangeSupported = false; + foreach ($this->module as $name => $module) { + if (($module instanceof passwordService) && $module->supportsForcePasswordChange()) { + $forceChangeSupported = true; + break; + } + } + if ($forceChangeSupported) { + $container->addElement(new htmlTableExtendedInputCheckbox('lamForcePasswordChange', false, _('Force password change'))); + $container->addElement(new htmlHelpLink('406'), true); + } $container->addElement(new htmlSpacer(null, '10px'), true); // password modules $moduleContainer = new htmlTable(); @@ -1000,7 +1012,6 @@ class accountContainer { } $moduleContainer->colspan = 5; $container->addElement($moduleContainer, true); - $container->addElement(new htmlSpacer(null, '10px'), true); // generate HTML $tabindex = 2000; if ($printContainer) { @@ -1043,11 +1054,13 @@ class accountContainer { $return['errorsOccured'] = 'true'; } } + $forcePasswordChange = ($input['forcePasswordChange'] == 'true'); + $return['forcePasswordChange'] = $forcePasswordChange; if ($return['errorsOccured'] == 'false') { // set new password foreach ($this->module as $name => $module) { if ($module instanceof passwordService) { - $messages = $module->passwordChangeRequested($password1, $modules); + $messages = $module->passwordChangeRequested($password1, $modules, $forcePasswordChange); for ($m = 0; $m < sizeof($messages); $m++) { if ($messages[$m][0] == 'ERROR') { $return['errorsOccured'] = 'true'; @@ -1920,18 +1933,26 @@ interface passwordService { * @return boolean true if this module manages password attributes */ public function managesPasswordAttributes(); - + + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange(); + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password - * @param $modules list of modules for which the password should be changed + * @param array $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) */ - public function passwordChangeRequested($password, $modules); - + public function passwordChangeRequested($password, $modules, $forcePasswordChange); + } ?> diff --git a/lam/lib/modules/asteriskAccount.inc b/lam/lib/modules/asteriskAccount.inc index 8d732e54..36b2f1f1 100644 --- a/lam/lib/modules/asteriskAccount.inc +++ b/lam/lib/modules/asteriskAccount.inc @@ -1509,17 +1509,27 @@ class asteriskAccount extends baseModule implements passwordService { return true; } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return false; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { if (!in_array(get_class($this), $modules)) { return array(); } diff --git a/lam/lib/modules/asteriskVoicemail.inc b/lam/lib/modules/asteriskVoicemail.inc index f2b78203..6ac3d4e6 100644 --- a/lam/lib/modules/asteriskVoicemail.inc +++ b/lam/lib/modules/asteriskVoicemail.inc @@ -4,7 +4,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam) Copyright (C) 2010 Pavel Pozdnyak - 2010 - 2011 Roland Gruber + 2010 - 2012 Roland Gruber 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 @@ -546,17 +546,27 @@ class asteriskVoicemail extends baseModule implements passwordService { return true; } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return false; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { if (!in_array(get_class($this), $modules)) { return array(); } diff --git a/lam/lib/modules/inetOrgPerson.inc b/lam/lib/modules/inetOrgPerson.inc index 22699b07..0f9082c6 100644 --- a/lam/lib/modules/inetOrgPerson.inc +++ b/lam/lib/modules/inetOrgPerson.inc @@ -2940,17 +2940,27 @@ class inetOrgPerson extends baseModule implements passwordService { return false; } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return false; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { if (!in_array(get_class($this), $modules)) { return array(); } diff --git a/lam/lib/modules/phpGroupwareUser.inc b/lam/lib/modules/phpGroupwareUser.inc index 9a21b0c2..73aab630 100644 --- a/lam/lib/modules/phpGroupwareUser.inc +++ b/lam/lib/modules/phpGroupwareUser.inc @@ -3,7 +3,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) - Copyright (C) 2008 - 2011 Roland Gruber + Copyright (C) 2008 - 2012 Roland Gruber 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 @@ -429,17 +429,27 @@ class phpGroupwareUser extends baseModule implements passwordService { return false; } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return false; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { // update password timestamp when Unix password was updated if (!in_array('posixAccount', $modules)) { return array(); diff --git a/lam/lib/modules/posixAccount.inc b/lam/lib/modules/posixAccount.inc index e27bc797..9bd5b5b3 100644 --- a/lam/lib/modules/posixAccount.inc +++ b/lam/lib/modules/posixAccount.inc @@ -2174,17 +2174,27 @@ class posixAccount extends baseModule implements passwordService { return true; } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return false; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { if (!in_array(get_class($this), $modules)) { return array(); } diff --git a/lam/lib/modules/posixGroup.inc b/lam/lib/modules/posixGroup.inc index 67302b2e..a1e38e45 100644 --- a/lam/lib/modules/posixGroup.inc +++ b/lam/lib/modules/posixGroup.inc @@ -4,7 +4,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) Copyright (C) 2003 - 2006 Tilo Lutz - 2007 - 2010 Roland Gruber + 2007 - 2012 Roland Gruber 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 @@ -777,17 +777,27 @@ class posixGroup extends baseModule implements passwordService { return true; } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return false; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { if (!in_array(get_class($this), $modules)) { return array(); } diff --git a/lam/lib/modules/sambaSamAccount.inc b/lam/lib/modules/sambaSamAccount.inc index 2799acd5..9db13b3e 100644 --- a/lam/lib/modules/sambaSamAccount.inc +++ b/lam/lib/modules/sambaSamAccount.inc @@ -860,7 +860,7 @@ class sambaSamAccount extends baseModule implements passwordService { $this->attributes['sambaSID'][0] = $SID."-". (($attrs['uidNumber'][0]*2)+$RIDbase); } } - if (isset($_POST['passwordIsExpired'])) { + if (isset($_POST['forcePasswordChangeOption'])) { $this->expirePassword = true; } else { @@ -1099,7 +1099,7 @@ class sambaSamAccount extends baseModule implements passwordService { } $return->addElement(new htmlTableExtendedInputCheckbox('sambaAcctFlagsL', $locked, _('Account is locked'), 'locked'), true); // password change at next login - $return->addElement(new htmlTableExtendedInputCheckbox('passwordIsExpired', $this->expirePassword, _('Password change at next login'), 'passwordIsExpired'), true); + $return->addElement(new htmlTableExtendedInputCheckbox('forcePasswordChangeOption', $this->expirePassword, _('Password change at next login'), 'passwordIsExpired'), true); // password can be changed $return->addElement(new htmlOutputText(_('User can change password'))); $tempTable = new htmlTable(); @@ -2139,17 +2139,27 @@ class sambaSamAccount extends baseModule implements passwordService { } } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return true; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { if (!in_array(get_class($this), $modules)) { return array(); } @@ -2158,6 +2168,9 @@ class sambaSamAccount extends baseModule implements passwordService { } $this->attributes['sambaNTPassword'][0] = ntPassword($password); $this->attributes['sambaPwdLastSet'][0] = time(); + if ($forcePasswordChange) { + $this->attributes['sambaPwdLastSet'][0] = '0'; + } return array(); } diff --git a/lam/lib/modules/shadowAccount.inc b/lam/lib/modules/shadowAccount.inc index be04f5ab..b0f42d7e 100644 --- a/lam/lib/modules/shadowAccount.inc +++ b/lam/lib/modules/shadowAccount.inc @@ -4,7 +4,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) Copyright (C) 2003 - 2006 Tilo Lutz - Copyright (C) 2007 - 2011 Roland Gruber + Copyright (C) 2007 - 2012 Roland Gruber 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 @@ -592,23 +592,36 @@ class shadowAccount extends baseModule implements passwordService { return false; } + /** + * Specifies if this module supports to force that a user must change his password on next login. + * + * @return boolean force password change supported + */ + public function supportsForcePasswordChange() { + return true; + } + /** * This function is called whenever the password should be changed. Account modules * must change their password attributes only if the modules list contains their module name. * * @param String $password new password * @param $modules list of modules for which the password should be changed + * @param boolean $forcePasswordChange force the user to change his password at next login * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) * @see passwordService::passwordChangeRequested */ - public function passwordChangeRequested($password, $modules) { + public function passwordChangeRequested($password, $modules, $forcePasswordChange) { // update password timestamp when Unix password was updated if (!in_array('posixAccount', $modules)) { return array(); } if (in_array_ignore_case('shadowAccount', $this->attributes['objectClass'])) { $this->attributes['shadowLastChange'][0] = intval(time()/3600/24); + if ($forcePasswordChange && isset($this->attributes['shadowMax'][0]) && ($this->attributes['shadowMax'][0] != 0)) { + $this->attributes['shadowLastChange'][0] = intval(time()/3600/24) - $this->attributes['shadowMax'][0] - 1; + } } return array(); } diff --git a/lam/templates/lib/500_lam.js b/lam/templates/lib/500_lam.js index cabf9979..b3f58572 100644 --- a/lam/templates/lib/500_lam.js +++ b/lam/templates/lib/500_lam.js @@ -263,11 +263,13 @@ function passwordHandleInput(random, ajaxURL) { }); var pwd1 = jQuery('#passwordDialog').find('[name=newPassword1]').val(); var pwd2 = jQuery('#passwordDialog').find('[name=newPassword2]').val(); + var forcePasswordChange = jQuery('input[name=lamForcePasswordChange]').attr('checked'); var pwdJSON = { "modules": modules, "password1": pwd1, "password2": pwd2, - "random": random + "random": random, + "forcePasswordChange": forcePasswordChange }; // make AJAX call jQuery.post(ajaxURL, {jsonInput: pwdJSON}, function(data) {passwordHandleReply(data);}, 'json'); @@ -283,6 +285,9 @@ function passwordHandleReply(data) { jQuery('#passwordDialogMessageArea').html(""); jQuery('#passwordDialog').dialog("close"); jQuery('#passwordMessageArea').html(data.messages); + if (data.forcePasswordChange) { + jQuery('#forcePasswordChangeOption').attr('checked', 'checked'); + } } else { jQuery('#passwordDialogMessageArea').html(data.messages);