Code

Added sOA Record to dns plugins.
[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                     'sOARecord'     => "sOARecord",       
28                     'rRSIGRecord'   => "rRSIGRecord",      
29                     'nSECRecord'    => "nSECRecord");
30   /* All available record types */
31   /* Return all record types 
32    */
33   static function getDnsRecordTypes($ForZones = false)
34   {
35     if($ForZones){
36       $tmp = DNS::$RecordTypes;
37       unset($tmp['cNAMERecord']);
38       unset($tmp['pTRRecord']);
39       unset($tmp['tXTRecord']);
40       return($tmp);
41     }else{
42       return(DNS::$RecordTypes);
43     }
44   }
47   /* This fucntion is used to flip the ip address, for example
48      12.3.45  ->  45.3.12
49      Because some entries (like zones) are store like that 45.3.12.in-addr.arpa
50      but we want to display 12.3.45.
51    */
52   static function FlipIp($ip)
53   {
54     $tmp = array_reverse(split("\.",$ip));
55     $new = "";
56     foreach($tmp as $section){
57       $new .= $section.".";
58     }
59     return(preg_replace("/.$/","",$new));
60   }
63   /* This static function returns the zones specified for given host
64    */
65   static function getDNSZoneEntries($config,$HostDn,$silent = false)
66   {
67     $ldap = $config->get_ldap_link();
68     $ldap->cd($config->current['BASE']); 
70     /* Not all records are allowed within a zone entry
71      */  
72     $SkipRecords = array("tXTRecord","cNAMERecord","pTRRecord");
74     /* Special sOArecords 
75      */
76     $sOAREcords  = array("0"=>"sOAprimary","1"=>"sOAmail","2"=>"sOAserial","3"=>"sOArefresh","4"=>"sOAretry","5"=>"sOAexpire","6"=>"sOAttl");
78     /* Create tempalte for all fetched zone Data 
79      */
80     $ZoneBase = array();
81     $ZoneBase['exists']  = false;
82     $ZoneBase['RECORDS'] = array();
83     $ZoneBase['zoneName'] = array();
84     $ZoneBase['dNSClass'] = array();
86     foreach($sOAREcords as $attr){
87       $ZoneBase[$attr] = "";
88     }
90     $Zones    = array();
92     /* Get & Parse all zone entries 
93      */
94     $ldap->ls("(&(objectClass=dNSZone)(zoneName=*)(relativeDomainName=@))",$HostDn,array("*"));
95     $tmp_res = array();
96     while($attrs = $ldap->fetch()) {
97       $tmp_res[] = $attrs;
98     }
100     /* Parse fetched zones 
101      */
102     foreach($tmp_res as $attrs){
104       $zoneName                   = $attrs['zoneName'][0];
105       $Zones[$zoneName]           = $ZoneBase;
106       $Zones[$zoneName]['exists'] = true;
108       /* Set basic attributes 
109        */
110       foreach(array("zoneName","dNSClass") as $attr){
111         if(isset($attrs[$attr][0])){
112           $Zones[$zoneName][$attr] = $attrs[$attr][0];
113         }
114       }
116       /* Set initial zone name, to be able to detect if this entry was renamed 
117        */
118       $Zones[$zoneName]['InitialzoneName'] = $zoneName;
120       /* Generate SOA entry
121        */
122       if(isset($attrs['sOARecord'][0])){
123         $tmp = split("\ ",$attrs['sOARecord'][0]) ;
124         $tmp2 = array();
126         /* Assign soa vars */
127         foreach($sOAREcords as $key => $name){
128           if(isset($tmp[$key])){
129             $Zones[$zoneName][$name] = $tmp[$key];
130           }else{
131             $Zones[$zoneName][$name] = "";
132           }
133         }
134       } // ENDE SOA Record 
136       /* Get record attributes 
137        */
138       foreach(DNS::$RecordTypes as $name => $value){
140         /* Skip some attributes 
141          */
142         if(in_array($name,$SkipRecords)) continue;
144         /* If there is a record attribute
145          */
146         if(isset($attrs[$name])){
148           /* get all entries
149            */
150           for($i = 0 ; $i < $attrs[$value]['count']; $i ++){
151             $Zones[$zoneName]['RECORDS'][] =  array("type"=>$name,"value"=>$attrs[$value][$i]);
152           }
153         }
154       }
156       /* Get reverse record ..
157        */
158       $ldap->ls("(&(objectClass=dNSZone)(relativeDomainName=@)(zoneName=*))",$attrs['dn'],array("zoneName"));
160       if($ldap->count() == 0){
161         if(!$silent){
162           msg_dialog::display(_("Error"), sprintf(_("Cannot find reverse zone for DNS zone '%s'. Parsing zone aborted."),$zoneName), ERROR_DIALOG);
163         }
164         unset($Zones[$zoneName]);
165       }elseif($ldap->count()>1){
166         if(!$silent){
167           msg_dialog::display(_("Error"), sprintf(_("Found more than one reverse zone for '%s'. Parsing zone aborted."),$zoneName), ERROR_DIALOG);
168         }
169         unset($Zones[$zoneName]);
170       }else{
171         $tmp = $ldap->fetch();
172         $Zones[$zoneName]['ReverseZone']        = DNS::FlipIp(str_replace(".in-addr.arpa","",$tmp['zoneName'][0]));
173         $Zones[$zoneName]['InitialReverseZone'] = DNS::FlipIp(str_replace(".in-addr.arpa","",$tmp['zoneName'][0]));
174       }
175     }
176     return($Zones);
177   }
180   /* This static function compares two dns zone objects and returns an 
181    *  array with following indexes 
182    *   - delete, for dns which must be deleted (only if dns zone is removed)
183    *   - rename, if a dn must be renamed, for example, the zoneName has changed
184    *   - add,    if there is a new dns account created    
185    */
186   static function getDNSZoneEntriesDiff($config,$newZones,$HostDn)
187   {
188     $oldZones = DNS::getDNSZoneEntries($config,$HostDn,true);
190     $sOAattributes =  array("sOAprimary","sOAmail","sOAserial","sOArefresh","sOAretry","sOAexpire","sOAttl");
192     $move   = array();
193     $add    = array();
194     $del    = array();
196     /* Generate a template for zones with default values
197      */
198     $zoneBase                       = array();
199     $zoneBase['objectClass']        = array("top","dNSZone");
200     $zoneBase['zoneName']           = "";
201     $zoneBase['relativeDomainName'] = "@";
202     $zoneBase['dNSClass']           = "IN";
203     $zoneBase['sOARecord']          = "";
205     /* Contains all renamed zoneNames 
206      * For zone entry udpdates
207      */
208     $PrePareZoneEntries = array();
210     /* Walk through all zones and detect renamed/added/deleted zones ... 
211      */
212     foreach($newZones as $name => $zone){
214       /* This zone was renamed 
215        */
216       if((!empty($zone['InitialzoneName'])) && ($zone['InitialzoneName'] != $zone['zoneName'])){
218         /* Move old zone to new position 
219          */ 
220         $oldDn = "zoneName=".$zone['InitialzoneName'].",".$HostDn;
221         $newDn = "zoneName=".$zone['zoneName'].",".$HostDn;
222         $PrePareZoneEntries[$zone['InitialzoneName']] = $zone['zoneName'];
223         $move [$oldDn] = $newDn;      
224       }
226       /* Get old zone if available
227        */
228       $oldZone=array();
229       if(!empty($oldZones[$zone['InitialzoneName']])){
230         $oldZone = $oldZones[$zone['InitialzoneName']];
231       }
233       /* Create forward zone entry and put it in our add queue
234        */
235       $newDn  = "zoneName=".$zone['zoneName'].",".$HostDn;
236       $obj    =  $zoneBase;
237       $obj['zoneName'] = $zone['zoneName'];
239       /* Create sOARecord & add it to the obj
240        */ 
241       $soa = "";
242       foreach($sOAattributes as $attr){
243         $soa.=" ".$zone[$attr];
244       }  
245       $obj['sOARecord'] = trim($soa);
246       $obj['nSRecord'] = $zone['sOAprimary'];
248       /* If reverse zone was renamed, move entry 
249        */
250       if(!empty($zone['InitialReverseZone'])){
251         if($zone['InitialReverseZone'] != $zone['ReverseZone']){
252           $base = "zoneName=".$zone['zoneName'].",".$HostDn;
253           $oldRDn = "zoneName=". DNS::FlipIp($zone['InitialReverseZone']).".in-addr.arpa,".$base; 
254           $newRDn = "zoneName=". DNS::FlipIp($zone['ReverseZone']).".in-addr.arpa,".$base;
255           $PrePareZoneEntries[DNS::FlipIp($zone['InitialReverseZone']).".in-addr.arpa"] = DNS::FlipIp($zone['ReverseZone']).".in-addr.arpa";
256           $move [$oldRDn] = $newRDn;
257         }
258       }
260       /* Append record entries 
261        *  Set old value to array, to ensure that 
262        *  they will be deleted if necessary
263        */
264       if(isset($oldZone['RECORDS'])){
265         foreach($oldZone['RECORDS'] as $rec){
266           $obj[$rec['type']] = array();
267         }
268       }
270       /* Add new Records 
271        */
272       foreach($zone['RECORDS'] as $rec){
273         if(!isset($obj[$rec['type']])||!is_array($obj[$rec['type']])){
274           $obj[$rec['type']] = array();
275         }
276         $obj[$rec['type']][] = $rec['value'];
277       }
279       /* Append udpated Zone Forward Entry to our add queue
280        */    
281       $add[$newDn] = $obj;   
283       /* Create Reverse Entry 
284        * And append it to our add queue
285        */
286       $zone['ReverseZone'] = DNS::FlipIp($zone['ReverseZone']).".in-addr.arpa";
287       $base = "zoneName=".$zone['zoneName'].",".$HostDn;
288       $newRDn = "zoneName=".$zone['ReverseZone'].",".$base;
289       $rObj = $obj;
290       $rObj['zoneName']= $zone['ReverseZone'];
291       $add[$newRDn] = $rObj;
293       /* Remove currently managed zone from oldZones.
294        *  this gives us the ability to detect removed zones
295        */
296       if(isset($oldZones[$zone['InitialzoneName']])){
297         unset($oldZones[$zone['InitialzoneName']]); 
298       }
299     }
301     /* The rest of our oldZones must be deleted
302      *  because they are no longer available in newZones anymore.
303      */
304     foreach($oldZones as $zone)  {
305       $oldDn = "zoneName=".$zone['InitialzoneName'].",".$HostDn;
306       $del[$oldDn] = $zone;
307     }
309     /* Check for entries which must be updated 
310      */
311     $zoneUpdates = array();
312     $udpate = array();
313     if(count($PrePareZoneEntries)){
314       $ldap = $config->get_ldap_link();
315       foreach($PrePareZoneEntries as $FromZoneName => $ToZoneName){
316         $ldap->cd($HostDn);
317         $ldap->search("(&(objectClass=dNSZone)(zoneName=".$FromZoneName.")(!(relativeDomainName=@)))",array("zoneName"));
318         while($attrs = $ldap->fetch()){
319           $zoneUpdates[$attrs['dn']] = array("zoneName"=>$ToZoneName);
320         }
321       }
322     }
324     $ret = array("del" => $del , "move" => $move , "add" => $add,"zoneUpdates"=>$zoneUpdates);
325     return($ret);
326   }
329   /* This static function returns the dns-host eintries for given 
330    *  name.
331    */
332   static function getDNSHostEntries($config,$name,$silent = false)
333   {
334     $types = array();
335     $ret = array();
336     $ret['RECORDS']   = array();
337     $ret['dNSClass']  = "IN";
338     $ret['zoneName']  = "";
339     $ret['dNSTTL']    = "";
340     $ret['exists']    = false;
342     $ldap = $config->get_ldap_link();
343     $ldap->cd($config->current['BASE']);
345     /* First check all zones for an entry with the given name.
346      * If the name occurs in more than one entry alert the user ...
347      */
348     $foundIn = array();
349     $zones = DNS::getAvailableZones($config);
350     $zonesArr = array();
351     foreach($zones as $zoneMix){
352       $zoneIndex = split("/",$zoneMix);
353       if(!array_key_exists($zoneIndex[0],$zonesArr)) {
354         $zonesArr[$zoneIndex[0]] = array();
355       }
356       array_push($zonesArr[$zoneIndex[0]],$zoneIndex[1]);
357     }
359     foreach($zonesArr as $nameServer => $nameServerArr){
360       $foundInTmp = array();
361       foreach($nameServerArr as $zoneArr => $zone){
363         /* Strip eventually domain part from hostname 
364          */
365         $zN = trim($zone,".");
366         $nN = trim($name,".");  
367         if(preg_match("/".preg_quote($zN, '/')."$/",$nN)){
368           $nN = preg_replace("/[\.]*".preg_quote($zN, '/')."[\.]*$/","",$nN);
369         }else{
370           $nN = $name;
371         }
372         $zoneMix = $nameServer."/".$zone;
373         $zoneDn = DNS::getDNSZoneDN($config,$zoneMix);
374         $ldap->ls("(&(objectClass=dNSZone)(zoneName=*)(relativeDomainName=".$nN.")(!(relativeDomainName=@)))", $zoneDn,$attrs = array("*"));
375         while($attrs = $ldap->fetch()){
376           $foundInTmp [$zoneMix] = $attrs['dn'];
377           $foundIn [$zoneMix] = $attrs['dn'];
378         }
379       }
380     }
382     /* No zone found which contains an entry for us
383      */
384     if(count($foundIn) == 0){
385       return($ret);
386     }
388     /* Get host informations from zone
389      */ 
390     $id_tmp = key($foundIn);
391     $ldap->cd($foundIn[$id_tmp]);
392     $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("*"));
393     while($attrs = $ldap->fetch()){
395       /* Strip eventually domain part from hostname 
396        */
397       $zN = trim($attrs['zoneName'][0],".");
398       $nN = trim($name,"."); 
399       $testname = $attrs['relativeDomainName'][0].".".$zN;
401       /* Check given host name with zone settings 
402        */ 
403       if(preg_match("/".preg_quote($testname, '/')."[\.]*$/",$nN) || $attrs['relativeDomainName'][0] == $name){
404         $ret['exists'] = true;
405         $ret['zoneName'] = $id_tmp;
406         foreach(array("dNSClass","dNSTTL") as $atr){
407           if(isset($attrs[$atr][0])){
408             $ret[$atr] = $attrs[$atr][0];
409           }
410         }
411       }
413       /* Create list with all used records */
414       foreach(DNS::$RecordTypes as $name => $value){
416         /* If there is a record attribute  */
417         if(isset($attrs[$name])){
419           /* get all entries */
420           for($i = 0 ; $i < $attrs[$value]['count']; $i ++){
421             $types[] = array( "type"    => $name,
422                 "value"   => $attrs[$value][$i]);
423           }
424         }
425       }
426       $ret['RECORDS'] = $types;
427     }
428     return($ret);
429   }  
433   /* This static function compares two dns settings and returns an 
434    *  array with following indexes 
435    *   - delete, for dns which must be deleted (only if dns account is removed)
436    *   - rename, if a dn must be renamed, for example, the relativeDomainName has changed
437    *   - add,    if there is a new dns account created    
438    */
439   static function getDNSHostEntriesDiff($config,$oldName,$newEntry,$newName)
440   {
441     $oldEntry = DNS::getDNSHostEntries($config,$oldName);
443     $add    = array();
444     $del    = array();
445     $move   = array();
447     /* Don't go further if there is nothing to do
448      * Is no account / was no account
449      */
450     if(($newEntry['exists'] == false )&& ($oldEntry['exists'] == false)){
451       return(array("move"=>$move,"add"=>$add,"del"=>$del));
452     }
454     $zones              = DNS::getAvailableZones($config);
455     $specialAttributes  = array("cNAMERecord","pTRRecord");
456     $newRecords         = array();  // Used to remember which records are removed 
457     $zoneNameMix           = $newEntry['zoneName'];
458     $zoneDn             = DNS::getDNSZoneDN($config,$zoneNameMix);
459     $tmp                = array_flip($zones);
460     $zoneName                                   = DNS::getNameFromMix($zoneNameMix);
462     /* Strip domain part out of dns host entry 
463      */
464     $zN = trim($zoneName,".");
465     $nN = trim($newName,".");
466     $oN = trim($oldName,".");
467     $newName = preg_replace("/[\.]*".preg_quote($zN, '/')."$/i","",$nN);
468     $oldName = preg_replace("/[\.]*".preg_quote($zN, '/')."$/i","",$oN);
470     /* If reverseZone can't be resolved ... this 
471      *  can't be a valid entry, so remove this account
472      */ 
473     if(isset($tmp[$zoneNameMix])){
474       $reverseNameMix  = $tmp[$zoneNameMix];
475       $reverseDn    = DNS::getDNSZoneDN($config,$reverseNameMix);
476       if(empty($reverseDn)){
477         $newEntry['exists'] = false;
478       }
479     }else{
480       $newEntry['exists'] = false;
481     }
483     /* If account was edited prepare some
484      *  attributes & arrays ... if required add some 
485      *  dns to $move 
486      */
487     if($oldEntry['exists']){
489       /* Check if the account was removed 
490        */
491       if($newEntry['exists'] == false){
492         $dn = "relativeDomainName=".$oldName.",".DNS::getDNSZoneDN($config,$oldEntry['zoneName']);
493         $del[$dn] ="";
494         return(array("move"=>$move,"add"=>$add,"del"=>$del));
495       }
497       /* Check if zoneName has changed 
498        */   
499       if(count($newEntry['RECORDS'])){
500         if($oldEntry['zoneName'] != $newEntry['zoneName']){
501           $oldzoneDn = DNS::getDNSZoneDN($config,$oldEntry['zoneName']);
502           $dn = "relativeDomainName=".$oldName.",".$oldzoneDn;
503           $dn2= "relativeDomainName=".$oldName.",".$zoneDn;
504           $move[$dn]=$dn2;
505         }
507         /* Check if host name has changed 
508          */ 
509         if($oldName != $newName){
510           $dn = "relativeDomainName=".$oldName.",".$zoneDn;
511           $dn2= "relativeDomainName=".$newName.",".$zoneDn;
512           $move[$dn]=$dn2;
513           $dn = "relativeDomainName=".$oldName.",".$dn2;
514           $dn2= "relativeDomainName=".$newName.",".$dn2;
515           $move[$dn]=$dn2;
516         }
517       }
519       /* Prepare record entries
520        *  Fill old records with array();
521        *  To ensure that they will be deleted if they stay unused
522        */
523       foreach($oldEntry['RECORDS'] as $id => $rec){
524         $newRecords[$rec['type']] = array();
525       }
526     }
528     /* There must be at least one record in our entry  
529      */
530     if((!count($newEntry['RECORDS'])) || (!$newEntry['exists'])){
531       $dn = "relativeDomainName=".$newName.",".DNS::getDNSZoneDN($config,$oldEntry['zoneName']);
532       $del[$dn] ="";
533       $ret = array("move"=>$move,"add"=>$add,"del"=>$del);
534       return($ret);
535     }
537     /* Prepare temp obj
538      */
539     $baseObj =  array();
540     $baseObj['objectClass']       = array("top","dNSZone");
541     if(!empty($newEntry['dNSTTL'])){
542       $baseObj['dNSTTL']            = $newEntry['dNSTTL'];
543     }
544     $baseObj['dNSClass']          = $newEntry['dNSClass'];
545     $baseObj['zoneName']          = $zoneName; 
546     $baseObj['relativeDomainName']= $newName; 
548     /* Add Container Object to zone
549      *  (this possibly already exists, check this before writing to ldap)
550      */
551     $baseDn =  "relativeDomainName=".$newName.",".$zoneDn;
552     $add[$baseDn] = $baseObj;
554     /* Add base obejct which contains all std records
555      */
556     $stdDn = "relativeDomainName=".$newName.",".$baseDn;
557     $add[$stdDn] = $baseObj;
559     /* Set defaults. Normaly only contains old record names.
560      *  The old names will be set to array, to ensure that they will be deleted.
561      *  Or overwritten and filled with new values.
562      */
563     foreach($newRecords as $name => $def){
564       if(!in_array($name,$specialAttributes)){
565         $add[$stdDn][$name] = $def;
566       }
567     }
569     /* Delete all OLD special attributes.
570      */
571     foreach($oldEntry['RECORDS'] as $id => $rec){
572       if(in_array($rec['type'],$specialAttributes)){
573         $deldn= "relativeDomainName=".$rec['value'].",".$baseDn;
574         $del[$deldn] = "";
575       }
576     }
579     /* Create new record entries 
580      */
581     foreach($newEntry['RECORDS'] as $id => $rec){
582       /* Create object which contains special records 
583        *  like pTRRecord or CNAMERecord
584        */
585       if($rec['type']  == "pTRRecord"){
586         $PTRdn= "relativeDomainName=".DNS::FlipIP($rec['value']).",".$baseDn;
587         $ptrObj = $baseObj;
588         $reverseName = DNS::getNameFromMix($reverseNameMix);
589         $ptrObj['zoneName']           = $reverseName;
590         if(!preg_match("/\.$/",$newName)){
591           $ptrObj['pTRRecord']          = preg_replace("/\.\.$/",".",$newName.".".$zoneName.".");
592         }else{
593           $ptrObj['pTRRecord']          = preg_replace("/\.\.$/",".",$newName.".");
594         }
595         $ptrObj['relativeDomainName'] = DNS::FlipIP($rec['value']);
597         $add[$PTRdn] = $ptrObj;
598       }else  
599         if($rec['type']  == "cNAMERecord"){
600           $PTRdn= "relativeDomainName=".$rec['value'].",".$baseDn;
601           $ptrObj = $baseObj;
602           $ptrObj['zoneName']           = $zoneName;
603           $ptrObj['cNAMERecord']        = $newName;
604           $ptrObj['relativeDomainName'] = $rec['value'];
606           $add[$PTRdn] = $ptrObj;
607         }else{
608           /* Append basic attributes
609            */
610           $add[$stdDn][$rec['type']][] = $rec['value'];  
611         }
612     } // foreach record 
614     $ret = array("move"=>$move,"add"=>$add,"del"=>$del);
615     return($ret);
616   } 
618   static function getNameFromMix($zoneMix){
619     $ret = "";
620     if(!strstr($zoneMix, '/')) return($ret);    
621     $zoneIndex          = split("/",$zoneMix);
622     return($zoneIndex[1]);
623   }
625   /* returns the dn for a specified zone
626    */
627   static function getDNSZoneDN($config,$zoneNameMix)
628   {
629     $ret = "";
630     if(!strstr($zoneNameMix, '/')) {
631       msg_dialog::display(_("Error"), sprintf(_("Undefined zone name '%s'!"),$zoneNameMix), ERROR_DIALOG);
632       return($ret);
633     }
635     $zoneNameIndex              = split("/",$zoneNameMix); 
636     $zoneName           = $zoneNameIndex[1];
637     $nameServer                         = strtolower($zoneNameIndex[0]);
638     $ldap               = $config->get_ldap_link();
640     /* search for the nameserver */
641     $ldap-> cd($config->current['BASE']);
642     $ldap->search("(&(objectClass=goServer)(cn=".$nameServer."))",array("cn"));
643     if($ldap->count()){
644       $attr = $ldap->fetch();
645     } else {
646       return($ret);
647     }
649     $ldap-> cd($attr['dn']);
650     $ldap->search("(&(objectClass=dNSZone)(sOARecord=*)(zoneName=".$zoneName."))",array("zoneName"));
651     if($ldap->count()){
652       $attr = $ldap->fetch();
653       return($attr['dn']);
654     }
656     return($ret);
657   }
660   /* returns all available zones 
661    *  array[reverseName] = zoneName;
662    */
663   static function getAvailableZones($config)
664   {
665     $ReverseZones = $ForwardZones = $zones = array();
666     $runtime_cache = session::get("runtime_cache");
667     if(!isset($runtime_cache['DNS']['getAvailableZones'])){
668     
669       $ret = array();
670       $ldap = $config->get_ldap_link();
671       $tmp = get_sub_list("(&(objectClass=dNSZone)(sOARecord=*))","",get_ou("serverRDN"),
672           $config->current['BASE'],array("zoneName"),GL_NO_ACL_CHECK | GL_SUBSEARCH);
674       foreach($tmp as $at){
675         if(preg_match("/\.in\-addr\.arpa/",$at['zoneName'][0])){
676           $ReverseZones[$at['dn']] = $at;
677         }else{
678           $ForwardZones[$at['dn']] = $at;
679         }
680       }
682       foreach($ForwardZones as $dn => $obj){
684         /* try to find reverse
685          */  
686         foreach($ReverseZones as $Rdn => $Robj ){
687           if(preg_match("/".$dn."/",$Rdn)){
688             $zones[strtoupper($ldap->getCn($dn))."/".$Robj['zoneName'][0]] =  
689               strtoupper($ldap->getCn($dn))."/".$obj['zoneName'][0];
690           }
691         }   
692       }
693       $runtime_cache['DNS']['getAvailableZones'] = $zones;
694       session::set("runtime_cache",$runtime_cache);
695     }
696     return($runtime_cache['DNS']['getAvailableZones']);
697   }
699 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
700 ?>