Code

Reverted 7503
[gosa.git] / include / functions_dns.inc
index 21f4fe60541445810b09db8205d8cb7ef31c5731..e1cda20a0af871f8972d184bdf70ac72d122c6ce 100644 (file)
@@ -28,6 +28,7 @@ $RecordTypes['sSHFPRecord']   = "sSHFPRecord";
 $RecordTypes['rRSIGRecord']   = "rRSIGRecord";      
 $RecordTypes['nSECRecord']    = "nSECRecord";       
 
+
 /* Return all record types 
  */
 function getDnsRecordTypes($ForZones = false)
@@ -45,9 +46,9 @@ function getDnsRecordTypes($ForZones = false)
 }
 
 
-/* this is used to flip the ip address for example
-   12.3.45  ->  54.3.12
-   Because some entries (like zones) are store like that 54.3.12.in-addr.arpa
+/* This fucntion is used to flip the ip address, for example
+   12.3.45  ->  45.3.12
+   Because some entries (like zones) are store like that 45.3.12.in-addr.arpa
    but we want to display 12.3.45.
  */
 function FlipIp($ip)
@@ -65,13 +66,12 @@ function FlipIp($ip)
  */
 function getDNSZoneEntries($config,$HostDn,$silent = false)
 {
-
   global $RecordTypes;
+
   $ldap = $config->get_ldap_link();
   $ldap->cd($config->current['BASE']); 
 
-  /* Not all records are allowen within a zone entry
+  /* Not all records are allowed within a zone entry
    */  
   $SkipRecords = array("tXTRecord","cNAMERecord","pTRRecord");
 
@@ -79,6 +79,10 @@ function getDNSZoneEntries($config,$HostDn,$silent = false)
    */
   $sOAREcords  = array("0"=>"sOAprimary","1"=>"sOAmail","2"=>"sOAserial","3"=>"sOArefresh","4"=>"sOAretry","5"=>"sOAexpire","6"=>"sOAttl");
 
+  /* Get host entry */
+  $ldap->cat($HostDn);
+  $host_attr = $ldap->fetch();
+
   /* Create tempalte for all fetched zone Data 
    */
   $ZoneBase = array();
@@ -105,21 +109,20 @@ function getDNSZoneEntries($config,$HostDn,$silent = false)
    */
   foreach($tmp_res as $attrs){
 
-    $zoneName                    = $attrs['zoneName'][0];
+    $zoneName                   = strtoupper($host_attr['cn'][0])."/".$attrs['zoneName'][0];
     $Zones[$zoneName]           = $ZoneBase;
     $Zones[$zoneName]['exists'] = true;
 
     /* Set basic attributes 
      */
-    foreach(array("zoneName","dNSClass") as $attr){
-      if(isset($attrs[$attr][0])){
-        $Zones[$zoneName][$attr] = $attrs[$attr][0];
-      }
+    if(isset($attrs["dNSClass"][0])){
+      $Zones[$zoneName]["dNSClass"] = $attrs["dNSClass"][0];
     }
 
-    /* Set initial zone name, to be able to detect if this entry is renamed 
+    /* Set initial zone name, to be able to detect if this entry was renamed 
      */
     $Zones[$zoneName]['InitialzoneName'] = $zoneName;
+    $Zones[$zoneName]['zoneName'] = $zoneName;
 
     /* Generate SOA entry
      */
@@ -173,8 +176,8 @@ function getDNSZoneEntries($config,$HostDn,$silent = false)
       unset($Zones[$zoneName]);
     }else{
       $tmp = $ldap->fetch();
-      $Zones[$zoneName]['ReverseZone'] FlipIp(str_replace(".in-addr.arpa","",$tmp['zoneName'][0]));
-      $Zones[$zoneName]['InitialReverseZone'] = FlipIp(str_replace(".in-addr.arpa","",$tmp['zoneName'][0]));
+      $Zones[$zoneName]['ReverseZone']        = strtoupper($host_attr['cn'][0])."/".FlipIp(str_replace(".in-addr.arpa","",$tmp['zoneName'][0]));
+      $Zones[$zoneName]['InitialReverseZone'] = strtoupper($host_attr['cn'][0])."/".FlipIp(str_replace(".in-addr.arpa","",$tmp['zoneName'][0]));
     }
   }
   return($Zones);
@@ -206,6 +209,9 @@ function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
   $zoneBase['dNSClass']           = "IN";
   $zoneBase['sOARecord']          = "";
 
+  /* Contains all renamed zoneNames 
+   * For zone entry udpdates
+   */
   $PrePareZoneEntries = array();
   
   /* Walk through all zones and detect renamed/added/deleted zones ... 
@@ -218,24 +224,24 @@ function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
       
       /* Move old zone to new position 
        */ 
-      $oldDn = "zoneName=".$zone['InitialzoneName'].",".$HostDn;
-      $newDn = "zoneName=".$zone['zoneName'].",".$HostDn;
-      $PrePareZoneEntries[$zone['InitialzoneName']] = $zone['zoneName'];
+      $oldDn = "zoneName=".getNameFromMix($zone['InitialzoneName']).",".$HostDn;
+      $newDn = "zoneName=".getNameFromMix($zone['zoneName']).",".$HostDn;
+      $PrePareZoneEntries[$zone['InitialzoneName']] = getNameFromMix($zone['zoneName']);
       $move [$oldDn] = $newDn;      
     }
 
     /* Get old zone if available
      */
     $oldZone=array();
