Code

Only generate password proposals when they are needed
[gosa.git] / gosa-core / plugins / personal / password / class_password.inc
index 73944131d221fb9ca06f3ff6a46eaaabb9e6ef78..e73d414926f30c34bd4fb380462d6e827c27fef3 100644 (file)
@@ -1,39 +1,71 @@
 <?php
 /*
-   This code is part of GOsa (https://gosa.gonicus.de)
-   Copyright (C) 2007 Fabian Hickert
-
-   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
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This code is part of GOsa (http://www.gosa-project.org)
+ * Copyright (C) 2003-2008 GONICUS GmbH
+ *
+ * ID: $$Id$$
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 class password extends plugin
 {
   /* Definitions */
   var $plHeadline     = "Password";
-  var $plDescription  = "This does something";
+  var $plDescription  = "Change user password";
+
+  var $proposal = "";
+  var $proposalEnabled = FALSE;
+  var $proposalSelected = FALSE;
+  var $proposalInitialized = FALSE;
+
+  var $forcedHash = NULL;
+
 
   function password(&$config, $dn= NULL, $parent= NULL)
   {
-    plugin::plugin($config, $dn, $parent);
+      plugin::plugin($config, $dn, $parent);
+
+  }
+
+  function forceHash($hash)
+  {
+      $this->forcedHash = $hash;
   }
 
