Code

Updated functions.inc
[gosa.git] / gosa-core / include / functions.inc
index 0754d26eca09293ebe1609155ec7088cd1effb94..1da4e832c9b95fead61c302f443836260335dc7a 100644 (file)
@@ -25,10 +25,11 @@ 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);
@@ -55,7 +56,6 @@ $svn_revision = '$Revision$';
 /* Include required files */
 require_once("class_location.inc");
 require_once ("functions_debug.inc");
-require_once ("functions_dns.inc");
 require_once ("accept-to-gettext.inc");
 
 /* Define constants for debugging */
@@ -94,14 +94,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());
@@ -715,18 +746,17 @@ 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;
 
   /* Get LDAP link */
@@ -739,19 +769,57 @@ function get_sub_list($filter, $category,$sub_base, $base= "", $attributes= arra
     $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);
+  $sub_bases = array();
+  foreach($sub_deps as $key => $sub_base){
+    $sub_bases[$key] = preg_replace("/,.*$/","",$sub_base);
+  }
 
-  /* Check if there is a sub department specified */
-  if($sub_base == ""){
-    return(get_list($filter, $category,$base,$attributes,$flags));
+  /* Check if we have enabled the sub_dir search support AND 
+   *  if there is a sub department specified.
+   * If not, fall back to old method, get_list().
+   */
+  $sub_enabled = isset($config->current['SUB_LIST_SUPPORT']) && preg_match("/true/i",$config->current['SUB_LIST_SUPPORT']);
+  if(!count($sub_bases) || !$sub_enabled){
+    
+    /* Log this fall back, it may be an unpredicted behaviour.
+     */
+    if(!count($sub_bases)){
+      gosa_log("debug","get_sub_list","",$attributes,sprintf("get_sub_list(): Falling back to get_list(), due to empty sub_bases parameter. This may slow down GOsa.",$src,$attrs['dn']));
+    }
+    $tmp = get_list($filter, $category,$base,$attributes,$flags | GL_SUBSEARCH);
+    return($tmp);
   }
 
-  /* Get all deparments matching the given sub_base */
+  /* Get all deparments matching the given sub_bases */
   $departments = array();
-  $ldap->search($sub_base,array("dn"));
+  $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();
@@ -771,7 +839,7 @@ 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 */
@@ -792,18 +860,24 @@ 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;
-        }
       }
     }
   }
@@ -842,33 +916,36 @@ 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;
-      }
     }
   }
 
@@ -1275,7 +1352,7 @@ function show_ldap_error($message, $addon= "")
       msg_dialog::display(_("LDAP error:"), $message, ERROR_DIALOG);
     } else {
       if(!preg_match("/No such object/i",$message)){
-        msg_dialog::display(sprintf(_("LDAP error in plugin '%s':"),"<i>".$addon."</i>"),$message,ERROR_DIALOG);
+        msg_dialog::display(_("LDAP error"), sprintf(_("Plugin '%s':%s"),"<i>".$addon."</i>", "<br><br>$message"),ERROR_DIALOG);
       }
     }
     return TRUE;
@@ -2284,7 +2361,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");
     }
   }
@@ -2497,31 +2574,40 @@ 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);
+  # Try to use gosa-si?
+  if (isset($config->current['GOSA_SI'])){
+       $res= gosaSupportDaemon::send("gosa_gen_smb_hash", "GOSA", array("password" => $password), TRUE);
+       $hash= $res['XML']['HASH'];
+  } 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"), _("Setting for SMBHASH in gosa.conf is incorrect! Cannot change Samba password."), ERROR_DIALOG);
+         msg_dialog::display(_("Configuration error"), _("Cannot generate samba hash!"), ERROR_DIALOG);
+         return ("");
+  }
+
+  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 {
-    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);
+         $attrs['lmPassword']= $lm;
+         $attrs['ntPassword']= $nt;
+         $attrs['pwdLastSet']= date('U');
   }
+  return($attrs);
 }
 
 
@@ -2556,11 +2642,66 @@ function getEntryCSN($dn)
 }
 
 
-function display_error_page()
+/* Add a given objectClass to an attrs entry */
+function add_objectClass($classes, &$attrs)
 {
-  $smarty= get_smarty();
-  $smarty->display(get_template_path('headers.tpl'));
-  echo "<body>".msg_dialog::get_dialogs()."</body></html>";
+  if (is_array($classes)){
+    $list= $classes;
+  } else {
+    $list= array($classes);
+  }
+
+  foreach ($list as $class){
+    $attrs['objectClass'][]= $class;
+  }
+}
+
+
+/* Removes a given objectClass from the attrs entry */
+function remove_objectClass($classes, &$attrs)
+{
+  if (isset($attrs['objectClass'])){
+    /* Array? */
+    if (is_array($classes)){
+      $list= $classes;
+    } else {
+      $list= array($classes);
+    }
+
+    $tmp= array();
+    foreach ($attrs['objectClass'] as $oc) {
+      foreach ($list as $class){
+        if ($oc != $class){
+          $tmp[]= $oc;
+        }
+      }
+    }
+    $attrs['objectClass']= $tmp;
+  }
+}
+
+/*! \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.'"');
+  }
+
+  echo $data;
   exit();
 }