-    if(isset($oldZones[$zone['InitialzoneName']])){
+    if(!empty($oldZones[$zone['InitialzoneName']])){
       $oldZone = $oldZones[$zone['InitialzoneName']];
     }
 
     /* Create forward zone entry and put it in our add queue
      */
-    $newDn  = "zoneName=".$zone['zoneName'].",".$HostDn;
+    $newDn  = "zoneName=".getNameFromMix($zone['zoneName']).",".$HostDn;
     $obj    =  $zoneBase;
-    $obj['zoneName'] = $zone['zoneName'];
+    $obj['zoneName'] = getNameFromMix($zone['zoneName']);
  
     /* Create sOARecord & add it to the obj
      */ 
@@ -244,14 +250,15 @@ function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
       $soa.=" ".$zone[$attr];
     }  
     $obj['sOARecord'] = trim($soa);
+    $obj['nSRecord'] = $zone['sOAprimary'];
 
     /* If reverse zone was renamed, move entry 
      */
     if(!empty($zone['InitialReverseZone'])){
       if($zone['InitialReverseZone'] != $zone['ReverseZone']){
-        $base = "zoneName=".$zone['zoneName'].",".$HostDn;
-        $oldRDn = "zoneName=". FlipIp($zone['InitialReverseZone']).".in-addr.arpa,".$base; 
-        $newRDn = "zoneName=". FlipIp($zone['ReverseZone']).".in-addr.arpa,".$base;
+        $base = "zoneName=".getNameFromMix($zone['zoneName']).",".$HostDn;
+        $oldRDn = "zoneName=". FlipIp(getNameFromMix($zone['InitialReverseZone'])).".in-addr.arpa,".$base; 
+        $newRDn = "zoneName=". FlipIp(getNameFromMix($zone['ReverseZone'])).".in-addr.arpa,".$base;
         $PrePareZoneEntries[FlipIp($zone['InitialReverseZone']).".in-addr.arpa"] = FlipIp($zone['ReverseZone']).".in-addr.arpa";
         $move [$oldRDn] = $newRDn;
       }
@@ -270,6 +277,9 @@ function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
     /* Add new Records 
      */
     foreach($zone['RECORDS'] as $rec){
+      if(!isset($obj[$rec['type']])||!is_array($obj[$rec['type']])){
+        $obj[$rec['type']] = array();
+      }
       $obj[$rec['type']][] = $rec['value'];
     }
 
@@ -280,8 +290,8 @@ function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
     /* Create Reverse Entry 
      * And append it to our add queue
      */
-    $zone['ReverseZone'] = FlipIp($zone['ReverseZone']).".in-addr.arpa";
-    $base = "zoneName=".$zone['zoneName'].",".$HostDn;
+    $zone['ReverseZone'] = FlipIp(getNameFromMix($zone['ReverseZone'])).".in-addr.arpa";
+    $base = "zoneName=".getNameFromMix($zone['zoneName']).",".$HostDn;
     $newRDn = "zoneName=".$zone['ReverseZone'].",".$base;
     $rObj = $obj;
     $rObj['zoneName']= $zone['ReverseZone'];
@@ -296,11 +306,11 @@ function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
   }
  
   /* The rest of our oldZones must be deleted
-   *  because they wern't available in newZones anymore.
+   *  because they are no longer available in newZones anymore.
    */
   foreach($oldZones as $zone)  {
-    $oldDn = "zoneName=".$zone['InitialzoneName'].",".$HostDn;
-    $del[$oldDn] = "";
+    $oldDn = "zoneName=".getNameFromMix($zone['InitialzoneName']).",".$HostDn;
+    $del[$oldDn] = $zone;
   }
 
   /* Check for entries which must be updated 
@@ -311,7 +321,7 @@ function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
     $ldap = $config->get_ldap_link();
     foreach($PrePareZoneEntries as $FromZoneName => $ToZoneName){
       $ldap->cd($HostDn);
-      $ldap->search("(&(objectClass=dNSZone)(zoneName=".$FromZoneName.")(!(relativeDomainName=@)))",array("zoneName"));
+      $ldap->search("(&(objectClass=dNSZone)(zoneName=".getNameFromMix($FromZoneName).")(!(relativeDomainName=@)))",array("zoneName"));
       while($attrs = $ldap->fetch()){
         $zoneUpdates[$attrs['dn']] = array("zoneName"=>$ToZoneName);
       }
@@ -346,18 +356,27 @@ function getDNSHostEntries($config,$name,$silent = false)
    */
   $foundIn = array();
   $zones = getAvailableZones($config);
