index 85d231f555d6b45611d44877527a1436236cb4f7..8307b6e63ee5c6996ef2a3821aad4484ccd1dec5 100644 (file)
msg_dialog::display(_("Internal error"), sprintf(_("File %s cannot be deleted!"), bold($directory."/".$file)), ERROR_DIALOG);
// This should never be reached
}
- } elseif(is_dir($directory."/".$file) &&
- is_writable($directory."/".$file)) {
- // Just recursively delete it
- rmdirRecursive($directory."/".$file);
- }
+ }
}
// We should now create a fresh revision file
clean_smarty_compile_dir($directory);
}
-/*! \brief Change the password of a given DN
- *
- * Change the password of a given DN with the specified hash.
- *
- * \param string 'dn' the DN whose password shall be changed
- * \param string 'password' the password
- * \param int mode
- * \param string 'hash' which hash to use to encrypt it, default is empty
- * 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
+/*! \brief Change the password for a given object ($dn).
+ * This method uses the specified hashing method to generate a new password
+ * for the object and it also takes care of sambaHashes, if enabled.
+ * Finally the postmodify hook of the class 'user' will be called, if it is set.
+ *
+ * @param String The DN whose password shall be changed.
+ * @param String The new password.
+ * @param Boolean Skip adding samba hashes to the target (sambaNTPassword,sambaLMPassword)
+ * @param String The hashin method to use, default is the global configured default.
+ * @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 else FALSE.
*/
-function change_password ($dn, $password, $mode=0, $hash= "", $old_password = "")
+function change_password ($dn, $password, $mode=FALSE, $hash= "", $old_password = "", &$message = "")
{
global $config;
$newpass= "";
- /* Convert to lower. Methods are lowercase */
- $hash= strtolower($hash);
-
- // Get all available encryption Methods
+ // Not sure, why this is here, but maybe some encryption methods require it.
+ mt_srand((double) microtime()*1000000);
- // NON STATIC CALL :)
+ // Get a list of all available password encryption methods.
$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();
+ // Fetch the current object data, to be able to detect the current hashing method
+ // and to be able to rollback changes once has an error occured.
+ $ldap = $config->get_ldap_link();
$ldap->cat ($dn, array("shadowLastChange", "userPassword","sambaNTPassword","sambaLMPassword", "uid"));
- $attrs = $ldap->fetch ();
+ $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";
- }
-
- // 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);
+ // If no hashing method is enforced, then detect what method we've to use.
+ $hash = strtolower($hash);
+ if(empty($hash)){
- /* Extract used hash */
- if ($hash == ""){
- $test = passwordMethod::get_method($attrs['userPassword'][0],$dn);
- } else {
+ // Do we need clear-text password for this object?
+ if(isset($attrs['userPassword'][0]) && !preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0])){
+ $hash = "clear";
$test = new $available[$hash]($config,$dn);
$test->set_hash($hash);
}
- } else {
- // User MD5 by default
- $hash= "md5";
- $test = new $available['md5']($config, $dn);
- }
-
- if($test instanceOf passwordMethod){
+ // If we've still no valid hashing method detected, then try to extract if from the userPassword attribute.
+ elseif(isset($attrs['userPassword'][0]) && preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0], $matches)){
+ $test = passwordMethod::get_method($attrs['userPassword'][0],$dn);
+ $hash = $test->get_hash_name();
+ }
- stats::log('global', 'global', array('users'), $action = 'change_password', $amount = 1, 0, $test->get_hash());
+ // No current password was found and no hash is enforced, so we've to use the config default here.
+ $hash = $config->get_cfg_value('core','passwordDefaultHash');
+ $test = new $available[$hash]($config,$dn);
+ $test->set_hash($hash);
+ }else{
+ $test = new $available[$hash]($config,$dn);
+ $test->set_hash($hash);
+ }
- $deactivated = $test->is_locked($config,$dn);
+ // We've now a valid password-method-handle and can create the new password hash or don't we?
+ if(!$test instanceOf passwordMethod){
+ $message = _("Cannot detect password hash!");
+ }else{
- /* Feed password backends with information */
- $test->dn= $dn;
- $test->attrs= $attrs;
+ // Feed password backends with object 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;
+ // Do we have to append samba attributes too?
+ // - sambaNTPassword / sambaLMPassword
+ $tmp = $config->get_cfg_value('core','sambaHashHook');
+ $attrs= array();
+ if (!$mode && !empty($tmp)){
+ $attrs= generate_smb_nt_hash($password);
+ $shadow = (isset($attrs["shadowLastChange"][0]))?(int)(date("U") / 86400):0;
+ if ($shadow != 0){
+ $attrs['shadowLastChange']= $shadow;
+ }
}
- // Write back modified entry
+ // Write back the new password hash
$ldap->cd($dn);
- $attrs= array();
-
- // Not for groups
- if ($mode == 0){
-
- $tmp = $config->get_cfg_value('core','sambaHashHook');
- if(!empty($tmp)){
-
- // Create SMB Password
- $attrs= generate_smb_nt_hash($password);
+ $attrs['userPassword']= $newpass;
- if ($shadow != 0){
- $attrs['shadowLastChange']= $shadow;
- }
- }
+ // Prepare a special attribute list, which will be used for event hook calls
+ $attrsEvent = array();
+ foreach($initialAttrs as $name => $value){
+ if(!is_numeric($name))
+ $attrsEvent[$name] = escapeshellarg($value[0]);
+ }
+ $attrsEvent['dn'] = escapeshellarg($initialAttrs['dn']);
+ foreach($attrs as $name => $value){
+ $attrsEvent[$name] = escapeshellarg($value);
}
+ $attrsEvent['current_password'] = escapeshellarg($old_password);
+ $attrsEvent['new_password'] = escapeshellarg($password);
- $attrs['userPassword']= array();
- $attrs['userPassword']= $newpass;
+ // Call the premodify hook now
+ $passwordPlugin = new password($config,$dn);
+ plugin::callHook($passwordPlugin, 'PREMODIFY', $attrsEvent, $output,$retCode,$error, $directlyPrintError = FALSE);
+ if($retCode === 0 && count($output)){
+ $message = sprintf(_("Pre-event hook reported a problem: %s. Password change canceled!"),implode($output));
+ return(FALSE);
+ }
+ // Perform ldap operations
$ldap->modify($attrs);
- /* Read ! if user was deactivated */
+ // Check if the object was locked before, if it was, lock it again!
+ $deactivated = $test->is_locked($config,$dn);
if($deactivated){
$test->lock_account($config,$dn);
}
- new log("modify","users/passwordMethod",$dn,array_keys($attrs),$ldap->get_error());
-
- $passwordPlugin = new password($config,$dn);
-
-
- // Try to write changes to the ldap
+ // Check if everything went fine and then call the post event hooks.
+ // If an error occures, then try to rollback the complete actions done.
$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;
+ new log("modify","users/passwordMethod",$dn,array(),"Password change - ldap modifications! - FAILED");
$success =FALSE;
+ $message = msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD);
+ $preRollback =TRUE;
} else {
// Now call the passwordMethod change mechanism.
if(!$test->set_password($password)){
- $preRollback = TRUE;
+ $ldapRollback = TRUE;
+ $preRollback =TRUE;
$success = FALSE;
+ new log("modify","users/passwordMethod",$dn,array(),"Password change - set_password! - FAILED");
+ $message = _("Password change failed!");
}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));
+ plugin::callHook($passwordPlugin, 'POSTMODIFY', $attrsEvent, $output,$retCode,$error, $directlyPrintError = FALSE);
+ if($retCode === 0){
+ if(count($output)){
+ new log("modify","users/passwordMethod",$dn,array(),"Password change - Post modify hook reported! - FAILED!");
+ $message = sprintf(_("Post-event hook reported a problem: %s. Password change canceled!"),implode($output));
+ $ldapRollback = TRUE;
+ $preRollback = TRUE;
+ $success = FALSE;
+ }else{
+ #new log("modify","users/passwordMethod",$dn,array(),"Password change - successfull!");
+ }
}else{
- $preRollback = TRUE;
$ldapRollback = TRUE;
+ $preRollback = TRUE;
$success = FALSE;
+ new log("modify","users/passwordMethod",$dn,array(),"Password change - postmodify hook execution! - FAILED");
+ new log("modify","users/passwordMethod",$dn,array(),$error);
// Call password method again and send in old password to
// keep the database consistency
@@ -3135,35 +3145,50 @@ function change_password ($dn, $password, $mode=0, $hash= "", $old_password = ""
}
}
- // 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.
+ // Setting the 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($preRollback){
+ new log("modify","users/passwordMethod",$dn,array(),"Rolling back premodify hook!");
+ $oldpass= $test->generate_hash($old_password);
+ $attrsEvent['current_password'] = escapeshellarg($password);
+ $attrsEvent['new_password'] = escapeshellarg($old_password);
+ foreach(array("userPassword","sambaNTPassword","sambaLMPassword") as $attr){
+ if(isset($initialAttrs[$attr][0])) $attrsEvent[$attr] = $initialAttrs[$attr][0];
+ }
+
+ plugin::callHook($passwordPlugin, 'PREMODIFY', $attrsEvent, $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));
+ new log("modify","users/passwordMethod",$dn,array(),"Rolling back premodify hook! - FAILED!");
}
}
// 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){
+ new log("modify","users/passwordMethod",$dn,array(),"Rolling back ldap modifications!");
$attrs = array();
foreach(array("userPassword","sambaNTPassword","sambaLMPassword") as $attr){
- $attrs[$attr] = $initialAttrs[$attr][0];
+ if(isset($initialAttrs[$attr][0])) $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));
+ $message = msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD);
+ new log("modify","users/passwordMethod",$dn,array(),"Rolling back ldap modifications! - FAILED");
}
}
+ // Log action.
+ if($success){
+ stats::log('global', 'global', array('users'), $action = 'change_password', $amount = 1, 0, $test->get_hash());
+ new log("modify","users/passwordMethod",$dn,array(),"Password change - successfull!");
+ }else{
+ new log("modify","users/passwordMethod",$dn,array(),"Password change - FAILED!");
+ }
+
return($success);
}
}