+  function refreshProposal()
+  {
+      $this->proposal = passwordMethod::getPasswordProposal($this->config);
+      $this->proposalEnabled = (!empty($this->proposal));
+  }
 
   function execute()
   {
+      // Try to generate a password proposal, if this is successfull
+      //  then preselect the proposal usage.
+      if(!$this->proposalInitialized){
+          $this->refreshProposal();
+          if($this->proposal != ""){
+              $this->proposalSelected = TRUE;
+          }
+          $this->proposalInitialized = TRUE;
+      }
+
     plugin::execute();
     $smarty = get_smarty();
+    $smarty->assign("usePrototype", "true");
     $ui = get_userinfo();
 
     /* Get acls */
@@ -42,81 +74,108 @@ class password extends plugin
     $smarty->assign("NotAllowed" , !preg_match("/w/i",$password_ACLS));
 
     /* Display expiration template */
-    if((isset($this->config->data['MAIN']['ACCOUNT_EXPIRATION'])) &&
-        preg_match('/true/i', $this->config->data['MAIN']['ACCOUNT_EXPIRATION'])){
+    $smarty->assign("passwordExpired", FALSE);
+    if ($this->config->get_cfg_value("handleExpiredAccounts") == "true"){
       $expired= ldap_expired_account($this->config, $ui->dn, $ui->username);
-      if($expired == 4){
+      $smarty->assign("passwordExpired", $expired & POSIX_FORCE_PASSWORD_CHANGE);
+      if($expired == POSIX_DISALLOW_PASSWORD_CHANGE){
         return($smarty->fetch(get_template_path("nochange.tpl", TRUE)));
       }
     }
 
+
+    // Refresh proposal if requested
+    if(isset($_POST['refreshProposal'])) $this->refreshProposal();
+    if(isset($_POST['proposalSelected'])) $this->proposalSelected = get_post('proposalSelected') == 1;
+    $smarty->assign("proposal" , $this->proposal);
+    $smarty->assign("proposalEnabled" , $this->proposalEnabled);
+    $smarty->assign("proposalSelected" , $this->proposalSelected);
+
     /* Pwd change requested */
     if (isset($_POST['password_finish'])){
 
+
+        if($this->proposalSelected){
+            $current_password = get_post('current_password');
+            $new_password = $this->proposal;
+            $repeated_password = $this->proposal;
+        }else{
+            $current_password = get_post('current_password');
+            $new_password = get_post('new_password');
+            $repeated_password = get_post('repeated_password');
+        }
+
+
       /* Should we check different characters in new password */
-      $check_differ = isset($this->config->data['MAIN']['PWDIFFER']);
-      $differ       = @$this->config->data['MAIN']['PWDIFFER'];
+      $check_differ = $this->config->get_cfg_value("passwordMinDiffer") != "";
+      $differ       = $this->config->get_cfg_value("passwordMinDiffer", 0);
 
       /* Enable length check ? */
-      $check_length = isset($this->config->data['MAIN']['PWMINLEN']);
-      $length       = @$this->config->data['MAIN']['PWMINLEN'];
+      $check_length = $this->config->get_cfg_value("passwordMinLength") != "";
+      $length       = $this->config->get_cfg_value("passwordMinLength", 0);
+
+      // Perform GOsa password policy checks
+      $message = array();
+      if(empty($current_password)){
+          $message[] = _("You need to specify your current password in order to proceed.");
+      }elseif($new_password  != $repeated_password){
+          $message[] = _("The passwords you've entered as 'New password' and 'Repeated new password' do not match.");
+      }elseif($new_password == ""){
+          $message[] = _("The password you've entered as 'New password' is empty.");
+      }elseif($check_differ && (substr($current_password, 0, $differ) == substr($new_password, 0, $differ))){
+          $message[] = _("The password used as new and current are too similar.");
+      }elseif($check_length && (strlen($new_password) < $length)){
+          $message[] = _("The password used as new is to short.");
+      #}elseif(!passwordMethod::is_harmless($new_password)){
+       #   $message[] = _("The password contains possibly problematic Unicode characters!");
+      }
 
       /* Call external password quality hook ?*/
-      $check_hook   = isset($this->config->data['MAIN']['EXTERNALPWDHOOK']);
-      $hook         = @$this->config->data['MAIN']['EXTERNALPWDHOOK']." ".$ui->username." ".$_POST['current_password']." ".$_POST['new_password'];
-      if($check_hook){
-        exec($hook,$resarr);
-        $check_hook_output = "";
-        if(count($resarr) > 0) {
-          $check_hook_output= join('\n', $resarr);
-        }
+      if(!count($message)){
+          $check_hook   = $this->config->get_cfg_value("passwordHook") != "";
+          $hook         = $this->config->get_cfg_value("passwordHook")." ".
+              escapeshellarg($ui->username)." ".escapeshellarg($current_password)." ".escapeshellarg($new_password);
+          if($check_hook){
+              exec($hook,$resarr);
+              $check_hook_output = "";
+              if(count($resarr) > 0) {
+                  $check_hook_output= join('\n', $resarr);
+              }
+              if(!empty($check_hook_output)){
+                  $message[] = sprintf(_("Check-hook reported a problem: %s. Password change canceled!"),$check_hook_output);
+              }
+          }
       }
 
-      /* Check given values */    
-      if(!isset($_POST['current_password']) || empty($_POST['current_password'])){
-        msg_dialog::display(_("User password"),
-                            _("You need to specify your current password in order to proceed."),WARNING_DIALOG);
-      }elseif ($_POST['new_password'] != $_POST['repeated_password']){
-        msg_dialog::display(_("User password"),
-                            _("The passwords you've entered as 'New password' and 'Repeated new password' do not match."),WARNING_DIALOG);
-      } elseif ($_POST['new_password'] == ""){
-        msg_dialog::display(_("User password"),
-                            _("The password you've entered as 'New password' is empty."),WARNING_DIALOG);
-      }elseif($check_differ && (substr($_POST['current_password'], 0, $differ) == substr($_POST['new_password'], 0, $differ))){
-        msg_dialog::display(_("User password"),
-                            _("The password used as new and current are too similar."),WARNING_DIALOG);
-      }elseif($check_length && (strlen($_POST['new_password']) < $length)){
-        msg_dialog::display(_("User password"),
-                            _("The password used as new is to short."),WARNING_DIALOG);
-      }elseif($check_hook && $check_hook_output != ""){
-        msg_dialog::display(_("User password"),
-                    sprintf(_("External password changer reported a problem: %s."),$check_hook_output),WARNING_DIALOG);
+      // Some errors/warning occured, display them and abort password change.
+      if(count($message)){
+          msg_dialog::displayChecks($message);
       }else{
 
         /* Try to connect via current password */
         $tldap = new LDAP(
             $ui->dn, 
-            $_POST['current_password'],
+            $current_password,
             $this->config->current['SERVER'],
-            isset($this->config->current['RECURSIVE'])  && preg_match("/true/i",$this->config->current['RECURSIVE']),
-            isset($this->config->current['TLS'])        && preg_match("/true/i",$this->config->current['TLS']));
+            $this->config->get_cfg_value("ldapFollowReferrals") == "true",
+            $this->config->get_cfg_value("ldapTLS") == "true");
 
         /* connection Successfull ? */
-        if ($tldap->error != "Success"){
-          msg_dialog::display(_("User password"),
+        if (!$tldap->success()){
+          msg_dialog::display(_("Password change"),
                               _("The password you've entered as your current password doesn't match the real one."),WARNING_DIALOG);
         }else{
 
           /* Check GOsa permissions */
           if (!preg_match("/w/i",$password_ACLS)){
-            msg_dialog::display(_("User password"),
+            msg_dialog::display(_("Password change"),
                                 _("You have no permission to change your password."),WARNING_DIALOG);
           }else{
-            change_password ($ui->dn, $_POST['new_password']);
+            $this->change_password($ui->dn, $new_password,$this->forcedHash);
             gosa_log ("User/password has been changed");
-            $ui->password= $_POST['new_password'];
+            $ui->password= $new_password;
             session::set('ui',$ui);
-#$this->handle_post_events("modify",array("userPassword" => $_POST['new_password']));
+#$this->handle_post_events("modify",array("userPassword" => $new_password));
             return($smarty->fetch(get_template_path("changed.tpl", TRUE)));
           }
         }
@@ -125,6 +184,16 @@ class password extends plugin
     return($smarty->fetch(get_template_path("password.tpl", TRUE)));
   } 
 
+  function change_password($dn, $pwd, $hash)
+  {
+      if(!$hash){
+          change_password ($dn, $pwd);
+      }else{
+          change_password ($dn, $pwd,0, $hash);
+      }
+  }
+
+
   function remove_from_parent()
   {
     $this->handle_post_events("remove");