summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b662aed)
raw | patch | inline | side by side (parent: b662aed)
author | hickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Wed, 8 Sep 2010 16:21:35 +0000 (16:21 +0000) | ||
committer | hickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Wed, 8 Sep 2010 16:21:35 +0000 (16:21 +0000) |
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@19571 594d385d-05f5-0310-b6e9-bd551577e9d8
gosa-core/include/functions.inc | patch | blob | history |
index d87a157c16dfc3bbc610a60c8e320776226597aa..85d231f555d6b45611d44877527a1436236cb4f7 100644 (file)
* \param string 'password' the password
* \param int mode
* \param string 'hash' which hash to use to encrypt it, default is empty
- * for cleartext storage.
+ * for cleartext storage.
+ * \param string The users old password, this allows script based rollback mechanisms,
+ * the prehook will then be called witch switched newPassword/oldPassword.
* \return boolean TRUE on success FALSE on error
*/
-function change_password ($dn, $password, $mode=0, $hash= "")
+function change_password ($dn, $password, $mode=0, $hash= "", $old_password = "")
{
- global $config;
- $newpass= "";
+ global $config;
+ $newpass= "";
- /* Convert to lower. Methods are lowercase */
- $hash= strtolower($hash);
+ /* Convert to lower. Methods are lowercase */
+ $hash= strtolower($hash);
- // Get all available encryption Methods
+ // Get all available encryption Methods
- // NON STATIC CALL :)
- $methods = new passwordMethod(session::get('config'),$dn);
- $available = $methods->get_available_methods();
+ // NON STATIC CALL :)
+ $methods = new passwordMethod(session::get('config'),$dn);
+ $available = $methods->get_available_methods();
- // read current password entry for $dn, to detect the encryption Method
- $ldap = $config->get_ldap_link();
- $ldap->cat ($dn, array("shadowLastChange", "userPassword", "uid"));
- $attrs = $ldap->fetch ();
+ // read current password entry for $dn, to detect the encryption Method
+ $ldap = $config->get_ldap_link();
+ $ldap->cat ($dn, array("shadowLastChange", "userPassword","sambaNTPassword","sambaLMPassword", "uid"));
+ $attrs = $ldap->fetch ();
+ $initialAttrs = $attrs;
- /* Is ensure that clear passwords will stay clear */
- if($hash == "" && isset($attrs['userPassword'][0]) && !preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0])){
- $hash = "clear";
- }
+ /* Is ensure that clear passwords will stay clear */
+ if($hash == "" && isset($attrs['userPassword'][0]) && !preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0])){
+ $hash = "clear";
+ }
+
+ // Detect the encryption Method
+ if ( (isset($attrs['userPassword'][0]) && preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0], $matches)) || $hash != ""){
- // Detect the encryption Method
- if ( (isset($attrs['userPassword'][0]) && preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0], $matches)) || $hash != ""){
+ /* Check for supported algorithm */
+ mt_srand((double) microtime()*1000000);
- /* Check for supported algorithm */
- mt_srand((double) microtime()*1000000);
+ /* Extract used hash */
+ if ($hash == ""){
+ $test = passwordMethod::get_method($attrs['userPassword'][0],$dn);
+ } else {
+ $test = new $available[$hash]($config,$dn);
+ $test->set_hash($hash);
+ }
- /* Extract used hash */
- if ($hash == ""){
- $test = passwordMethod::get_method($attrs['userPassword'][0],$dn);
} else {
- $test = new $available[$hash]($config,$dn);
- $test->set_hash($hash);
+ // User MD5 by default
+ $hash= "md5";
+ $test = new $available['md5']($config, $dn);
}
- } else {
- // User MD5 by default
- $hash= "md5";
- $test = new $available['md5']($config, $dn);
- }
+ if($test instanceOf passwordMethod){
- if($test instanceOf passwordMethod){
+ stats::log('global', 'global', array('users'), $action = 'change_password', $amount = 1, 0, $test->get_hash());
- stats::log('global', 'global', array('users'), $action = 'change_password', $amount = 1, 0, $test->get_hash());
+ $deactivated = $test->is_locked($config,$dn);
- $deactivated = $test->is_locked($config,$dn);
+ /* Feed password backends with information */
+ $test->dn= $dn;
+ $test->attrs= $attrs;
+ $newpass= $test->generate_hash($password);
- /* Feed password backends with information */
- $test->dn= $dn;
- $test->attrs= $attrs;
- $newpass= $test->generate_hash($password);
+ // Update shadow timestamp?
+ if (isset($attrs["shadowLastChange"][0])){
+ $shadow= (int)(date("U") / 86400);
+ } else {
+ $shadow= 0;
+ }
- // Update shadow timestamp?
- if (isset($attrs["shadowLastChange"][0])){
- $shadow= (int)(date("U") / 86400);
- } else {
- $shadow= 0;
- }
+ // Write back modified entry
+ $ldap->cd($dn);
+ $attrs= array();
- // Write back modified entry
- $ldap->cd($dn);
- $attrs= array();
-
- // Not for groups
- if ($mode == 0){
+ // Not for groups
+ if ($mode == 0){
- $tmp = $config->get_cfg_value('core','sambaHashHook');
- if(!empty($tmp)){
+ $tmp = $config->get_cfg_value('core','sambaHashHook');
+ if(!empty($tmp)){
- // Create SMB Password
- $attrs= generate_smb_nt_hash($password);
+ // Create SMB Password
+ $attrs= generate_smb_nt_hash($password);
- if ($shadow != 0){
- $attrs['shadowLastChange']= $shadow;
+ if ($shadow != 0){
+ $attrs['shadowLastChange']= $shadow;
+ }
}
}
- }
- $attrs['userPassword']= array();
- $attrs['userPassword']= $newpass;
+ $attrs['userPassword']= array();
+ $attrs['userPassword']= $newpass;
- $ldap->modify($attrs);
+ $ldap->modify($attrs);
- /* Read ! if user was deactivated */
- if($deactivated){
- $test->lock_account($config,$dn);
- }
+ /* Read ! if user was deactivated */
+ if($deactivated){
+ $test->lock_account($config,$dn);
+ }
- new log("modify","users/passwordMethod",$dn,array_keys($attrs),$ldap->get_error());
+ new log("modify","users/passwordMethod",$dn,array_keys($attrs),$ldap->get_error());
- if (!$ldap->success()) {
- msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, ERROR_DIALOG));
- } else {
+ $passwordPlugin = new password($config,$dn);
- /* Run backend method for change/create */
- if(!$test->set_password($password)){
- return(FALSE);
- }
- /* Find postmodify entries for this class */
- $command= $config->get_cfg_value("password","postmodify");
+ // Try to write changes to the ldap
+ $preRollback = FALSE;
+ $ldapRollback = FALSE;
+ $success = TRUE;
+ if (!$ldap->success()) {
+ msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, ERROR_DIALOG));
+ $preRollback = TRUE;
+ $success =FALSE;
+ } else {
- if ($command != ""){
- /* Walk through attribute list */
- $command= preg_replace("/%userPassword/", escapeshellarg($password), $command);
- $command= preg_replace("/%dn/", escapeshellarg($dn), $command);
+ // Now call the passwordMethod change mechanism.
+ if(!$test->set_password($password)){
+ $preRollback = TRUE;
+ $success = FALSE;
+ }else{
+
+ // Execute the password hook
+ plugin::callHook($passwordPlugin, 'PREMODIFY', $attrs, $output,$retCode,$error, $directlyPrintError = FALSE);
+ if($retCode === 0 && count($output)){
+ $attrs = array();
+ $attrs['userPassword'] = escapeshellarg($password);
+ $attrs['current_password'] = escapeshellarg($password);
+ $attrs['old_password'] = escapeshellarg($old_password);
+ $message = sprintf(_("Pre-event hook reported a problem: %s. Password change canceled!"),implode($output));
+ msg_dialog::displayChecks(array($message));
+ }else{
+ $preRollback = TRUE;
+ $ldapRollback = TRUE;
+ $success = FALSE;
+
+ // Call password method again and send in old password to
+ // keep the database consistency
+ $test->set_password($old_password);
+ }
+ }
+ }
- if (check_command($command)){
- @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute");
- exec($command);
- } else {
- $message= sprintf(_("Command %s specified as post modify action for plugin %s does not exist!"), bold($command), bold("password"));
- msg_dialog::display(_("Configuration error"), $message, ERROR_DIALOG);
+ // Setting password in the ldap database or further operation failed, we should now execute
+ // the plugins pre-event hook, using switched passwords new/old password.
+ // This ensures that passwords which were set outside of GOsa, will be reset to its
+ // starting value.
+ if($preRollback && !empty($old_password)){
+ $attrs = array();
+ $attrs['current_password'] = escapeshellarg($password);
+ $attrs['new_password'] = escapeshellarg($old_password);
+ plugin::callHook($passwordPlugin, 'PREMODIFY', $attrs, $output,$retCode,$error, $directlyPrintError = FALSE);
+ if($retCode === 0 && count($output)){
+ $message = sprintf(_("Pre-event hook reported a problem: %s. Password change canceled!"),implode($output));
+ msg_dialog::displayChecks(array($message));
+ }
}
- }
+
+ // We've written the password to the ldap database, but executing the postmodify hook failed.
+ // Now, we've to rollback all password related ldap operations.
+ if($ldapRollback){
+ $attrs = array();
+ foreach(array("userPassword","sambaNTPassword","sambaLMPassword") as $attr){
+ $attrs[$attr] = $initialAttrs[$attr][0];
+ }
+ $ldap->cd($dn);
+ $ldap->modify($attrs);
+ if(!$ldap->success()){
+ msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, ERROR_DIALOG));
+ }
+ }
+
+ return($success);
}
- return(TRUE);
- }
}