Code

Added a method which returns an array with all objects we've permissions on.
[gosa.git] / gosa-core / include / functions.inc
index d9d12986fd5aa5ba65846f3604594aa4025f3899..aa28014a03cd8ab43c6e8719b85949cbd380c4f4 100644 (file)
@@ -1743,7 +1743,7 @@ function gen_uids($rule, $attributes)
       $size= preg_replace('/^.*{id(:|!)(\d+)}.*$/', '\\2', $uid);
 
       $start= $m[1]==":"?0:-1;
-      for ($i= $start, $p= pow(10,$size); $i < $p; $i++){
+      for ($i= $start, $p= pow(10,$size)-1; $i < $p; $i++){
         if ($i == -1) {
           $number= "";
         } else {
@@ -1757,6 +1757,9 @@ function gen_uids($rule, $attributes)
           break;
         }
       }
+
+      /* Remove link if nothing has been found */
+      $uid= preg_replace('/{id(:|!)\d+}/', '', $uid);
     }
 
     if(preg_match('/\{id#\d+}/',$uid)){
@@ -1772,6 +1775,9 @@ function gen_uids($rule, $attributes)
           break;
         }
       }
+
+      /* Remove link if nothing has been found */
+      $uid= preg_replace('/{id#\d+}/', '', $uid);
     }
 
     /* Don't assign used ones */
@@ -2234,47 +2240,47 @@ function check_schema($cfg,$rfc2307bis = FALSE)
   /* The gosa base schema */
   $checks['gosaObject'] = $def_check;
   $checks['gosaObject']['REQUIRED_VERSION'] = "2.6.1";
-  $checks['gosaObject']['SCHEMA_FILES']     = array("gosa+samba3.schema","gosa.schema");
+  $checks['gosaObject']['SCHEMA_FILES']     = array("gosa-samba3.schema","gosa-samba2.schema");
   $checks['gosaObject']['CLASSES_REQUIRED'] = array("gosaObject");
   $checks['gosaObject']['IS_MUST_HAVE']     = TRUE;
 
   /* GOsa Account class */
   $checks["gosaAccount"]["REQUIRED_VERSION"]= "2.6.6";
-  $checks["gosaAccount"]["SCHEMA_FILES"]    = array("gosa+samba3.schema","gosa.schema");
+  $checks["gosaAccount"]["SCHEMA_FILES"]    = array("gosa-samba3.schema","gosa-samba2.schema");
   $checks["gosaAccount"]["CLASSES_REQUIRED"]= array("gosaAccount");
   $checks["gosaAccount"]["IS_MUST_HAVE"]    = TRUE;
   $checks["gosaAccount"]["INFO"]            = _("Used to store account specific informations.");
 
   /* GOsa lock entry, used to mark currently edited objects as 'in use' */
   $checks["gosaLockEntry"]["REQUIRED_VERSION"] = "2.6.1";
