Code

closes #411
[gosa.git] / gosa-core / include / functions.inc
index 3ab7a405346f19d3c70c4ecef361737817333310..6fc523247ad3255c3fae25e6d6338d2429f19aa6 100644 (file)
@@ -1,7 +1,9 @@
 <?php
 /*
- * This code is part of GOsa (https://gosa.gonicus.de)
- * Copyright (C) 2003 Cajus Pollmeier
+ * 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
 
 /* Configuration file location */
 define ("CONFIG_DIR", "/etc/gosa");
-define ("CONFIG_FILE", "gosa.conf-trunk");
+define ("CONFIG_FILE", "gosa.conf");
 define ("CONFIG_TEMPLATE_DIR", "../contrib/");
-define ("HELP_BASEDIR", "/var/www/doc/");
 
 /* Define get_list flags */
-define("GL_NONE",      0);
-define("GL_SUBSEARCH", 1);
-define("GL_SIZELIMIT", 2);
-define("GL_CONVERT"  , 4);
+define("GL_NONE",         0);
+define("GL_SUBSEARCH",    1);
+define("GL_SIZELIMIT",    2);
+define("GL_CONVERT",      4);
+define("GL_NO_ACL_CHECK", 8);
 
 /* Heimdal stuff */
 define('UNIVERSAL',0x00);
@@ -49,8 +51,8 @@ define('DES3_CBC_MD5',5);
 define('DES3_CBC_SHA1',16);
 
 /* Define globals for revision comparing */
-$svn_path = '$HeadURL$';
-$svn_revision = '$Revision$';
+$svn_path = '$HeadURL: https://oss.gonicus.de/repositories/gosa/trunk/gosa-core/include/functions.inc $';
+$svn_revision = '$Revision: 9246 $';
 
 /* Include required files */
 require_once("class_location.inc");
