Code

Replaced in_array calls with in_array_strict
[gosa.git] / gosa-plugins / dns / admin / systems / services / dns / class_DNS.inc
1 <?php
3 class DNS
4 {
5     static $RecordTypes= array('aRecord' => "aRecord",
6             'mDRecord'      => "mDRecord",         
7             'mXRecord'      => "mXRecord",         
8             'nSRecord'      => "nSRecord",          
9             'pTRRecord'     => "relativeDomainName",
10             'hInfoRecord'   => "hInfoRecord",      
11             'mInfoRecord'   => "mInfoRecord",       
12             'cNAMERecord'   => "relativeDomainName",
13             'tXTRecord'     => "tXTRecord",         
14             'aFSDBRecord'   => "aFSDBRecord",       
15             'SigRecord'     => "SigRecord",         
16             'KeyRecord'     => "KeyRecord",         
17             'aAAARecord'    => "aAAARecord",        
18             'LocRecord'     => "LocRecord",         
19             'nXTRecord'     => "nXTRecord",        
20             'sRVRecord'     => "sRVRecord",         
21             'nAPTRRecord'   => "nAPTRRecord",       
22             'kXRecord'      => "kXRecord",          
23             'certRecord'    => "certRecord",        
24             'a6Record'      => "a6Record",          
25             'dSRecord'      => "dSRecord",          
26             'sSHFPRecord'   => "sSHFPRecord",       
27             'rRSIGRecord'   => "rRSIGRecord",      
28             'nSECRecord'    => "nSECRecord");
29     /* All available record types */
30     /* Return all record types 
31      */
32     static function getDnsRecordTypes($ForZones = false)
33     {
34         if($ForZones){
35             $tmp = DNS::$RecordTypes;
36             unset($tmp['cNAMERecord']);
37             unset($tmp['pTRRecord']);
38             unset($tmp['tXTRecord']);
39             return($tmp);
40         }else{
41             return(DNS::$RecordTypes);
42         }
43     }
46     /* This fucntion is used to flip the ip address, for example
47        12.3.45  ->  45.3.12
48        Because some entries (like zones) are store like that 45.3.12.in-addr.arpa.
49        but we want to display 12.3.45.
50      */
51     static function FlipIp($ip)
52     {
53         $tmp = array_reverse(explode(".",$ip));
54         $new = "";
55         foreach($tmp as $section){
56             $new .= $section.".";
57         }
58         return(preg_replace("/.$/","",$new));
59     }
62     /* This static function returns the zones specified for given host
63      */
64     static function getDNSZoneEntries($config,$HostDn,$silent = false)
65     {
66         $ldap = $config->get_ldap_link();
67         $ldap->cd($config->current['BASE']); 
69         /* Not all records are allowed within a zone entry
70          */  
71         $SkipRecords = array("tXTRecord","cNAMERecord","pTRRecord");
73         /* Special sOArecords 
74          */
75         $sOAREcords  = array("0"=>"sOAprimary","1"=>"sOAmail","2"=>"sOAserial","3"=>"sOArefresh","4"=>"sOAretry","5"=>"sOAexpire","6"=>"sOAttl");
77         /* Create tempalte for all fetched zone Data 
78          */
79         $ZoneBase = array();
80         $ZoneBase['exists']  = false;
81         $ZoneBase['RECORDS'] = array();
82         $ZoneBase['zoneName'] = array();
83         $ZoneBase['dNSClass'] = array();
85         foreach($sOAREcords as $attr){
86             $ZoneBase[$attr] = "";
87         }
89         $Zones    = array();
91         /* Get & Parse all zone entries 
92          */
93         $ldap->ls("(&(objectClass=dNSZone)(zoneName=*)(relativeDomainName=@))",$HostDn,array("*"));
94         $tmp_res = array();
95         while($attrs = $ldap->fetch()) {
96             $tmp_res[] = $attrs;
97         }
99         /* Parse fetched zones 
100          */
101         foreach($tmp_res as $attrs){
103             $zoneName                   = $attrs['zoneName'][0];
104             $Zones[$zoneName]           = $ZoneBase;
105             $Zones[$zoneName]['exists'] = true;
107             /* Set basic attributes 
108              */
109             foreach(array("zoneName","dNSClass") as $attr){
110                 if(isset($attrs[$attr][0])){
111                     $Zones[$zoneName][$attr] = $attrs[$attr][0];
112                 }
113             }
115             /* Set initial zone name, to be able to detect if this entry was renamed 
116              */
117             $Zones[$zoneName]['InitialzoneName'] = $zoneName;
119             /* Generate SOA entry
120              */
121             if(isset($attrs['sOARecord'][0])){
122                 $tmp = explode(" ",$attrs['sOARecord'][0]) ;
123                 $tmp2 = array();
125                 /* Assign soa vars */
126                 foreach($sOAREcords as $key => $name){
127                     if(isset($tmp[$key])){
128                         $Zones[$zoneName][$name] = $tmp[$key];
129                     }else{
130                         $Zones[$zoneName][$name] = "";
131                     }
132                 }
133             } // ENDE SOA Record 
135             /* Get record attributes 
136              */
137             foreach(DNS::$RecordTypes as $name => $value){
139                 /* Skip some attributes 
140                  */
141                 if(in_array_strict($name,$SkipRecords)) continue;
143                 /* If there is a record attribute
144                  */
145                 if(isset($attrs[$name])){
147                     /* get all entries
148                      */
149                     for($i = 0 ; $i < $attrs[$value]['count']; $i ++){
150                         $Zones[$zoneName]['RECORDS'][] =  array("type"=>$name,"value"=>$attrs[$value][$i]);
151                     }
152                 }
153             }
155             /* Get reverse record ..
156              */
157             $ldap->ls("(&(objectClass=dNSZone)(relativeDomainName=@)(zoneName=*))",$attrs['dn'],array("zoneName"));
159             if($ldap->count() == 0){
160                 if(!$silent){
161                     msg_dialog::display(_("Error"), sprintf(_("Cannot find reverse zone for DNS zone '%s'. Parsing zone aborted."),$zoneName), ERROR_DIALOG);
162                 }
163                 unset($Zones[$zoneName]);
164             }elseif($ldap->count()>1){
165                 if(!$silent){
166                     msg_dialog::display(_("Error"), sprintf(_("Found more than one reverse zone for '%s'. Parsing zone aborted."),$zoneName), ERROR_DIALOG);
167                 }
168                 unset($Zones[$zoneName]);
169             }else{
170                 $tmp = $ldap->fetch();
171                 $Zones[$zoneName]['ReverseZone']        = DNS::FlipIp(str_replace(".in-addr.arpa.","",$tmp['zoneName'][0]));
172                 $Zones[$zoneName]['InitialReverseZone'] = DNS::FlipIp(str_replace(".in-addr.arpa.","",$tmp['zoneName'][0]));
173             }
174         }
175         return($Zones);
176     }
179     /* This static function compares two dns zone objects and returns an 
180      *  array with following indexes 
181      *   - delete, for dns which must be deleted (only if dns zone is removed)
182      *   - rename, if a dn must be renamed, for example, the zoneName has changed
183      *   - add,    if there is a new dns account created    
184      */
185     static function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
186     {
187         $oldZones = DNS::getDNSZoneEntries($config,$HostDn,true);
189         $sOAattributes =  array("sOAprimary","sOAmail","sOAserial","sOArefresh","sOAretry","sOAexpire","sOAttl");
191         $move   = array();
192         $add    = array();
193         $del    = array();
195         /* Generate a template for zones with default values
196          */
197         $zoneBase                       = array();
198         $zoneBase['objectClass']        = array("top","dNSZone");
199         $zoneBase['zoneName']           = "";
200         $zoneBase['relativeDomainName'] = "@";
201         $zoneBase['dNSClass']           = "IN";
202         $zoneBase['sOARecord']          = "";
204         /* Contains all renamed zoneNames 
205          * For zone entry udpdates
206          */
207         $PrePareZoneEntries = array();
209         /* Walk through all zones and detect renamed/added/deleted zones ... 
210          */
211         foreach($newZones as $name => $zone){
213             /* This zone was renamed 
214              */
215             if((!empty($zone['InitialzoneName'])) && ($zone['InitialzoneName'] != $zone['zoneName'])){
217                 /* Move old zone to new position 
218                  */ 
219                 $oldDn = "zoneName=".$zone['InitialzoneName'].",".$HostDn;
220                 $newDn = "zoneName=".$zone['zoneName'].",".$HostDn;
221                 $PrePareZoneEntries[$zone['InitialzoneName']] = $zone['zoneName'];
222                 $move [$oldDn] = $newDn;      
223             }
225             /* Get old zone if available
226              */
227             $oldZone=array();
228             if(!empty($oldZones[$zone['InitialzoneName']])){
229                 $oldZone = $oldZones[$zone['InitialzoneName']];
230             }
232             /* Create forward zone entry and put it in our add queue
233              */
234             $newDn  = "zoneName=".$zone['zoneName'].",".$HostDn;
235             $obj    =  $zoneBase;
236             $obj['zoneName'] = $zone['zoneName'];
238             /* Create sOARecord & add it to the obj
239              */ 
240             $soa = "";
241             foreach($sOAattributes as $attr){
242                 $soa.=" ".$zone[$attr];
243             }  
244             $obj['sOARecord'] = trim($soa);
245             $obj['nSRecord'] = $zone['sOAprimary'];
247             /* If reverse zone was renamed, move entry 
248              */
249             if(!empty($zone['InitialReverseZone'])){
250                 if($zone['InitialReverseZone'] != $zone['ReverseZone']){
251                     $base = "zoneName=".$zone['zoneName'].",".$HostDn;
252                     $oldRDn = "zoneName=". DNS::FlipIp($zone['InitialReverseZone']).".in-addr.arpa.,".$base; 
253                     $newRDn = "zoneName=". DNS::FlipIp($zone['ReverseZone']).".in-addr.arpa.,".$base;
254                     $PrePareZoneEntries[DNS::FlipIp($zone['InitialReverseZone']).".in-addr.arpa."] = DNS::FlipIp($zone['ReverseZone']).".in-addr.arpa.";
255                     $move [$oldRDn] = $newRDn;
256                 }
257             }
259             /* Append record entries 
260              *  Set old value to array, to ensure that 
261              *  they will be deleted if necessary
262              */
263             if(isset($oldZone['RECORDS'])){
264                 foreach($oldZone['RECORDS'] as $rec){
265                     $obj[$rec['type']] = array();
266                 }
267             }
269             /* Add new Records 
270              */
271             foreach($zone['RECORDS'] as $rec){
272                 if(!isset($obj[$rec['type']])||!is_array($obj[$rec['type']])){
273                     $obj[$rec['type']] = array();
274                 }
275                 $obj[$rec['type']][] = $rec['value'];
276             }
278             /* Append udpated Zone Forward Entry to our add queue
279              */    
280             $add[$newDn] = $obj;   
282             /* Create Reverse Entry 
283              * And append it to our add queue
284              */
285             $zone['ReverseZone'] = DNS::FlipIp($zone['ReverseZone']).".in-addr.arpa.";
286             $base = "zoneName=".$zone['zoneName'].",".$HostDn;
287             $newRDn = "zoneName=".$zone['ReverseZone'].",".$base;
288             $rObj = $obj;
289             $rObj['zoneName']= $zone['ReverseZone'];
290             $add[$newRDn] = $rObj;
292             /* Remove currently managed zone from oldZones.
293              *  this gives us the ability to detect removed zones
294              */
295             if(isset($oldZones[$zone['InitialzoneName']])){
296                 unset($oldZones[$zone['InitialzoneName']]); 
297             }
298         }
300         /* The rest of our oldZones must be deleted
301          *  because they are no longer available in newZones anymore.
302          */
303         foreach($oldZones as $zone)  {
304             $oldDn = "zoneName=".$zone['InitialzoneName'].",".$HostDn;
305             $del[$oldDn] = $zone;
306         }
308         /* Check for entries which must be updated 
309          */
310         $zoneUpdates = array();
311         $udpate = array();
312         if(count($PrePareZoneEntries)){
313             $ldap = $config->get_ldap_link();
314             foreach($PrePareZoneEntries as $FromZoneName => $ToZoneName){
315                 $ldap->cd($HostDn);
316                 $ldap->search("(&(objectClass=dNSZone)(zoneName=".$FromZoneName.")(!(relativeDomainName=@)))",array("zoneName"));
317                 while($attrs = $ldap->fetch()){
318                     $zoneUpdates[$attrs['dn']] = array("zoneName"=>$ToZoneName);
319                 }
320             }
321         }
323         $ret = array("del" => $del , "move" => $move , "add" => $add,"zoneUpdates"=>$zoneUpdates);
324         return($ret);
325     }
328     /* This static function returns the dns-host eintries for given 
329      *  name.
330      */
331     static function getDNSHostEntries($config,$name,$silent = false)
332     {
333         $types = array();
334         $ret = array();
335         $ret['RECORDS']   = array();
336         $ret['dNSClass']  = "IN";
337         $ret['zoneName']  = "";
338         $ret['dNSTTL']    = "";
339         $ret['exists']    = false;
341         $ldap = $config->get_ldap_link();
342         $ldap->cd($config->current['BASE']);
344         /* First check all zones for an entry with the given name.
345          * If the name occurs in more than one entry alert the user ...
346          */
347         $foundIn = array();
348         $zones = DNS::getAvailableZones($config);
349         $zonesArr = array();
350         foreach($zones as $zoneMix){
351             $zoneIndex = explode("/",$zoneMix);
352             if(!array_key_exists($zoneIndex[0],$zonesArr)) {
353                 $zonesArr[$zoneIndex[0]] = array();
354             }
355             array_push($zonesArr[$zoneIndex[0]],$zoneIndex[1]);
356         }
358         foreach($zonesArr as $nameServer => $nameServerArr){
359             $foundInTmp = array();
360             foreach($nameServerArr as $zoneArr => $zone){
362                 /* Strip eventually domain part from hostname 
363                  */
364                 $zN = trim($zone,".");
365                 $nN = trim($name,".");  
366                 if(preg_match("/".preg_quote($zN, '/')."$/",$nN)){
367                     $nN = preg_replace("/[\.]*".preg_quote($zN, '/')."[\.]*$/","",$nN);
368                 }else{
369                     $nN = $name;
370                 }
371                 $zoneMix = $nameServer."/".$zone;
372                 $zoneDn = DNS::getDNSZoneDN($config,$zoneMix);
373                 $ldap->ls("(&(objectClass=dNSZone)(zoneName=*)(relativeDomainName=".$nN.")(!(relativeDomainName=@)))", $zoneDn,$attrs = array("*"));
374                 while($attrs = $ldap->fetch()){
375                     $foundInTmp [$zoneMix] = $attrs['dn'];
376                     $foundIn [$zoneMix] = $attrs['dn'];
377                 }
378             }
379         }
381         /* No zone found which contains an entry for us
382          */
383         if(count($foundIn) == 0){
384             return($ret);
385         }
387         /* Get host informations from zone
388          */ 
389         $id_tmp = key($foundIn);
390         $ldap->cd($foundIn[$id_tmp]);
391         $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("*"));
392         while($attrs = $ldap->fetch()){
394             /* Strip eventually domain part from hostname 
395              */
396             $zN = trim($attrs['zoneName'][0],".");
397             $nN = trim($name,"."); 
398             $testname = $attrs['relativeDomainName'][0].".".$zN;
400             /* Check given host name with zone settings 
401              */ 
402             if(preg_match("/".preg_quote($testname, '/')."[\.]*$/",$nN) || $attrs['relativeDomainName'][0] == $name){
403                 $ret['exists'] = true;
404                 $ret['zoneName'] = $id_tmp;
405                 foreach(array("dNSClass","dNSTTL") as $atr){
406                     if(isset($attrs[$atr][0])){
407                         $ret[$atr] = $attrs[$atr][0];
408                     }
409                 }
410             }
412             /* Create list with all used records */
413             foreach(DNS::$RecordTypes as $name => $value){
415                 /* If there is a record attribute  */
416                 if(isset($attrs[$name])){
418                     /* get all entries */
419                     for($i = 0 ; $i < $attrs[$value]['count']; $i ++){
420                         $types[] = array( "type"    => $name,
421                                 "value"   => $attrs[$value][$i]);
422                     }
423                 }
424             }
425             $ret['RECORDS'] = $types;
426         }
427         return($ret);
428     }  
432     /* This static function compares two dns settings and returns an 
433      *  array with following indexes 
434      *   - delete, for dns which must be deleted (only if dns account is removed)
435      *   - rename, if a dn must be renamed, for example, the relativeDomainName has changed
436      *   - add,    if there is a new dns account created    
437      */
438     static function getDNSHostEntriesDiff($config,$oldName,$newEntry,$newName)
439     {
440         $oldEntry = DNS::getDNSHostEntries($config,$oldName);
442         $add    = array();
443         $del    = array();
444         $move   = array();
446         /* Don't go further if there is nothing to do
447          * Is no account / was no account
448          */
449         if(($newEntry['exists'] == false )&& ($oldEntry['exists'] == false)){
450             return(array("move"=>$move,"add"=>$add,"del"=>$del));
451         }
453         $zones              = DNS::getAvailableZones($config);
454         $specialAttributes  = array("cNAMERecord","pTRRecord");
455         $newRecords         = array();  // Used to remember which records are removed 
456         $zoneNameMix           = $newEntry['zoneName'];
457         $zoneDn             = DNS::getDNSZoneDN($config,$zoneNameMix);
458         $tmp                = array_flip($zones);
459         $zoneName                                       = DNS::getNameFromMix($zoneNameMix);
461         /* Strip domain part out of dns host entry 
462          */
463         $zN = trim($zoneName,".");
464         $nN = trim($newName,".");
465         $oN = trim($oldName,".");
466         $newName = preg_replace("/[\.]*".preg_quote($zN, '/')."$/i","",$nN);
467         $oldName = preg_replace("/[\.]*".preg_quote($zN, '/')."$/i","",$oN);
469         /* If reverseZone can't be resolved ... this 
470          *  can't be a valid entry, so remove this account
471          */ 
472         if(isset($tmp[$zoneNameMix])){
473             $reverseNameMix  = $tmp[$zoneNameMix];
474             $reverseDn    = DNS::getDNSZoneDN($config,$reverseNameMix);
475             if(empty($reverseDn)){
476                 $newEntry['exists'] = false;
477             }
478         }else{
479             $newEntry['exists'] = false;
480         }
482         /* If account was edited prepare some
483          *  attributes & arrays ... if required add some 
484          *  dns to $move 
485          */
486         if($oldEntry['exists']){
488             /* Check if the account was removed 
489              */
490             if($newEntry['exists'] == false){
491                 $dn = "relativeDomainName=".$oldName.",".DNS::getDNSZoneDN($config,$oldEntry['zoneName']);
492                 $del[$dn] ="";
493                 return(array("move"=>$move,"add"=>$add,"del"=>$del));
494             }
496             /* Check if zoneName has changed 
497              */   
498             if(count($newEntry['RECORDS'])){
499                 if($oldEntry['zoneName'] != $newEntry['zoneName']){
500                     $oldzoneDn = DNS::getDNSZoneDN($config,$oldEntry['zoneName']);
501                     $dn = "relativeDomainName=".$oldName.",".$oldzoneDn;
502                     $dn2= "relativeDomainName=".$oldName.",".$zoneDn;
503                     $move[$dn]=$dn2;
504                 }
506                 /* Check if host name has changed 
507                  */ 
508                 if($oldName != $newName){
509                     $dn = "relativeDomainName=".$oldName.",".$zoneDn;
510                     $dn2= "relativeDomainName=".$newName.",".$zoneDn;
511                     $move[$dn]=$dn2;
512                     $dn = "relativeDomainName=".$oldName.",".$dn2;
513                     $dn2= "relativeDomainName=".$newName.",".$dn2;
514                     $move[$dn]=$dn2;
515                 }
516             }
518             /* Prepare record entries
519              *  Fill old records with array();
520              *  To ensure that they will be deleted if they stay unused
521              */
522             foreach($oldEntry['RECORDS'] as $id => $rec){
523                 $newRecords[$rec['type']] = array();
524             }
525         }
527         /* There must be at least one record in our entry  
528          */
529         if((!count($newEntry['RECORDS'])) || (!$newEntry['exists'])){
530             $dn = "relativeDomainName=".$newName.",".DNS::getDNSZoneDN($config,$oldEntry['zoneName']);
531             $del[$dn] ="";
532             $ret = array("move"=>$move,"add"=>$add,"del"=>$del);
533             return($ret);
534         }
536         /* Prepare temp obj
537          */
538         $baseObj =  array();
539         $baseObj['objectClass']       = array("top","dNSZone");
540         if(!empty($newEntry['dNSTTL'])){
541             $baseObj['dNSTTL']            = $newEntry['dNSTTL'];
542         }
543         $baseObj['dNSClass']          = $newEntry['dNSClass'];
544         $baseObj['zoneName']          = $zoneName; 
545         $baseObj['relativeDomainName']= $newName; 
547         /* Add Container Object to zone
548          *  (this possibly already exists, check this before writing to ldap)
549          */
550         $baseDn =  "relativeDomainName=".$newName.",".$zoneDn;
551         $add[$baseDn] = $baseObj;
553         /* Add base obejct which contains all std records
554          */
555         $stdDn = "relativeDomainName=".$newName.",".$baseDn;
556         $add[$stdDn] = $baseObj;
558         /* Set defaults. Normaly only contains old record names.
559          *  The old names will be set to array, to ensure that they will be deleted.
560          *  Or overwritten and filled with new values.
561          */
562         foreach($newRecords as $name => $def){
563             if(!in_array_strict($name,$specialAttributes)){
564                 $add[$stdDn][$name] = $def;
565             }
566         }
568         /* Delete all OLD special attributes.
569          */
570         foreach($oldEntry['RECORDS'] as $id => $rec){
571             if(in_array_strict($rec['type'],$specialAttributes)){
572                 $deldn= "relativeDomainName=".$rec['value'].",".$baseDn;
573                 $del[$deldn] = "";
574             }
575         }
578         /* Create new record entries 
579          */
580         foreach($newEntry['RECORDS'] as $id => $rec){
581             /* Create object which contains special records 
582              *  like pTRRecord or CNAMERecord
583              */
584             if($rec['type']  == "pTRRecord"){
585                 $PTRdn= "relativeDomainName=".DNS::FlipIP($rec['value']).",".$baseDn;
586                 $ptrObj = $baseObj;
587                 $reverseName = DNS::getNameFromMix($reverseNameMix);
588                 $ptrObj['zoneName']           = $reverseName;
589                 if(!preg_match("/\.$/",$newName)){
590                     $ptrObj['pTRRecord']          = preg_replace("/\.\.$/",".",$newName.".".$zoneName.".");
591                 }else{
592                     $ptrObj['pTRRecord']          = preg_replace("/\.\.$/",".",$newName.".");
593                 }
594                 $ptrObj['relativeDomainName'] = DNS::FlipIP($rec['value']);
596                 $add[$PTRdn] = $ptrObj;
597             }else  
598                 if($rec['type']  == "cNAMERecord"){
599                     $PTRdn= "relativeDomainName=".$rec['value'].",".$baseDn;
600                     $ptrObj = $baseObj;
601                     $ptrObj['zoneName']           = $zoneName;
602                     $ptrObj['cNAMERecord']        = $newName;
603                     $ptrObj['relativeDomainName'] = $rec['value'];
605                     $add[$PTRdn] = $ptrObj;
606                 }else{
607                     /* Append basic attributes
608                      */
609                     $add[$stdDn][$rec['type']][] = $rec['value'];  
610                 }
611         } // foreach record 
613         $ret = array("move"=>$move,"add"=>$add,"del"=>$del);
614         return($ret);
615     } 
617     static function getNameFromMix($zoneMix){
618         $ret = "";
619         if(!strstr($zoneMix, '/')) return($ret);        
620         $zoneIndex              = explode("/",$zoneMix);
621         return($zoneIndex[1]);
622     }
624     /* returns the dn for a specified zone
625      */
626     static function getDNSZoneDN($config,$zoneNameMix)
627     {
628         $ret = "";
629         if(!strstr($zoneNameMix, '/')) {
630             msg_dialog::display(_("Error"), sprintf(_("Undefined zone name '%s'!"),$zoneNameMix), ERROR_DIALOG);
631             return($ret);
632         }
634         $zoneNameIndex          = explode("/",$zoneNameMix); 
635         $zoneName           = $zoneNameIndex[1];
636         $nameServer                             = strtolower($zoneNameIndex[0]);
637         $ldap               = $config->get_ldap_link();
639         /* search for the nameserver */
640         $ldap-> cd($config->current['BASE']);
641         $ldap->search("(&(objectClass=goServer)(cn=".$nameServer."))",array("cn"));
642         if($ldap->count()){
643             $attr = $ldap->fetch();
644         } else {
645             return($ret);
646         }
648         $ldap-> cd($attr['dn']);
649         $ldap->search("(&(objectClass=dNSZone)(sOARecord=*)(zoneName=".$zoneName."))",array("zoneName"));
650         if($ldap->count()){
651             $attr = $ldap->fetch();
652             return($attr['dn']);
653         }
655         return($ret);
656     }
659     /* returns all available zones 
660      *  array[reverseName] = zoneName;
661      */
662     static function getAvailableZones($config)
663     {
664         $ReverseZones = $ForwardZones = $zones = array();
665         $runtime_cache = session::get("runtime_cache");
666         if(!isset($runtime_cache['DNS']['getAvailableZones'])){
668             $ret = array();
669             $ldap = $config->get_ldap_link();
670             $tmp = get_sub_list("(&(objectClass=dNSZone)(sOARecord=*))","",get_ou("servgeneric", "serverRDN"),
671                     $config->current['BASE'],array("zoneName"),GL_NO_ACL_CHECK | GL_SUBSEARCH);
673             foreach($tmp as $at){
674                 if(preg_match("/\.in\-addr\.arpa\./",$at['zoneName'][0])){
675                     $ReverseZones[$at['dn']] = $at;
676                 }else{
677                     $ForwardZones[$at['dn']] = $at;
678                 }
679             }
681             foreach($ForwardZones as $dn => $obj){
683                 /* try to find reverse
684                  */  
685                 foreach($ReverseZones as $Rdn => $Robj ){
686                     if(preg_match("/".$dn."/",$Rdn)){
687                         $zones[strtoupper($ldap->getCn($dn))."/".$Robj['zoneName'][0]] =  
688                             strtoupper($ldap->getCn($dn))."/".$obj['zoneName'][0];
689                     }
690                 }   
691             }
692             $runtime_cache['DNS']['getAvailableZones'] = $zones;
693             session::set("runtime_cache",$runtime_cache);
694         }
695         return($runtime_cache['DNS']['getAvailableZones']);
696     }
699     static function touchDNSZone($config,$zoneName)
700     {
701         if(empty($zoneName)){
702             return null;
703         }
705         preg_match('@(?<server>[^/]*)/(?<name>.*)@',$zoneName,$matches);
706         $name = $matches['name'];
707         $server = strtolower($matches['server']);
709         // Search for the zone entry and its reverse entry.
710         $ldap = $config->get_ldap_link();
711         $ldap-> cd($config->current['BASE']);
712         $ldap->search("(&(objectClass=dNSZone)(zoneName=$name)(sOARecord=*))",array("sOARecord"));
713         if($ldap->count() != 1){
714             trigger_error("Invalid Zone ".$zoneName);
715         }else{
716             $to_update= array();
717             $forward = $ldap->fetch();
718             $to_update[$forward['dn']] = $forward;
719             $ldap->cd($forward['dn']);
720             $ldap->search("(&(objectClass=dNSZone)(relativeDomainName=@)(sOARecord=*))",array("sOARecord"));
722             // We may have multiple reverse zones later.
723             while($attrs = $ldap->fetch()){
724                 $to_update[$attrs['dn']] = $attrs;
725             }
727             // Increase the sAONumber for each zone
728             foreach($to_update as $zone){
729                 $tmp = explode(' ',$zone['sOARecord'][0]);
730                 $sOA = $tmp[2];
731                 $sOAdate = substr($sOA,0,8);
732                 $sOAnumber = substr($sOA,-2);
733                 $date = date('Ymd');
734                 $number = '01';
735                 if($sOAdate < $date){
736                     $sOA = $date.$number;
737                 } else {
738                     $number = sprintf("%02d", $sOAnumber+1);
739                     $sOA = $sOAdate.$number;
740                 }
741                 $tmp[2] = $sOA;
742                 $zone['sOARecord'][0] = implode(' ', $tmp);
743                 $attrs = array('sOARecord' => $zone['sOARecord'][0]);
744                 $ldap = $config->get_ldap_link();
745                 $ldap->cd($zone['dn']);
746                 $ldap->modify($attrs);
747                 if (!$ldap->success()){
748                     msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
749                 }
750             }
751         }
752     }
754 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
755 ?>