-  foreach($zones as $zone){
-    $zoneDn = getDNSZoneDN($config,$zone);
-    $ldap->ls("(&(objectClass=dNSZone)(zoneName=*)(relativeDomainName=".$name.")(!(relativeDomainName=@)))", $zoneDn,$attrs = array("*"));
-    while($attrs = $ldap->fetch()){
-      $foundIn [] = $attrs['dn'];
+  
+  $zonesArr = array();
+  foreach($zones as $zoneMix){
+       $zoneIndex = split("/",$zoneMix);
+       if(!array_key_exists($zoneIndex[0],$zonesArr)) {
+      $zonesArr[$zoneIndex[0]] = array();
     }
+               array_push($zonesArr[$zoneIndex[0]],$zoneIndex[1]);
   }
-
-  /* Alert if there is more than one zone with an entry named like $name
-   */ 
-  if((count($foundIn) > 1) && (!$silent)) {
-    print_red(sprintf(_("Found more than one dns zone which contains an entry named '%s'. Aborting getting dns informations for this device."),$name));
+  
+  foreach($zonesArr as $nameServer => $nameServerArr){
+       $foundInTmp = array();
+       foreach($nameServerArr as $zoneArr => $zone){
+               $zoneMix = $nameServer."/".$zone;
+       $zoneDn = getDNSZoneDN($config,$zoneMix);
+       $ldap->ls("(&(objectClass=dNSZone)(zoneName=*)(relativeDomainName=".$name.")(!(relativeDomainName=@)))", $zoneDn,$attrs = array("*"));
+       while($attrs = $ldap->fetch()){
+         $foundInTmp [$zoneMix] = $attrs['dn'];
+         $foundIn [$zoneMix] = $attrs['dn'];
+       }
+       }
   }
 
   /* No zone found which contains an entry for us
@@ -368,7 +387,8 @@ function getDNSHostEntries($config,$name,$silent = false)
 
   /* Get host informations from zone
    */ 
-  $ldap->cd($foundIn[0]);
+  $id_tmp = key($foundIn);
+  $ldap->cd($foundIn[$id_tmp]);
   $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("*"));
   while($attrs = $ldap->fetch()){
 
@@ -377,7 +397,8 @@ function getDNSHostEntries($config,$name,$silent = false)
      */
     if($attrs['relativeDomainName'][0] == $name){
       $ret['exists'] = true;
-      foreach(array("dNSClass","zoneName","dNSTTL") as $atr){
+      $ret['zoneName'] = $id_tmp;
+      foreach(array("dNSClass","dNSTTL") as $atr){
         if(isset($attrs[$atr][0])){
           $ret[$atr] = $attrs[$atr][0];
         }
@@ -421,24 +442,28 @@ function getDNSHostEntriesDiff($config,$oldName,$newEntry,$newName)
   $move   = array();
 
   $zones              = getAvailableZones($config);
-
   $specialAttributes  = array("cNAMERecord","pTRRecord");
-
   $newRecords         = array();  // Used to remember which records are removed 
-
-  $zoneName     = $newEntry['zoneName'];
-  $zoneDn       = getDNSZoneDN($config,$zoneName);
-  
-  $tmp          = array_flip($zones);
-  
-  if(isset($tmp[$zoneName])){
-    $reverseName  = $tmp[$zoneName];
-    $reverseDn    = getDNSZoneDN($config,$reverseName);
+  $zoneNameMix           = $newEntry['zoneName'];
+  $zoneDn             = getDNSZoneDN($config,$zoneNameMix);
+  $tmp                = array_flip($zones);
+  $zoneName                                    = getNameFromMix($zoneNameMix);
+  /* If reverseZone can't be resolved ... this 
+   *  can't be a valid entry, so remove this account
+   */ 
+  if(isset($tmp[$zoneNameMix])){
+    $reverseNameMix  = $tmp[$zoneNameMix];
+    $reverseDn    = getDNSZoneDN($config,$reverseNameMix);
+    if(empty($reverseDn)){
+      $newEntry['exists'] = false;
+    }
   }else{
     $newEntry['exists'] = false;
   }
 
   /* Don't go further if there is nothing to do
+   * Is no account / was no account
    */
   if(($newEntry['exists'] == false )&& ($oldEntry['exists'] == false)){
     return(array("move"=>$move,"add"=>$add,"del"=>$del));
@@ -460,36 +485,39 @@ function getDNSHostEntriesDiff($config,$oldName,$newEntry,$newName)
 
     /* Check if zoneName has changed 
      */   
-    if($oldEntry['zoneName'] != $newEntry['zoneName']){
-      $oldzoneDn = getDNSZoneDN($config,$oldEntry['zoneName']);
-      $dn = "relativeDomainName=".$oldName.",".$oldzoneDn;
-      $dn2= "relativeDomainName=".$oldName.",".$zoneDn;
-      $move[$dn]=$dn2;
-    }
+    if(count($newEntry['RECORDS'])){
+      if($oldEntry['zoneName'] != $newEntry['zoneName']){
+        $oldzoneDn = getDNSZoneDN($config,$oldEntry['zoneName']);
+        $dn = "relativeDomainName=".$oldName.",".$oldzoneDn;
+        $dn2= "relativeDomainName=".$oldName.",".$zoneDn;
+        $move[$dn]=$dn2;
+      }
 
-    /* Check if host name has changed 
-     */ 
-    if($oldName != $newName){
-      $dn = "relativeDomainName=".$oldName.",".$zoneDn;
-      $dn2= "relativeDomainName=".$newName.",".$zoneDn;
-      $move[$dn]=$dn2;
-      $dn = "relativeDomainName=".$oldName.",".$dn2;
-      $dn2= "relativeDomainName=".$newName.",".$dn2;
-      $move[$dn]=$dn2;
+      /* Check if host name has changed 
+       */ 
+      if($oldName != $newName){
+        $dn = "relativeDomainName=".$oldName.",".$zoneDn;
+        $dn2= "relativeDomainName=".$newName.",".$zoneDn;
+        $move[$dn]=$dn2;
+        $dn = "relativeDomainName=".$oldName.",".$dn2;
+        $dn2= "relativeDomainName=".$newName.",".$dn2;
+        $move[$dn]=$dn2;
+      }
     }
-    
-    /* Prepare record entries 
-    */
+
+    /* Prepare record entries
+     *  Fill old records with array();
+     *  To ensure that they will be deleted if they stay unused
+     */
     foreach($oldEntry['RECORDS'] as $id => $rec){
       $newRecords[$rec['type']] = array();
     }
   }
 
-
   /* There must be at least one record in our entry  
    */
   if((!count($newEntry['RECORDS'])) || (!$newEntry['exists'])){
-    $dn = "relativeDomainName=".$oldName.",".getDNSZoneDN($config,$oldEntry['zoneName']);
+    $dn = "relativeDomainName=".$newName.",".getDNSZoneDN($config,$oldEntry['zoneName']);
     $del[$dn] ="";
     $ret = array("move"=>$move,"add"=>$add,"del"=>$del);
     return($ret);
@@ -542,19 +570,24 @@ function getDNSHostEntriesDiff($config,$oldName,$newEntry,$newName)
      *  like pTRRecord or CNAMERecord
      */
     if($rec['type']  == "pTRRecord"){
-      $PTRdn= "relativeDomainName=".$rec['value'].",".$baseDn;
+      $PTRdn= "relativeDomainName=".FlipIP($rec['value']).",".$baseDn;
       $ptrObj = $baseObj;
+      $reverseName = getNameFromMix($reverseNameMix);
       $ptrObj['zoneName']           = $reverseName;
-      $ptrObj['pTRRecord']          = $newName.".".$zoneName;
-      $ptrObj['relativeDomainName'] = $rec['value'];
-      
+      if(!preg_match("/\.$/",$newName)){
+        $ptrObj['pTRRecord']          = preg_replace("/\.\.$/",".",$newName.".".$zoneName.".");
+      }else{
+        $ptrObj['pTRRecord']          = preg_replace("/\.\.$/",".",$newName.".");
+      }
+      $ptrObj['relativeDomainName'] = FlipIP($rec['value']);
+    
       $add[$PTRdn] = $ptrObj;
     }else  
     if($rec['type']  == "cNAMERecord"){
       $PTRdn= "relativeDomainName=".$rec['value'].",".$baseDn;
       $ptrObj = $baseObj;
-      $ptrObj['zoneName']           = $reverseName;
-      $ptrObj['cNAMERecord']        = $newName.".".$zoneName;
+      $ptrObj['zoneName']           = $zoneName;
+      $ptrObj['cNAMERecord']        = $newName;
       $ptrObj['relativeDomainName'] = $rec['value'];
       
       $add[$PTRdn] = $ptrObj;
@@ -569,18 +602,44 @@ function getDNSHostEntriesDiff($config,$oldName,$newEntry,$newName)
   return($ret);
 } 
 
+function getNameFromMix($zoneMix){
+       $ret = "";
+  if(!strstr($zoneMix, '/')) return($ret);     
+  $zoneIndex           = split("/",$zoneMix);
+  return($zoneIndex[1]);
+}
 
 /* returns the dn for a specified zone
  */
-function getDNSZoneDN($config,$zoneName){
+function getDNSZoneDN($config,$zoneNameMix)
+{
   $ret = "";
-  $ldap = $config->get_ldap_link();
+  if(!strstr($zoneNameMix, '/')) {
+    print_red(sprintf(_("Undefined zone name '%s'. Zone name must look like this 'server/zone.com'."),$zoneNameMix));
+    return($ret);
+  }
+
+  $zoneNameIndex               = split("/",$zoneNameMix); 
+  $zoneName           = $zoneNameIndex[1];
+  $nameServer                          = strtolower($zoneNameIndex[0]);
+  $ldap               = $config->get_ldap_link();
+
+  /* search for the nameserver */
   $ldap-> cd($config->current['BASE']);
+  $ldap->search("(&(objectClass=goServer)(cn=".$nameServer."))",array("cn"));
+  if($ldap->count()){
+    $attr = $ldap->fetch();
+  } else {
+    return($ret);
+  }
+  
+  $ldap-> cd($attr['dn']);
   $ldap->search("(&(objectClass=dNSZone)(sOARecord=*)(zoneName=".$zoneName."))",array("zoneName"));
   if($ldap->count()){
     $attr = $ldap->fetch();
     return($attr['dn']);
   }
+  
   return($ret);
 }
 
@@ -594,8 +653,6 @@ function getAvailableZones($config)
   $ldap = $config->get_ldap_link();
   $ldap->cd ($config->current['BASE']);
 
-  restore_error_handler();
-
   /* Search for zones ...
    */
   $ldap->search("(&(objectClass=dNSZone)(sOARecord=*))",array("zoneName"));
@@ -618,9 +675,10 @@ function getAvailableZones($config)
      */  
     foreach($ReverseZones as $Rdn => $Robj ){
       if(preg_match("/".$dn."/",$Rdn)){
-        $zones[$Robj['zoneName'][0]] =  $obj['zoneName'][0];
+        $zones[strtoupper($ldap->getCn($dn))."/".$Robj['zoneName'][0]] =  
+                       strtoupper($ldap->getCn($dn))."/".$obj['zoneName'][0];
       }
-    }
+    }   
   }
   return($zones);
 }