@@ -93,14 +95,45 @@ $REWRITE= array( "รค" => "ae",
 /* Class autoloader */
 function __autoload($class_name) {
     global $class_mapping, $BASE_DIR;
+
+    if ($class_mapping === NULL){
+           echo sprintf(_("Fatal error: no class locations defined - please run '%s' to fix this"), "<b>update-gosa</b>");
+           exit;
+    }
+
     if (isset($class_mapping[$class_name])){
       require_once($BASE_DIR."/".$class_mapping[$class_name]);
     } else {
-      echo _("Fatal: cannot load class \"$class_name\" - execution aborted");
+      echo sprintf(_("Fatal error: cannot instantiate class '%s' - try running '%s' to fix this"), $class_name, "<b>update-gosa</b>");
+      exit;
     }
 }
 
 
+/*! \brief Checks if a class is available. 
+ *  @param  name String  The class name.
+ *  @return boolean      True if class is available, else false.
+ */
+function class_available($name)
+{
+  global $class_mapping;
+  return(isset($class_mapping[$name]));
+}
+
+
+/* Check if plugin is avaliable */
+function plugin_available($plugin)
+{
+       global $class_mapping, $BASE_DIR;
+
+       if (!isset($class_mapping[$plugin])){
+               return false;
+       } else {
+               return is_readable($BASE_DIR."/".$class_mapping[$plugin]);
+       }
+}
+
+
 /* Create seed with microseconds */
 function make_seed() {
   list($usec, $sec) = explode(' ', microtime());
@@ -280,7 +313,7 @@ function ldap_init ($server, $base, $binddn='', $pass='')
       isset($config->current['TLS']) && $config->current['TLS'] == "true");
 
   /* Sadly we've no proper return values here. Use the error message instead. */
-  if (!preg_match("/Success/i", $ldap->error)){
+  if (!$ldap->success()){
     echo sprintf(_("FATAL: Error when connecting the LDAP. Server said '%s'."), $ldap->get_error());
     exit();
   }
@@ -306,8 +339,8 @@ function process_htaccess ($username, $kerberos= FALSE)
 
     /* Look for entry or realm */
     $ldap= $config->get_ldap_link();
-    if (!preg_match("/Success/i", $ldap->error)){
-      msg_dialog::display(_("LDAP error"), sprintf(_('User login failed.').'<br><br>'._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+    if (!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), "", LDAP_AUTH, ERROR_DIALOG));
       $smarty= get_smarty();
       $smarty->display(get_template_path('headers.tpl'));
       echo "<body>".session::get('errors')."</body></html>";
@@ -333,8 +366,8 @@ function ldap_login_user_htaccess ($username)
 
   /* Look for entry or realm */
   $ldap= $config->get_ldap_link();
-  if (!preg_match("/Success/i", $ldap->error)){
-    msg_dialog::display(_("LDAP error"), sprintf(_('User login failed.').'<br><br>'._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+  if (!$ldap->success()){
+    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), "", LDAP_AUTH, FATAL_ERROR_DIALOG));
     $smarty= get_smarty();
     $smarty->display(get_template_path('headers.tpl'));
     echo "<body>".session::get('errors')."</body></html>";
@@ -343,7 +376,7 @@ function ldap_login_user_htaccess ($username)
   $ldap->search("(&(objectClass=gosaAccount)(uid=$username))", array("uid"));
   /* Found no uniq match? Strange, because we did above... */
   if ($ldap->count() != 1) {
-    msg_dialog::display(_("LDAP error"), _("Username / UID is not unique inside the LDAP tree. Please contact your Administrator."), ERROR_DIALOG);
+    msg_dialog::display(_("LDAP error"), _("Username / UID is not unique inside the LDAP tree!"), FATAL_ERROR_DIALOG);
     return (NULL);
   }
   $attrs= $ldap->fetch();
@@ -371,8 +404,8 @@ function ldap_login_user ($username, $password)
 
   /* look through the entire ldap */
   $ldap = $config->get_ldap_link();
-  if (!preg_match("/Success/i", $ldap->error)){
-    msg_dialog::display(_("LDAP error"), sprintf(_("User login failed.")."<br><br>"._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+  if (!$ldap->success()){
+    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error()), FATAL_ERROR_DIALOG);
     $smarty= get_smarty();
     $smarty->display(get_template_path('headers.tpl'));
     echo "<body>".session::get('errors')."</body></html>";
@@ -413,7 +446,7 @@ function ldap_login_user ($username, $password)
 
             /* found more than one matching id */
     default:
-            msg_dialog::display(_("Internal error"), _("Username / UID is not unique inside the LDAP tree. Please contact your Administrator."), ERROR_DIALOG);
+            msg_dialog::display(_("Internal error"), _("Username / UID is not unique inside the LDAP tree. Please contact your Administrator."), FATAL_ERROR_DIALOG);
             return (NULL);
   }
 
@@ -440,7 +473,7 @@ function ldap_login_user ($username, $password)
       $config->current['RECURSIVE'] == "true",
       isset($config->current['TLS'])
       && $config->current['TLS'] == "true");
-  if (!preg_match("/Success/i", $ldap->error)){
+  if (!$ldap->success()){
     return (NULL);
   }
 
@@ -567,7 +600,7 @@ function add_lock ($object, $user)
   $ldap->cd ($config->current['CONFIG']);
   $ldap->search("(&(objectClass=gosaLockEntry)(gosaUser=$user)(gosaObject=".base64_encode($object)."))",
       array("gosaUser"));
-  if (!preg_match("/Success/i", $ldap->error)){
+  if (!$ldap->success()){
     msg_dialog::display(_("Configuration error"), sprintf(_("Cannot create locking information in LDAP tree. Please contact your administrator!")."<br><br>"._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
     return;
   }
@@ -582,8 +615,8 @@ function add_lock ($object, $user)
     $attrs["gosaObject"] = base64_encode($object);
     $attrs["cn"] = "$name";
     $ldap->add($attrs);
-    if (!preg_match("/Success/i", $ldap->error)){
-      msg_dialog::display(_("Internal error"), sprintf(_("Adding a lock failed.")."<br><br>"._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+    if (!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), "cn=$name,".$config->current['CONFIG'], 0, ERROR_DIALOG));
       return;
     }
   }
@@ -611,11 +644,11 @@ function del_lock ($object)
   $ldap->cd ($config->current['CONFIG']);
   $ldap->search ("(&(objectClass=gosaLockEntry)(gosaObject=".base64_encode($object)."))", array("gosaObject"));
   $attrs= $ldap->fetch();
-  if ($ldap->getDN() != "" && preg_match("/Success/i", $ldap->error)){
+  if ($ldap->getDN() != "" && $ldap->success()){
     $ldap->rmdir ($ldap->getDN());
 
-    if (!preg_match("/Success/i", $ldap->error)){
-      msg_dialog::display(_("LDAP error"), sprintf(_("Removing a lock failed.")."<br><br>"._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+    if (!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $ldap->getDN(), LDAP_DEL, ERROR_DIALOG));
       return;
     }
   }
@@ -653,8 +686,8 @@ function get_lock ($object)
   $ldap= $config->get_ldap_link();
   $ldap->cd ($config->current['CONFIG']);
   $ldap->search("(&(objectClass=gosaLockEntry)(gosaObject=".base64_encode($object)."))", array("gosaUser"));
-  if (!preg_match("/Success/i", $ldap->error)){
-    msg_dialog::display(_("LDAP error"), sprintf(_("Cannot get locking information from LDAP tree!")."<br><br>"._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+  if (!$ldap->success()){
+    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), "", LDAP_SEARCH, ERROR_DIALOG));
     return("");
   }
 
@@ -698,8 +731,8 @@ function get_multiple_locks($objects)
   $ldap= $config->get_ldap_link();
   $ldap->cd ($config->current['CONFIG']);
   $ldap->search($filter, array("gosaUser","gosaObject"));
-  if (!preg_match("/Success/i", $ldap->error)){
-    msg_dialog::display(_("LDAP error"), sprintf(_("Cannot get locking information from LDAP tree!")."<br><br>"._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+  if (!$ldap->success()){
+    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), "", LDAP_SEARCH, ERROR_DIALOG));
     return("");
   }
 
@@ -714,43 +747,100 @@ function get_multiple_locks($objects)
 
 
 /* \!brief  This function searches the ldap database.
-            It search in  $sub_base,*,$base  for all objects matching the $filter.
+            It search in  $sub_bases,*,$base  for all objects matching the $filter.
 
     @param $filter    String The ldap search filter
     @param $category  String The ACL category the result objects belongs 
-    @param $sub_base  String The sub base we want to search for e.g. "ou=apps"
+    @param $sub_bases  String The sub base we want to search for e.g. "ou=apps"
     @param $base      String The ldap base from which we start the search
     @param $attributes Array The attributes we search for.
     @param $flags     Long   A set of Flags
  */
-function get_sub_list($filter, $category,$sub_base, $base= "", $attributes= array(), $flags= GL_SUBSEARCH)
+function get_sub_list($filter, $category,$sub_deps, $base= "", $attributes= array(), $flags= GL_SUBSEARCH)
 {
-
   global $config, $ui;
+  $departments = array();
+
+#  $start = microtime(TRUE);
 
   /* Get LDAP link */
   $ldap= $config->get_ldap_link($flags & GL_SIZELIMIT);
 
   /* Set search base to configured base if $base is empty */
   if ($base == ""){
-    $ldap->cd ($config->current['BASE']);
-  } else {
-    $ldap->cd ($base);
+    $base = $config->current['BASE'];
+  }
+  $ldap->cd ($base);
+
+  /* Ensure we have an array as department list */
+  if(is_string($sub_deps)){
+    $sub_deps = array($sub_deps);
   }
 
-  /* Remove , ("ou=1,ou=2.." => "ou=1") */
-  $sub_base = preg_replace("/,.*$/","",$sub_base);
+  /* Remove ,.*$ ("ou=1,ou=2.." => "ou=1") */
+  $sub_bases = array();
+  foreach($sub_deps as $key => $sub_base){
+    if(empty($sub_base)){
 
-  /* Check if there is a sub department specified */
-  if($sub_base == ""){
-    return(get_list($filter, $category,$base,$attributes,$flags));
+      /* Subsearch is activated and we got an empty sub_base.
+       *  (This may be the case if you have empty people/group ous).
+       * Fall back to old get_list(). 
+       * A log entry will be written.
+       */
+      if($flags & GL_SUBSEARCH){
+        $sub_bases = array();
+        break;
+      }else{
+        
+        /* Do NOT search within subtrees is requeste and the sub base is empty. 
+         * Append all known departments that matches the base.
+         */
+        $departments[$base] = $base;
+      }
+    }else{
+      $sub_bases[$key] = preg_replace("/,.*$/","",$sub_base);
+    }
+  }
+  
+   /* If there is no sub_department specified, fall back to old method, get_list().
+   */
+  if(!count($sub_bases) && !count($departments)){
+    
+    /* Log this fall back, it may be an unpredicted behaviour.
+     */
+    if(!count($sub_bases) && !count($departments)){
+      // log($action,$objecttype,$object,$changes_array = array(),$result = "") 
+      new log("debug","all",__FILE__,$attributes,
+          sprintf("get_sub_list(): Falling back to get_list(), due to empty sub_bases parameter.".
+            " This may slow down GOsa. Search was: '%s'",$filter));
+    }
+    $tmp = get_list($filter, $category,$base,$attributes,$flags);
+    return($tmp);
   }
 
-  /* Get all deparments matching the given sub_base */
-  $departments = array();
-  $ldap->search($sub_base,array("dn"));
+  /* Get all deparments matching the given sub_bases */
+  $base_filter= "";
+  foreach($sub_bases as $sub_base){
+    $base_filter .= "(".$sub_base.")";
+  }
+  $base_filter = "(&(objectClass=organizationalUnit)(|".$base_filter."))";
+  $ldap->search($base_filter,array("dn"));
   while($attrs = $ldap->fetch()){
-    $departments[$attrs['dn']] = $attrs['dn'];
+    foreach($sub_deps as $sub_dep){
+
+      /* Only add those departments that match the reuested list of departments.
+       *
+       * e.g.   sub_deps = array("ou=servers,ou=systems,");
+       *  
+       * In this case we have search for "ou=servers" and we may have also fetched 
+       *  departments like this "ou=servers,ou=blafasel,..."
+       * Here we filter out those blafasel departments.
+       */
+      if(preg_match("/".normalizePreg($sub_dep)."/",$attrs['dn'])){
+        $departments[$attrs['dn']] = $attrs['dn'];
+        break;
+      }
+    }
   }
 
   $result= array();
@@ -770,11 +860,11 @@ function get_sub_list($filter, $category,$sub_base, $base= "", $attributes= arra
     if ($flags & GL_SUBSEARCH) {
       $ldap->search ($filter, $attributes);
     } else {
-      $ldap->ls ($filter,$base,$attributes);
+      $ldap->ls ($filter,$dep,$attributes);
     }
 
     /* Check for size limit exceeded messages for GUI feedback */
-    if (preg_match("/size limit/i", $ldap->error)){
+    if (preg_match("/size limit/i", $ldap->get_error())){
       session::set('limit_exceeded', TRUE);
       $limit_exceeded = TRUE;
     }
@@ -791,21 +881,30 @@ function get_sub_list($filter, $category,$sub_base, $base= "", $attributes= arra
         $attrs["dn"]= $dn;
       }
 
-      /* Sort in every value that fits the permissions */
-      if (is_array($category)){
-        foreach ($category as $o){
-          if ($ui->get_category_permissions($dn, $o) != ""){
+      /* Skip ACL checks if we are forced to skip those checks */
+      if($flags & GL_NO_ACL_CHECK){
+        $result[]= $attrs;
+      }else{
+
+        /* Sort in every value that fits the permissions */
+        if (is_array($category)){
+          foreach ($category as $o){
+            if ($ui->get_category_permissions($dn, $o) != ""){
+              $result[]= $attrs;
+              break;
+            }
+          }
+        } else {
+          if ( $ui->get_category_permissions($dn, $category) != ""){
             $result[]= $attrs;
-            break;
           }
         }
-      } else {
-        if ($ui->get_category_permissions($dn, $category) != ""){
-          $result[]= $attrs;
-        }
       }
     }
   }
+#  if(microtime(TRUE) - $start > 0.1){
+#    echo sprintf("<pre>GET_SUB_LIST  %s .| %f  --- $base -----$filter ---- $flags</pre>",__LINE__,microtime(TRUE) - $start);
+#  }
   return($result);
 }
 
@@ -814,6 +913,8 @@ function get_list($filter, $category, $base= "", $attributes= array(), $flags= G
 {
   global $config, $ui;
 
+#  $start = microtime(TRUE);
+
   /* Get LDAP link */
   $ldap= $config->get_ldap_link($flags & GL_SIZELIMIT);
 
@@ -832,7 +933,7 @@ function get_list($filter, $category, $base= "", $attributes= array(), $flags= G
   }
 
   /* Check for size limit exceeded messages for GUI feedback */
-  if (preg_match("/size limit/i", $ldap->error)){
+  if (preg_match("/size limit/i", $ldap->get_error())){
     session::set('limit_exceeded', TRUE);
   }
 
@@ -841,36 +942,42 @@ function get_list($filter, $category, $base= "", $attributes= array(), $flags= G
   $result= array();
 
   while($attrs = $ldap->fetch()) {
+
     $dn= $ldap->getDN();
 
-    /* Sort in every value that fits the permissions */
-    if (is_array($category)){
-      foreach ($category as $o){
-        if ($ui->get_category_permissions($dn, $o) != ""){
-          if ($flags & GL_CONVERT){
-            $attrs["dn"]= convert_department_dn($dn);
-          } else {
-            $attrs["dn"]= $dn;
+    /* Convert dn into a printable format */
+    if ($flags & GL_CONVERT){
+      $attrs["dn"]= convert_department_dn($dn);
+    } else {
+      $attrs["dn"]= $dn;
+    }
+
+    if($flags & GL_NO_ACL_CHECK){
+      $result[]= $attrs;
+    }else{
+
+      /* Sort in every value that fits the permissions */
+      if (is_array($category)){
+        foreach ($category as $o){
+          if ($ui->get_category_permissions($dn, $o) != ""){
+
+            /* We found what we were looking for, break speeds things up */
+            $result[]= $attrs;
           }
+        }
+      } else {
+        if ($ui->get_category_permissions($dn, $category) != ""){
 
           /* We found what we were looking for, break speeds things up */
           $result[]= $attrs;
         }
       }
-    } else {
-      if ($ui->get_category_permissions($dn, $category) != ""){
-        if ($flags & GL_CONVERT){
-          $attrs["dn"]= convert_department_dn($dn);
-        } else {
-          $attrs["dn"]= $dn;
-        }
-
-        /* We found what we were looking for, break speeds things up */
-        $result[]= $attrs;
-      }
     }
   }
-
+#  if(microtime(TRUE) - $start > 0.1){
+#    echo sprintf("<pre>GET_LIST %s .| %f  --- $base -----$filter ---- $flags</pre>",__LINE__,microtime(TRUE) - $start);
+#  }
   return ($result);
 }
 
@@ -1045,8 +1152,8 @@ function get_ou($name)
                 "mimetypeou"    => "ou=mime,");
 
   /* Preset ou... */
-  if (isset($config->current[$name])){
-    $ou= $config->current[$name];
+  if (isset($config->current[strtoupper($name)])){
+    $ou= $config->current[strtoupper($name)];
   } elseif (isset($map[$name])) {
     $ou = $map[$name];
     return($ou);
@@ -1058,10 +1165,17 @@ function get_ou($name)
  
   if ($ou != ""){
     if (!preg_match('/^[^=]+=[^=]+/', $ou)){
-      return @LDAP::convert("ou=$ou,");
+      $ou = @LDAP::convert("ou=$ou");
     } else {
-      return @LDAP::convert("$ou,");
+      $ou = @LDAP::convert("$ou");
+    }
+
+    if(preg_match("/".normalizePreg($config->current['BASE'])."$/",$ou)){
+      return($ou);
+    }else{
+      return("$ou,");
     }
+  
   } else {
     return "";
   }
@@ -1104,6 +1218,8 @@ function get_base_from_people($dn)
 
 function strict_uid_mode()
 {
+  global $config;
+
   return !(isset($config->current['STRICT']) && preg_match('/^(no|false)$/i', $config->current['STRICT']));
 }
 
@@ -1120,48 +1236,6 @@ function get_uid_regexp()
 }
 
 
-function print_red()
-{
-  trigger_error("Use of obsolete print_red");
-  /* Check number of arguments */
-  if (func_num_args() < 1){
-    return;
-  }
-
-  /* Get arguments, save string */
-  $array = func_get_args();
-  $string= $array[0];
-
-  /* Step through arguments */
-  for ($i= 1; $i<count($array); $i++){
-    $string= preg_replace ("/%s/", $array[$i], $string, 1);
-  }
-
-  /* If DEBUGLEVEL is set, we're in web mode, use textual output in
-     the other case... */
-  if($string !== NULL){
-    if (preg_match("/"._("LDAP error:")."/", $string)){
-      $addmsg= _("Problems with the LDAP server mean that you probably lost the last changes. Please check your LDAP setup for possible errors and try again.");
-    } else {
-      if (!preg_match('/[.!?]$/', $string)){
-        $string.= ".";
-      }
-      $string= preg_replace('/<br>/', ' ', $string);
-      $addmsg= _("Please check your input and fix the error. Press 'OK' to close this message box.");
-      $addmsg = "";
-    }
-    if(empty($addmsg)){
-      $addmsg = _("Error");
-    }
-    msg_dialog::display($addmsg, $string,ERROR_DIALOG);
-    return;
-  }else{
-    return;
-  }
-
-}
-
-
 function gen_locked_message($user, $dn)
 {
   global $plug, $config;
@@ -1216,7 +1290,7 @@ function gen_locked_message($user, $dn)
   } else {
     $smarty->assign ("action", _("Edit anyway"));
   }
-  $smarty->assign ("message", sprintf(_("You're going to edit the LDAP entry/entries '%s'"), "<b>".$msg."</b>", ""));
+  $smarty->assign ("message", sprintf(_("You're going to edit the LDAP entry/entries %s"), "<b>".$msg."</b>", ""));
 
   return ($smarty->fetch (get_template_path('islocked.tpl')));
 }
@@ -1249,41 +1323,6 @@ function get_printer_list()
 }
 
 
-function show_errors($message)
-{
-  $complete= "";
-
-  /* Assemble the message array to a plain string */
-  foreach ($message as $error){
-    if ($complete == ""){
-      $complete= $error;
-    } else {
-      $complete= "$error<br>$complete";
-    }
-  }
-
-  /* Fill ERROR variable with nice error dialog */
-  msg_dialog::display(_("Error"), $complete, ERROR_DIALOG);
-}
-
-
-function show_ldap_error($message, $addon= "")
-{
-  if (!preg_match("/Success/i", $message)){
-    if ($addon == ""){
-      msg_dialog::display(_("LDAP error:"), $message, ERROR_DIALOG);
-    } else {
-      if(!preg_match("/No such object/i",$message)){
-        msg_dialog::display(_("LDAP error"), sprintf(_("Plugin '%s':%s"),"<i>".$addon."</i>", "<br><br>$message"),ERROR_DIALOG);
-      }
-    }
-    return TRUE;
-  } else {
-    return FALSE;
-  }
-}
-
-
 function rewrite($s)
 {
   global $REWRITE;
@@ -1472,7 +1511,7 @@ function apply_filter()
 function back_to_main()
 {
   $string= '<br><p class="plugbottom"><input type=submit name="password_back" value="'.
-    _("Back").'"></p><input type="hidden" name="ignore">';
+    msgPool::backButton().'"></p><input type="hidden" name="ignore">';
 
   return ($string);
 }
@@ -2134,17 +2173,17 @@ function get_base_from_hook($dn, $attrib)
         if (preg_match("/^[0-9]+$/", $output[0])){
           return ($output[0]);
         } else {
-          msg_dialog::display(_("Warning"), _("'base_hook' is not available. Using default base."), WARNING_DIALOG);
+          msg_dialog::display(_("Warning"), _("'base_hook' is not available. Using default base!"), WARNING_DIALOG);
           return ($config->current['UIDBASE']);
         }
       } else {
-        msg_dialog::display(_("Warning"), _("'base_hook' is not available. Using default base."), WARNING_DIALOG);
+        msg_dialog::display(_("Warning"), _("'base_hook' is not available. Using default base!"), WARNING_DIALOG);
         return ($config->current['UIDBASE']);
       }
 
     } else {
 
-      msg_dialog::display(_("Warning"), _("'base_hook' is not available. Using default base."), WARNING_DIALOG);
+      msg_dialog::display(_("Warning"), _("'base_hook' is not available. Using default base!"), WARNING_DIALOG);
       return ($config->current['UIDBASE']);
 
     }
@@ -2163,7 +2202,7 @@ function check_schema($cfg,$rfc2307bis = FALSE)
   $messages= array();
 
   /* Get objectclasses */
-  $ldap = new LDAP($cfg['admin'],$cfg['password'],$cfg['connection'] ,FALSE,$cfg['tls']);
+  $ldap = new ldapMultiplexer(new LDAP($cfg['admin'],$cfg['password'],$cfg['connection'] ,FALSE,$cfg['tls']));
   $objectclasses = $ldap->get_objectclasses();
   if(count($objectclasses) == 0){
     msg_dialog::display(_("LDAP warning"), _("Cannot get schema information from server. No schema check possible!"), WARNING_DIALOG);
@@ -2283,7 +2322,7 @@ function check_schema($cfg,$rfc2307bis = FALSE)
     }
     if(!$rfc2307bis && !isset($tmp['posixGroup']['STRUCTURAL'])){
       $checks['posixGroup']['STATUS']           = FALSE;
-      $checks['posixGroup']['MSG']              = _("You have disabled the rfc2307bis option on the 'ldap setup' step, but your schema   configuration do not support this option.");
+      $checks['posixGroup']['MSG']              = _("Your schema is configured to support the rfc2307bis group, but you have disabled this option on the 'ldap setup' step.");
       $checks['posixGroup']['INFO']             = _("The objectClass 'posixGroup' must be STRUCTURAL");
     }
   }
@@ -2387,8 +2426,8 @@ function change_password ($dn, $password, $mode=0, $hash= "")
   // Get all available encryption Methods
 
   // NON STATIC CALL :)
-  $tmp = new passwordMethod(session::get('config'));
-  $available = $tmp->get_available_methods();
+  $methods = new passwordMethod(session::get('config'));
+  $available = $methods->get_available_methods();
 
   // read current password entry for $dn, to detect the encryption Method
   $ldap       = $config->get_ldap_link();
@@ -2415,11 +2454,12 @@ function change_password ($dn, $password, $mode=0, $hash= "")
 
     /* Extract used hash */
     if ($hash == ""){
-      $hash= strtolower($matches[1]);
+      $test = passwordMethod::get_method($attrs['userPassword'][0]);
+    } else {
+      $test = new $available[$hash]($config);
+      $test->set_hash($hash);
     }
 
-    $test = new  $available[$hash]($config);
-
   } else {
     // User MD5 by default
     $hash= "md5";
@@ -2453,7 +2493,7 @@ function change_password ($dn, $password, $mode=0, $hash= "")
     $attrs= generate_smb_nt_hash($password);
   }
 
- /* Readd ! if user was deactivated */
+ /* Read ! if user was deactivated */
   if($deactivated){
     $newpass = preg_replace("/(^[^\}]+\})(.*$)/","\\1!\\2",$newpass);
   }
@@ -2465,8 +2505,8 @@ function change_password ($dn, $password, $mode=0, $hash= "")
 
   new log("modify","users/passwordMethod",$dn,array_keys($attrs),$ldap->get_error());
 
-  if ($ldap->error != 'Success') {
-    msg_dialog::display(_("LDAP error"), sprintf(_('Setting the password failed!').'<br><br>'._('LDAP server returned: %s'), "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
+  if (!$ldap->success()) {
+    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, ERROR_DIALOG));
   } else {
 
     /* Run backend method for change/create */
@@ -2496,37 +2536,44 @@ function change_password ($dn, $password, $mode=0, $hash= "")
 function generate_smb_nt_hash($password)
 {
   global $config;
-  $tmp= $config->data['MAIN']['SMBHASH']." ".escapeshellarg($password);
-  @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $tmp, "Execute");
 
-  exec($tmp, $ar);
-  flush();
-  reset($ar);
-  $hash= current($ar);
-  if ($hash == "") {
-    msg_dialog::display(_("Configuration error"), _("Setting for SMBHASH in gosa.conf is incorrect! Cannot change Samba password."), ERROR_DIALOG);
-  } else {
-    list($lm,$nt)= split (":", trim($hash));
-
-    if ($config->current['SAMBAVERSION'] == 3) {
-      $attrs['sambaLMPassword']= $lm;
-      $attrs['sambaNTPassword']= $nt;
-      $attrs['sambaPwdLastSet']= date('U');
-      $attrs['sambaBadPasswordCount']= "0";
-      $attrs['sambaBadPasswordTime']= "0";
+  # Try to use gosa-si?
+  if (isset($config->current['GOSA_SI'])){
+       $res= gosaSupportDaemon::send("gosa_gen_smb_hash", "GOSA", array("password" => $password), TRUE);
+    if (isset($res['XML']['HASH'])){
+       $hash= $res['XML']['HASH'];
     } else {
-      $attrs['lmPassword']= $lm;
-      $attrs['ntPassword']= $nt;
-      $attrs['pwdLastSet']= date('U');
+      $hash= "";
     }
-    return($attrs);
+  } else {
+         $tmp= $config->data['MAIN']['SMBHASH']." ".escapeshellarg($password);
+         @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $tmp, "Execute");
+
+         exec($tmp, $ar);
+         flush();
+         reset($ar);
+         $hash= current($ar);
   }
-}
 
+  if ($hash == "") {
+         msg_dialog::display(_("Configuration error"), _("Cannot generate samba hash!"), ERROR_DIALOG);
+         return ("");
+  }
 
-function crypt_single($string,$enc_type )
-{
-  return( passwordMethod::crypt_single_str($string,$enc_type));
+  list($lm,$nt)= split (":", trim($hash));
+
+  if ($config->current['SAMBAVERSION'] == 3) {
+         $attrs['sambaLMPassword']= $lm;
+         $attrs['sambaNTPassword']= $nt;
+         $attrs['sambaPwdLastSet']= date('U');
+         $attrs['sambaBadPasswordCount']= "0";
+         $attrs['sambaBadPasswordTime']= "0";
+  } else {
+         $attrs['lmPassword']= $lm;
+         $attrs['ntPassword']= $nt;
+         $attrs['pwdLastSet']= date('U');
+  }
+  return($attrs);
 }
 
 
@@ -2593,14 +2640,60 @@ function remove_objectClass($classes, &$attrs)
   }
 }
 
+/*! \brief  Initialize a file download with given content, name and data type. 
+ *  @param  data  String The content to send.
+ *  @param  name  String The name of the file.
+ *  @param  type  String The content identifier, default value is "application/octet-stream";
+ */
+function send_binary_content($data,$name,$type = "application/octet-stream")
+{
+  header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+  header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
+  header("Cache-Control: no-cache");
+  header("Pragma: no-cache");
+  header("Cache-Control: post-check=0, pre-check=0");
+  header("Content-type: ".$type."");
+
+  /* force download dialog */
+  if (preg_match('/MSIE 5.5/', $HTTP_USER_AGENT) || preg_match('/MSIE 6.0/', $HTTP_USER_AGENT)) {
+    header('Content-Disposition: filename="'.$name.'"');
+  } else {
+    header('Content-Disposition: attachment; filename="'.$name.'"');
+  }
 
-function display_error_page()
-{
-  $smarty= get_smarty();
-  $smarty->display(get_template_path('headers.tpl'));
-  echo "<body>".msg_dialog::get_dialogs()."</body></html>";
+  echo $data;
   exit();
 }
 
+
+/*! \brief Encode special string characters so we can use the string in \
+           HTML output, without breaking quotes.
+    @param  The String we want to encode.
+    @return The encoded String
+ */
+function xmlentities($str)
+{ 
+  if(is_string($str)){
+    return(htmlentities($str,ENT_QUOTES));
+  }elseif(is_array($str)){
+    foreach($str as $name => $value){
+      $str[$name] = xmlentities($value);
+    }
+  }
+  return($str);
+}
+
+
+function get_random_char () {
+     $randno = rand (0, 63);
+     if ($randno < 12) {
+         return (chr ($randno + 46)); // Digits, '/' and '.'
+     } else if ($randno < 38) {
+         return (chr ($randno + 53)); // Uppercase
+     } else {
+         return (chr ($randno + 59)); // Lowercase
+     }
+  }
+
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
 ?>