From 234766d2515726903052aaa8ed6dd0c17fc4911b Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Fri, 9 Oct 2009 18:21:12 +0000 Subject: [PATCH] added central password service --- lam/lib/modules.inc | 14 ++- lam/lib/modules/posixAccount.inc | 131 +++++----------------------- lam/lib/modules/sambaSamAccount.inc | 74 +++------------- lam/lib/modules/shadowAccount.inc | 46 +++++++--- 4 files changed, 81 insertions(+), 184 deletions(-) diff --git a/lam/lib/modules.inc b/lam/lib/modules.inc index d442041b..c3ea2388 100644 --- a/lam/lib/modules.inc +++ b/lam/lib/modules.inc @@ -1288,10 +1288,16 @@ class accountContainer { } } // set new password + $selectedModules = array(); foreach ($_POST as $key => $value) { if (substr($key, 0, 3) == 'cb_') { $name = substr($key, 3); - $return = array_merge($return, $this->module[$name]->passwordChanged($_POST['newPassword1'])); + $selectedModules[] = $name; + } + } + foreach ($this->module as $name => $module) { + if ($module instanceof passwordService) { + $return = array_merge($return, $module->passwordChangeRequested($_POST['newPassword1'], $selectedModules)); } } return $return; @@ -2092,13 +2098,15 @@ interface passwordService { public function managesPasswordAttributes(); /** - * This function is called whenever the password of this module should be changed. + * 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 * @return array list of error messages if any as parameter array for StatusMessage * e.g. return arrray(array('ERROR', 'Password change failed.')) */ - public function passwordChanged($password); + public function passwordChangeRequested($password, $modules); } diff --git a/lam/lib/modules/posixAccount.inc b/lam/lib/modules/posixAccount.inc index 8c16c956..6594a017 100644 --- a/lam/lib/modules/posixAccount.inc +++ b/lam/lib/modules/posixAccount.inc @@ -4,7 +4,7 @@ This code is part of LDAP Account Manager (http://www.sourceforge.net/projects/lam) Copyright (C) 2003 - 2006 Tilo Lutz - Copyright (C) 2005 - 2007 Roland Gruber + Copyright (C) 2005 - 2009 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 @@ -46,7 +46,6 @@ class posixAccount extends baseModule implements passwordService { private $groups_orig; private $createhomedir; private $lamdaemonServer; - private $clearTextPassword; /** * This function fills the error message array with messages. @@ -69,8 +68,6 @@ class posixAccount extends baseModule implements passwordService { $this->messages['uidNumber'][3] = array('ERROR', _('ID-Number'), _('ID is already in use')); $this->messages['uidNumber'][4] = array('ERROR', _('Account %s:') . ' posixAccount_uid', _('UID must be a number. It has to be inside the UID range which is defined in your configuration profile.')); $this->messages['uidNumber'][5] = array('INFO', _('UID number'), _('UID number has changed. To keep file ownership you have to run the following command as root: \'find / -uid %s -exec chown %s {} \;\'')); - $this->messages['userPassword'][0] = array('ERROR', _('Password'), _('Please enter the same password in both password fields.')); - $this->messages['userPassword'][1] = array('ERROR', _('Password'), _('Password contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and #*,.;:_-+!%&/|?{[()]}=@$ !')); $this->messages['userPassword'][4] = array('ERROR', _('Account %s:') . ' posixAccount_password', _('Password contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and #*,.;:_-+!%&/|?{[()]}=@$ !')); $this->messages['uid'][0] = array('INFO', _('UID'), _('UID has changed. Do you want to change home directory?')); $this->messages['uid'][1] = array('WARN', _('User name'), _('You are using a capital letters. This can cause problems because windows isn\'t case-sensitive.')); @@ -323,7 +320,6 @@ class posixAccount extends baseModule implements passwordService { 'primaryGroup', 'additionalGroups', 'homeDirectory', - 'userPassword', 'loginShell', 'cn' ); @@ -907,42 +903,6 @@ class posixAccount extends baseModule implements passwordService { return array(); } - /** - * Processes user input of the password page. - * It checks if all input values are correct and updates the associated LDAP attributes. - * - * @return array list of info/error messages - */ - function process_password() { - if ($_POST['form_subpage_posixAccount_attributes_back']) return array(); - else if ($_POST['form_subpage_posixAccount_attributes_randomPassword']) { - $pwd = generateRandomPassword(); - $this->clearTextPassword = $pwd; - $this->attributes['userPassword'][0] = pwd_hash($pwd, true, $this->moduleSettings['posixAccount_pwdHash'][0]); - return array(array('INFO', _('The password was set to:') . ' ' . $pwd)); - } - $errors = array(); - if ($_POST['userPassword'] != $_POST['userPassword2']) { - $errors[] = $this->messages['userPassword'][0]; - } - else { - if (!get_preg($_POST['userPassword'], 'password')) { - $errors[] = $this->messages['userPassword'][1]; - } - else { - $pwdPolicyResult = checkPasswordStrength($_POST['userPassword']); - if ($pwdPolicyResult === true) { - $this->clearTextPassword = $_POST['userPassword']; - $this->attributes['userPassword'][0] = pwd_hash($_POST['userPassword'], true, $this->moduleSettings['posixAccount_pwdHash'][0]); - } - else { - $errors[] = array('ERROR', $pwdPolicyResult); - } - } - } - return $errors; - } - /** * Returns the HTML meta data for the main account page. * @@ -1022,30 +982,20 @@ class posixAccount extends baseModule implements passwordService { array('kind' => 'help', 'value' => 'loginShell')); } } - if (!isset($this->attributes['userPassword'][0])) { - $return[] = array( - array('kind' => 'text', 'text' => _('Password') ), - array('kind' => 'input', 'name' => 'form_subpage_posixAccount_password_open', 'type' => 'submit', 'value' => _('Set password'))); + if (pwd_is_enabled($this->attributes['userPassword'][0])) { + $lockOption = array('kind' => 'input', 'name' => 'form_subpage_posixAccount_attributes_lockPassword', 'type' => 'submit', 'value' => _('Lock password')); } else { - if (pwd_is_enabled($this->attributes['userPassword'][0])) { - $lockOption = array('kind' => 'input', 'name' => 'form_subpage_posixAccount_attributes_lockPassword', 'type' => 'submit', 'value' => _('Lock password')); - } - else { - $lockOption = array('kind' => 'input', 'name' => 'form_subpage_posixAccount_attributes_unlockPassword', 'type' => 'submit', 'value' => _('Unlock password')); - } - $return[] = array( - array('kind' => 'text', 'text' => _('Password') ), - array('kind' => 'table', 'value' => array( - array( - array('kind' => 'input', 'name' => 'form_subpage_posixAccount_password_open', 'type' => 'submit', 'value' => _('Change password')) - ), - array($lockOption), - array( - array('kind' => 'input', 'name' => 'form_subpage_posixAccount_attributes_removePassword', 'type' => 'submit', 'value' => _('Remove password')) - ) - ))); + $lockOption = array('kind' => 'input', 'name' => 'form_subpage_posixAccount_attributes_unlockPassword', 'type' => 'submit', 'value' => _('Unlock password')); } + $return[] = array( + array('kind' => 'text', 'text' => _('Password') ), + array('kind' => 'table', 'value' => array( + array($lockOption), + array( + array('kind' => 'input', 'name' => 'form_subpage_posixAccount_attributes_removePassword', 'type' => 'submit', 'value' => _('Remove password')) + ) + ))); return $return; } @@ -1109,37 +1059,6 @@ class posixAccount extends baseModule implements passwordService { return $return; } - /** - * Displays the password changing dialog. - * - * @return array meta HTML code - */ - function display_html_password() { - $return[] = array( - array('kind' => 'text', 'text' => _('Password') ), - array('kind' => 'input', 'name' => 'userPassword', 'type' => 'password', 'size' => '20', 'maxlength' => '255', 'value' => ""), - array('kind' => 'help', 'value' => 'userPassword')); - $return[] = array( - array('kind' => 'text', 'text' => _('Repeat password')), - array('kind' => 'input', 'name' => 'userPassword2', 'type' => 'password', 'size' => '20', 'maxlength' => '255', 'value' => "")); - $return[] = array( - array('kind' => 'text', 'text' => ' ') - ); - $return[] = array( - array('kind' => 'text', 'text' => ' ') - ); - $return[] = array( - array('kind' => 'table', 'value' => array( - array( - array('kind' => 'input', 'type' => 'submit', 'value' => _('Ok'), 'name' => 'form_subpage_posixAccount_attributes_submit'), - array('kind' => 'input', 'type' => 'submit', 'value' => _('Cancel'), 'name' => 'form_subpage_posixAccount_attributes_back'), - array('kind' => 'text')))), - array('kind' => 'input', 'type' => 'submit', 'value' => _('Set random password'), - 'name' => 'form_subpage_posixAccount_attributes_randomPassword', 'td' => array('align' => 'right', 'colspan' => 2)) - ); - return $return; - } - /** * Returns a list of elements for the account profiles. * @@ -1247,9 +1166,6 @@ class posixAccount extends baseModule implements passwordService { 'posixAccount_homeDirectory' => array('' . _('Home directory') . '' . $this->attributes['homeDirectory'][0] . ''), 'posixAccount_loginShell' => array('' . _('Login shell') . '' . $this->attributes['loginShell'][0] . ''), ); - if (isset($this->clearTextPassword)) { - $return['posixAccount_userPassword'] = array('' . _('Password') . '' . $this->clearTextPassword . ''); - } return $return; } @@ -1811,15 +1727,6 @@ class posixAccount extends baseModule implements passwordService { return $return; } - /** - * Returns the clear text password. - * - * @return string password - */ - public function getClearTextPassword() { - return $this->clearTextPassword; - } - /** * This method specifies if a module manages password attributes. * @see passwordService::managesPasswordAttributes @@ -1831,14 +1738,20 @@ class posixAccount extends baseModule implements passwordService { } /** - * This function is called whenever the password of this module should be changed. - * @see passwordService::managesPasswordAttributes - * + * 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 * @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 passwordChanged($password) { + public function passwordChangeRequested($password, $modules) { + if (!in_array(get_class($this), $modules)) { + return array(); + } + $this->attributes['userPassword'][0] = pwd_hash($password, true, $this->moduleSettings['posixAccount_pwdHash'][0]); return array(); } diff --git a/lam/lib/modules/sambaSamAccount.inc b/lam/lib/modules/sambaSamAccount.inc index d67644bf..cf018461 100644 --- a/lam/lib/modules/sambaSamAccount.inc +++ b/lam/lib/modules/sambaSamAccount.inc @@ -42,8 +42,6 @@ include_once('sambaSamAccount/sambaMungedDial.inc'); class sambaSamAccount extends baseModule implements passwordService { // Variables - /** use Unix password as samba password? */ - private $useunixpwd; /** use no password? */ private $nopwd; /** password does not expire? */ @@ -91,8 +89,6 @@ class sambaSamAccount extends baseModule implements passwordService { $this->messages['logonScript'][2] = array('ERROR', _('Account %s:') . ' sambaSamAccount_logonScript', _('Logon script is invalid!')); $this->messages['workstations'][0] = array('ERROR', _('Samba workstations'), _('Please enter a comma separated list of host names!')); $this->messages['workstations'][1] = array('ERROR', _('Account %s:') . ' sambaSamAccount_workstations', _('Please enter a comma separated list of host names!')); - $this->messages['sambaLMPassword'][0] = array('ERROR', _('Password'), _('Please enter the same password in both password-fields.')); - $this->messages['sambaLMPassword'][1] = array('ERROR', _('Password'), _('Password contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and #*,.;:_-+!%&/|?{[()]}=@$ !')); $this->messages['sambaLMPassword'][2] = array('ERROR', _('Account %s:') . ' sambaSamAccount_password', _('Password contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and #*,.;:_-+!%&/|?{[()]}=@$ !')); $this->messages['rid'][2] = array('ERROR', _('Account %s:') . ' sambaSamAccount_rid', _('Please enter a RID number or the name of a special account!')); $this->messages['rid'][3] = array('ERROR', _('Account %s:') . ' sambaSamAccount_rid', _('This is not a valid RID number!')); @@ -630,7 +626,6 @@ class sambaSamAccount extends baseModule implements passwordService { function init($base) { // call parent init parent::init($base); - $this->useunixpwd = true; $this->noexpire = true; $this->nopwd = false; $this->deactivated = false; @@ -862,31 +857,6 @@ class sambaSamAccount extends baseModule implements passwordService { } } - if (isset($_POST['useunixpwd'])) { - $this->useunixpwd = true; - if (isset($this->moduleSettings['sambaSamAccount_lmHash'][0]) && ($this->moduleSettings['sambaSamAccount_lmHash'][0] == 'no')) { - $this->attributes['sambaLMPassword'][0] = lmPassword($this->getAccountContainer()->getAccountModule('posixAccount')->getClearTextPassword()); - } - $this->attributes['sambaNTPassword'][0] = ntPassword($this->getAccountContainer()->getAccountModule('posixAccount')->getClearTextPassword()); - $this->attributes['sambaPwdLastSet'][0] = time(); - } - else $this->useunixpwd = false; - if (!$this->useunixpwd && isset($_POST['sambaLMPassword']) && ($_POST['sambaLMPassword'] != '')) { - if ($_POST['sambaLMPassword'] != $_POST['sambaLMPassword2']) { - $errors[] = $this->messages['sambaLMPassword'][0]; - unset ($_POST['sambaLMPassword2']); - } - else { - if (!get_preg($_POST['sambaLMPassword'], 'password')) $errors[] = $this->messages['sambaLMPassword'][1]; - else { - if (isset($this->moduleSettings['sambaSamAccount_lmHash'][0]) && ($this->moduleSettings['sambaSamAccount_lmHash'][0] == 'no')) { - $this->attributes['sambaLMPassword'][0] = lmPassword($_POST['sambaLMPassword']); - } - $this->attributes['sambaNTPassword'][0] = ntPassword($_POST['sambaLMPassword']); - $this->attributes['sambaPwdLastSet'][0] = time(); - } - } - } $specialRids = array_flip($this->rids); // set special RID if selected if (in_array($_POST['sambaSID'], $specialRids)) { @@ -1119,19 +1089,6 @@ class sambaSamAccount extends baseModule implements passwordService { if ($this->get_scope()=='user') { $return[] = array( array('kind' => 'input', 'name' => 'sambaAcctFlagsU', 'type' => 'hidden', 'value' => 'true')); - $return[] = array( - array('kind' => 'text', 'text' => _('Samba password')), - array('kind' => 'input', 'name' => 'sambaLMPassword', 'type' => 'password', 'size' => '20', 'maxlength' => '255'), - array('kind' => 'help', 'value' => 'password')); - $return[] = array( - array('kind' => 'text', 'text' => _('Repeat password')), - array('kind' => 'input', 'name' => 'sambaLMPassword2', 'type' => 'password', 'size' => '20', 'maxlength' => '255')); - if ($this->getAccountContainer()->getAccountModule('posixAccount')->getClearTextPassword() != null) { - $return[] = array( - array('kind' => 'text', 'text' => _('Use Unix password') ), - array('kind' => 'input', 'name' => 'useunixpwd', 'type' => 'checkbox', 'checked' => $this->useunixpwd), - array('kind' => 'help', 'value' => 'useunixpwd')); - } $return[] = array( array('kind' => 'text', 'text' => _('Use no password') ), array('kind' => 'input', 'name' => 'sambaAcctFlagsN', 'type' => 'checkbox', 'checked' => $this->nopwd), @@ -1614,12 +1571,6 @@ class sambaSamAccount extends baseModule implements passwordService { for ( $i=1; $i<=31; $i++ ) $day[] = $i; for ( $i=1; $i<=12; $i++ ) $mon[] = $i; for ( $i=2003; $i<=2030; $i++ ) $year[] = $i; - // use Unix password as Samba password - $return[] = array( - array('kind' => 'text', 'text' => _('Use Unix password') . ': '), - array('kind' => 'input', 'name' => 'sambaSamAccount_useunixpwd', 'type' => 'checkbox', 'checked' => true), - array('kind' => 'help', 'value' => 'pwdunix') - ); // use no password at all $return[] = array( array('kind' => 'text', 'text' => _('Use no password') . ': '), @@ -1757,13 +1708,6 @@ class sambaSamAccount extends baseModule implements passwordService { // profile mappings in meta data parent::load_profile($profile); // special profile options - // use Unix password - if ($profile['sambaSamAccount_useunixpwd'][0] == "true") { - $this->useunixpwd = true; - } - elseif ($profile['sambaSamAccount_useunixpwd'][0] == "false") { - $this->useunixpwd = false; - } // use no password if ($profile['sambaSamAccount_sambaAcctFlagsN'][0] == "true") { $this->nopwd = true; @@ -2379,14 +2323,24 @@ class sambaSamAccount extends baseModule implements passwordService { } /** - * This function is called whenever the password of this module should be changed. - * @see passwordService::managesPasswordAttributes - * + * 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 * @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 passwordChanged($password) { + public function passwordChangeRequested($password, $modules) { + if (!in_array(get_class($this), $modules)) { + return array(); + } + if (isset($this->moduleSettings['sambaSamAccount_lmHash'][0]) && ($this->moduleSettings['sambaSamAccount_lmHash'][0] == 'no')) { + $this->attributes['sambaLMPassword'][0] = lmPassword($password); + } + $this->attributes['sambaNTPassword'][0] = ntPassword($password); + $this->attributes['sambaPwdLastSet'][0] = time(); return array(); } diff --git a/lam/lib/modules/shadowAccount.inc b/lam/lib/modules/shadowAccount.inc index 167262f7..90c06509 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.sourceforge.net/projects/lam) Copyright (C) 2003 - 2006 Tilo Lutz - Copyright (C) 2007 Roland Gruber + Copyright (C) 2007 - 2009 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 @@ -36,7 +36,7 @@ $Id$ * * @package modules */ -class shadowAccount extends baseModule { +class shadowAccount extends baseModule implements passwordService { /** * Creates a new shadowAccount object. @@ -237,16 +237,7 @@ class shadowAccount extends baseModule { if (!in_array('shadowAccount', $this->attributes['objectClass'])) { return array(); } - $return = $this->getAccountContainer()->save_module_attributes($this->attributes, $this->orig); - // Set shadowLastchange manual. - $clearPwd = $this->getAccountContainer()->getAccountModule('posixAccount')->getClearTextPassword(); - if (isset($clearPwd)) { - $return[$this->getAccountContainer()->dn]['modify']['shadowLastChange'] = array(intval(time()/3600/24)); - } - elseif ($this->getAccountContainer()->isNewAccount) { - $return[$this->getAccountContainer()->dn]['add']['shadowLastChange'] = array(intval(time()/3600/24)); - } - return $return; + return $this->getAccountContainer()->save_module_attributes($this->attributes, $this->orig); } /** @@ -501,6 +492,37 @@ class shadowAccount extends baseModule { } } + + /** + * This method specifies if a module manages password attributes. + * @see passwordService::managesPasswordAttributes + * + * @return boolean true if this module manages password attributes + */ + public function managesPasswordAttributes() { + // only listen to password changes + 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 + * @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) { + // update password timestamp when Unix password was updated + if (!in_array('posixAccount', $modules)) { + return array(); + } + $this->attributes['shadowLastChange'][0] = intval(time()/3600/24); + return array(); + } + } ?>