-  $checks["gosaLockEntry"]["SCHEMA_FILES"]     = array("gosa+samba3.schema","gosa.schema");
+  $checks["gosaLockEntry"]["SCHEMA_FILES"]     = array("gosa-samba3.schema","gosa-samba2.schema");
   $checks["gosaLockEntry"]["CLASSES_REQUIRED"] = array("gosaLockEntry");
   $checks["gosaLockEntry"]["IS_MUST_HAVE"]     = TRUE;
   $checks["gosaLockEntry"]["INFO"]             = _("Used to lock currently edited entries to avoid multiple changes at the same time.");
 
   /* Some other checks */
   foreach(array(
-        "gosaCacheEntry"        => array("version" => "2.6.1"),
-        "gosaDepartment"        => array("version" => "2.6.1"),
+        "gosaCacheEntry"        => array("version" => "2.6.1", "class" => "gosaAccount"),
+        "gosaDepartment"        => array("version" => "2.6.1", "class" => "gosaAccount"),
         "goFaxAccount"          => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"),
         "goFaxSBlock"           => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"),
         "goFaxRBlock"           => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"),
         "gosaUserTemplate"      => array("version" => "2.6.1", "class" => "posixAccount","file" => "nis.schema"),
-        "gosaMailAccount"       => array("version" => "2.6.1", "class" => "mailAccount","file" => "gosa+samba3.schema"),
-        "gosaProxyAccount"      => array("version" => "2.6.1", "class" => "proxyAccount","file" => "gosa+samba3.schema"),
+        "gosaMailAccount"       => array("version" => "2.6.1", "class" => "mailAccount","file" => "gosa-samba3.schema"),
+        "gosaProxyAccount"      => array("version" => "2.6.1", "class" => "proxyAccount","file" => "gosa-samba3.schema"),
         "gosaApplication"       => array("version" => "2.6.1", "class" => "appgroup","file" => "gosa.schema"),
         "gosaApplicationGroup"  => array("version" => "2.6.1", "class" => "appgroup","file" => "gosa.schema"),
         "GOhard"                => array("version" => "2.6.1", "class" => "terminals","file" => "goto.schema"),
         "gotoTerminal"          => array("version" => "2.6.1", "class" => "terminals","file" => "goto.schema"),
-        "goServer"              => array("version" => "2.6.1","class" => "server","file" => "goserver.schema"),
+        "goServer"              => array("version" => "2.6.1", "class" => "server","file" => "goserver.schema"),
         "goTerminalServer"      => array("version" => "2.6.1", "class" => "terminals","file" => "goto.schema"),
         "goShareServer"         => array("version" => "2.6.1", "class" => "terminals","file" => "goto.schema"),
         "goNtpServer"           => array("version" => "2.6.1", "class" => "terminals","file" => "goto.schema"),
         "goSyslogServer"        => array("version" => "2.6.1", "class" => "terminals","file" => "goto.schema"),
-        "goLdapServer"          => array("version" => "2.6.1"),
+        "goLdapServer"          => array("version" => "2.6.1", "class" => "goServer"),
         "goCupsServer"          => array("version" => "2.6.1", "class" => array("posixAccount", "terminals"),),
-        "goImapServer"          => array("version" => "2.6.1", "class" => array("mailAccount", "mailgroup"),"file" => "gosa+samba3.        schema"),
-        "goKrbServer"           => array("version" => "2.6.1"),
+        "goImapServer"          => array("version" => "2.6.1", "class" => array("mailAccount", "mailgroup"),"file" => "gosa-samba3.schema"),
+        "goKrbServer"           => array("version" => "2.6.1", "class" => "goServer"),
         "goFaxServer"           => array("version" => "2.6.1", "class" => "gofaxAccount","file" => "gofax.schema"),
         ) as $name => $values){
 
@@ -2285,26 +2291,25 @@ function check_schema($cfg,$rfc2307bis = FALSE)
           if(isset($values['file'])){
             $checks[$name]["SCHEMA_FILES"] = array($values['file']);
           }
-          $checks[$name]["CLASSES_REQUIRED"] = array($name);
+          if (isset($values['class'])) {
+            $checks[$name]["CLASSES_REQUIRED"] = is_array($values['class'])?$values['class']:array($values['class']);
+          }
         }
   foreach($checks as $name => $value){
     foreach($value['CLASSES_REQUIRED'] as $class){
 
       if(!isset($objectclasses[$name])){
-        $checks[$name]['STATUS'] = FALSE;
         if($value['IS_MUST_HAVE']){
+          $checks[$name]['STATUS'] = FALSE;
           $checks[$name]['MSG']    = sprintf(_("Missing required object class '%s'!"),$class);
-        }else{
+        } else {
+          $checks[$name]['STATUS'] = TRUE;
           $checks[$name]['MSG']    = sprintf(_("Missing optional object class '%s'!"),$class);
         }
       }elseif(!check_schema_version($objectclasses[$name],$value['REQUIRED_VERSION'])){
         $checks[$name]['STATUS'] = FALSE;
 
-        if($value['IS_MUST_HAVE']){
-          $checks[$name]['MSG'] = sprintf(_("Version mismatch for required object class '%s' (!=%s)!"), $class,                           $value['REQUIRED_VERSION']);
-        }else{
-          $checks[$name]['MSG'] = sprintf(_("Version mismatch for optional object class '%s' (!=%s)!"), $class,                           $value['REQUIRED_VERSION']);
-        }
+        $checks[$name]['MSG'] = sprintf(_("Version mismatch for required object class '%s' (!=%s)!"), $class,                           $value['REQUIRED_VERSION']);
       }else{
         $checks[$name]['STATUS'] = TRUE;
         $checks[$name]['MSG'] = sprintf(_("Class(es) available"));
@@ -2317,7 +2322,7 @@ function check_schema($cfg,$rfc2307bis = FALSE)
   /* The gosa base schema */
   $checks['posixGroup'] = $def_check;
   $checks['posixGroup']['REQUIRED_VERSION'] = "2.6.1";
-  $checks['posixGroup']['SCHEMA_FILES']     = array("gosa+samba3.schema","gosa.schema");
+  $checks['posixGroup']['SCHEMA_FILES']     = array("gosa-samba3.schema","gosa-samba2.schema");
   $checks['posixGroup']['CLASSES_REQUIRED'] = array("posixGroup");
   $checks['posixGroup']['STATUS']           = TRUE;
   $checks['posixGroup']['IS_MUST_HAVE']     = TRUE;
@@ -2592,17 +2597,11 @@ function generate_smb_nt_hash($password)
 
   list($lm,$nt)= split (":", trim($hash));
 
-  if ($config->get_cfg_value("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');
-  }
+  $attrs['sambaLMPassword']= $lm;
+  $attrs['sambaNTPassword']= $nt;
+  $attrs['sambaPwdLastSet']= date('U');
+  $attrs['sambaBadPasswordCount']= "0";
+  $attrs['sambaBadPasswordTime']= "0";
   return($attrs);
 }
 
@@ -2836,5 +2835,173 @@ function isIpInNet($ip, $net, $mask) {
 }
 
 
+function get_next_id($attrib, $dn)
+{
+  global $config;
+
+  switch ($config->get_cfg_value("idAllocationMethod", "traditional")){
+    case "pool":
+      return get_next_id_pool($attrib);
+    case "traditional":
+      return get_next_id_traditional($attrib, $dn);
+  }
+
+  msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("unknown idAllocation method!"), ERROR_DIALOG);
+  return null;
+}
+
+
+function get_next_id_pool($attrib) {
+  global $config;
+
+  /* Fill informational values */
+  $min= $config->get_cfg_value("${attrib}PoolMin", 10000);
+  $max= $config->get_cfg_value("${attrib}PoolMax", 40000);
+
+  /* Sanity check */
+  if ($min >= $max) {
+    msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." ".sprintf(_("%sPoolMin >= %sPoolMax!"), $attrib), ERROR_DIALOG);
+    return null;
+  }
+
+  /* ID to skip */
+  $ldap= $config->get_ldap_link();
+  $id= null;
+
+  /* Try to allocate the ID several times before failing */
+  $tries= 3;
+  while ($tries--) {
+
+    /* Look for ID map entry */
+    $ldap->cd ($config->current['BASE']);
+    $ldap->search ("(&(objectClass=sambaUnixIdPool)($attrib=*))", array("$attrib"));
+
+    /* If it does not exist, create one with these defaults */
+    if ($ldap->count() == 0) {
+      /* Fill informational values */
+      $minUserId= $config->get_cfg_value("uidPoolMin", 10000);
+      $minGroupId= $config->get_cfg_value("gidPoolMin", 10000);
+
+      /* Add as default */
+      $attrs= array("objectClass" => array("organizationalUnit", "sambaUnixIdPool"));
+      $attrs["ou"]= "idmap";
+      $attrs["uidNumber"]= $minUserId;
+      $attrs["gidNumber"]= $minGroupId;
+      $ldap->cd("ou=idmap,".$config->current['BASE']);
+      $ldap->add($attrs);
+      if ($ldap->error != "Success") {
+        msg_dialog::display(_("Error"), _("Cannot create sambaUnixIdPool entry!"), ERROR_DIALOG);
+        return null;
+      }
+      $tries++;
+      continue;
+    }
+    /* Bail out if it's not unique */
+    if ($ldap->count() != 1) {
+      msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("sambaUnixIdPool is not unique!"), ERROR_DIALOG);
+      return null;
+    }
+
+    /* Store old attrib and generate new */
+    $attrs= $ldap->fetch();
+    $dn= $ldap->getDN();
+    $oldAttr= $attrs[$attrib][0];
+    $newAttr= $oldAttr + 1;
+
+    /* Sanity check */
+    if ($newAttr >= $max) {
+      msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("no ID available!"), ERROR_DIALOG);
+      return null;
+    }
+    if ($newAttr < $min) {
+      msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("no ID available!"), ERROR_DIALOG);
+      return null;
+    }
+
+    #FIXME: PHP is not able to do a modification of "del: .../add: ...", so this
+    #       is completely unsafe in the moment.
+    #/* Remove old attr, add new attr */
+    #$attrs= array($attrib => $oldAttr);
+    #$ldap->rm($attrs, $dn);
+    #if ($ldap->error != "Success") {
+    #  continue;
+    #}
+    $ldap->cd($dn);
+    $ldap->modify(array($attrib => $newAttr));
+    if ($ldap->error != "Success") {
+      msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." ".$ldap->get_error(), ERROR_DIALOG);
+      return null;
+    } else {
+      return $oldAttr;
+    }
+  }
+
+  /* Bail out if we had problems getting the next id */
+  if (!$tries) {
+    msg_dialog::display(_("Error"), _("Cannot allocate a free ID:")." "._("maximum tries exceeded!"), ERROR_DIALOG);
+  }
+
+  return $id;
+}
+
+function get_next_id_traditional($attrib, $dn)
+{
+  global $config;
+
+  $ids= array();
+  $ldap= $config->get_ldap_link();
+
+  $ldap->cd ($config->current['BASE']);
+  if (preg_match('/gidNumber/i', $attrib)){
+    $oc= "posixGroup";
+  } else {
+    $oc= "posixAccount";
+  }
+  $ldap->search ("(&(objectClass=$oc)($attrib=*))", array("$attrib"));
+
+  /* Get list of ids */
+  while ($attrs= $ldap->fetch()){
+    $ids[]= (int)$attrs["$attrib"][0];
+  }
+
+  /* Add the nobody id */
+  $ids[]= 65534;
+
+  /* get the ranges */
+  $tmp = array('0'=> 1000);
+  if (preg_match('/posixAccount/', $oc) && $config->get_cfg_value("uidNumberBase") != ""){
+    $tmp= split('-',$config->get_cfg_value("uidNumberBase"));
+  } elseif($config->get_cfg_value("gidNumberBase") != ""){
+    $tmp= split('-',$config->get_cfg_value("gidNumberBase"));
+  }
+
+  /* Set hwm to max if not set - for backward compatibility */
+  $lwm= $tmp[0];
+  if (isset($tmp[1])){
+    $hwm= $tmp[1];
+  } else {
+    $hwm= pow(2,32);
+  }
+  /* Find out next free id near to UID_BASE */
+  if ($config->get_cfg_value("baseIdHook") == ""){
+    $base= $lwm;
+  } else {
+    /* Call base hook */
+    $base= get_base_from_hook($dn, $attrib);
+  }
+  for ($id= $base; $id++; $id < pow(2,32)){
+    if (!in_array($id, $ids)){
+      return ($id);
+    }
+  }
+
+  /* Should not happen */
+  if ($id == $hwm){
+    msg_dialog::display(_("Error"), _("Cannot allocate a free ID!"), ERROR_DIALOG);
+    exit;
+  }
+}
+
+
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
 ?>