Code

2a2e7df25ab17411edc8fb7b042878c0edeeec46
[gosa.git] / plugins / admin / systems / class_termDNS.inc
1 <?php
3 class termDNS extends plugin
4 {
5   /* CLI vars */
6   var $cli_summary= "Manage server basic objects";
7   var $cli_description= "Some longer text\nfor help";
8   var $cli_parameters= array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
10   /* attribute list for save action */
11   var $ignore_account= TRUE;
12   var $DNSattributes   = array("dNSClass","zoneName","dNSTTL");
13   var $attributes= array("ipHostNumber","macAddress");
14   var $objectclasses= array("whatever");
16   var $ipHostNumber ="";    // IP address 
17   var $macAddress   ="";    // Mac address 
18   var $cn           ="";    // CN of currently edited device 
20   var $Zones      = array();      // All Available Zones like array("3.2.1"=>"MyServer.de")
21   var $RecordTypes= array();      // Possible record types 
22     
23   var $dNSClass   = "IN";         // dNSClass name 
24   var $zoneName   = "";           // Used ZoneName 
25   var $dNSTTL     = 7200;         // TTL settings for the created entries 
27   /* Used records */
28   var $types = array();
29   var $DNSinitially_was_account = false;
31   function termDNS ($config, $dn,$objectClasses)
32   {
33     /* We need to know which objectClasses are used, to store the ip/mac*/
34     $this->objectclasses= $objectClasses;
35     plugin::plugin ($config, $dn);
37     /* All types with required attrs */
38     $this->RecordTypes['aRecord']       = "aRecord";           // ok
39     $this->RecordTypes['mDRecord']      = "mDRecord";          // ok
40     $this->RecordTypes['mXRecord']      = "mXRecord";          // ok
41     $this->RecordTypes['nSRecord']      = "nSRecord";          // ok 
42     $this->RecordTypes['pTRRecord']     = "relativeDomainName";// ok
43     $this->RecordTypes['hInfoRecord']   = "hInfoRecord";       // ok
44     $this->RecordTypes['mInfoRecord']   = "mInfoRecord";       // ok
45     $this->RecordTypes['cNAMERecord']   = "relativeDomainName";// ok
46     $this->RecordTypes['tXTRecord']     = "tXTRecord";         // ok
47     $this->RecordTypes['aFSDBRecord']   = "aFSDBRecord";       // ok
48     $this->RecordTypes['SigRecord']     = "SigRecord";         // ok
49     $this->RecordTypes['KeyRecord']     = "KeyRecord";         // ok 
50     $this->RecordTypes['aAAARecord']    = "aAAARecord";        // ok
51     $this->RecordTypes['LocRecord']     = "LocRecord";         // ok 
52     $this->RecordTypes['nXTRecord']     = "nXTRecord";         // ok
53     $this->RecordTypes['sRVRecord']     = "sRVRecord";         // ok
54     $this->RecordTypes['nAPTRRecord']   = "nAPTRRecord";       // ok
55     $this->RecordTypes['kXRecord']      = "kXRecord";          // ok
56     $this->RecordTypes['certRecord']    = "certRecord";        // ok
57     $this->RecordTypes['a6Record']      = "a6Record";          // ok
58     $this->RecordTypes['dSRecord']      = "dSRecord";          // ok
59     $this->RecordTypes['sSHFPRecord']   = "sSHFPRecord";       // ok
60     $this->RecordTypes['rRSIGRecord']   = "rRSIGRecord";       // ok
61     $this->RecordTypes['nSECRecord']    = "nSECRecord";        // ok 
63     /* Get all available zones */ 
64     $this->cn = $this->attrs['cn'][0];
65     $this->Zones = $this->get_Zones();
66     $types = array();
68     /* Get all records */
69     $ldap = $this->config->get_ldap_link();
70     $ldap->cd($this->dn); 
71     $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("*"));
73     while($attrs = $ldap->fetch()){
74       /* If relative domainname == cn 
75        * Try to read dnsclass / TTl / zone 
76        */
77       if($attrs['relativeDomainName'][0] == $this->cn){
78         /* Get class */
79         if(isset($attrs['dNSClass'][0])){
80           $this->dNSClass = $attrs['dNSClass'][0];
81         }
82         /* Get Zone*/
83         if(isset($attrs['zoneName'][0])){
84           $this->zoneName = $attrs['zoneName'][0];
85         }
86         /* Get ttl */
87         if(isset($attrs['dNSTTL'][0])){
88           $this->dNSTTL   = $attrs['dNSTTL'][0];
89         }
90       }
92       /* Create list with all used records */
93       foreach($this->RecordTypes as $name => $value){
94     
95         /* If there is a record attribute  */
96         if(isset($attrs[$name])){
97   
98  
99           /* get all entries */
100           for($i = 0 ; $i < $attrs[$value]['count']; $i ++){
101             if(($value == "aRecord")&&($this->ipHostNumber==$attrs[$value][$i])){
102              continue; 
103             }
104             $types[] =array("type"=>$name,"inittype"=>$name,"value"=>$attrs[$value][$i],"status"=>"edited","dn"=>$attrs['dn']);
105           }
106         }
107       }
108     }
110     /* If there is at least one entry in this -> types, we have DNS enabled */
111     $this->types = $types;
112     if(count($this->types) == 0){
113       $this->DNS_is_account = false;
114     }else{
115       $this->DNS_is_account = true;
116     }
117     
118     /* Store initally account settings */
119     $this->DNSinitially_was_account = $this->DNS_is_account;
120   }
122   function execute()
123   {
124           /* Call parent execute */
125     $smarty= get_smarty();
126     $display= "";
128     /* Add new empty array with status new, to our record list */
129     if(isset($_POST['AddNewRecord'])){
130       $this->types[]  =array("type"=>"aRecord","value"=>"","status"=>"new");
131     }
132    
133     /* Handle all posts */ 
134     $only_once =true;
135     foreach($_POST as $name => $value){
137       /* Check if we have to delete a record entry */
138       if((preg_match("/RemoveRecord_/",$name))&&($only_once)) {
139       
140         /* Avoid performing this once again */
141         $only_once = false;
143         /* Extract id for specified entry */
144         $id = preg_replace("/RemoveRecord_/","",$name);
145         $id = preg_replace("/_.*$/","",$id);
146     
147         /* Delete this record, mark edited entries to be able to delete them */
148         if(isset($this->types[$id])){
149           if($this->types[$id]['status'] == "edited"){
150             $this->types[$id]['status'] = "deleted";
151           }else{    
152             unset($this->types[$id]);
153           }
154         }
155       }
156     }
158     /* Assign smarty all non DNs attributes */
159     foreach($this->attributes as $attr){
160       $smarty->assign($attr,$this->$attr);
161     }
163     /* Assign smarty all DNS attributes */
164     foreach($this->DNSattributes as $attr){
165       $smarty->assign($attr,$this->$attr);
166     }
167     
168     /* Assign all needed vars */
169     $smarty->assign("DNSAccount",$this->DNS_is_account);
170     $smarty->assign("Zones",$this->Zones);
171     $smarty->assign("ZoneKeys",($this->Zones));
172     $changeStateForRecords ="";
173     $smarty->assign("records",$this->generateRecordsList(&$changeStateForRecords));
174     $smarty->assign("changeStateForRecords",$changeStateForRecords);
175     $smarty->assign("dNSClasses",array("IN"=>"IN"));
176     $smarty->assign("staticAddress","<font class=\"must\">*</font>");
177     $display.= $smarty->fetch(get_template_path('network.tpl', TRUE));
178     return($display);
179   }
181   function remove_from_parent()
182   {
183     /* This cannot be removed...    */
184   }
186   /* Save data to object */
187   function save_object()
188   {
189     /* Save all posted vars */
190     plugin::save_object();
191     
192     /* Ge all non dns attributes (IP/MAC)*/
193     foreach($this->attributes as $attr){
194       if(isset($_POST[$attr])){
195         $this->$attr = $_POST[$attr];
196       }
197     }
199     /* Get dns attributes */
200     if(isset($_POST['network_tpl_posted'])){
202       /* Check for posted record changes */
203       foreach($this->types as $key => $value){
204       
205         /* Check if type has changed */
206         if(isset($_POST['RecordTypeSelectedFor_'.$key])){
207           $this->types[$key]['type'] = $_POST['RecordTypeSelectedFor_'.$key];
208         }
209         /* Check if value has changed */
210         if(isset($_POST['RecordValue_'.$key])){
211           $this->types[$key]['value'] = $_POST['RecordValue_'.$key];
212         }
213       }
214       
215       /* Get all basic DNS attributes (TTL, Clas ..)*/
216       foreach($this->DNSattributes as $attr){
217         if(isset($_POST[$attr])){
218           $this->$attr = $_POST[$attr];
219         }
220       }
222       /* Enable diable DNS */
223       if(isset($_POST['enableDNS'])){
224         $this->DNS_is_account = true;
225       }else{
226         $this->DNS_is_account = false;
227       }
228     }
229   }
232   /* Check supplied data */
233   function check()
234   {
235     $message= array();
237     /* Check if mac is empty */
238     if ($this->macAddress == "" && chkacl ($this->acl, "macAddress") == ""){
239       $message[]= _("The required field 'MAC-address' is not set.");
240     }
242     /* Check if ip is empty */
243     if ($this->ipHostNumber == "" && chkacl ($this->acl, "ipHostNumber") == ""){
244       $message[]= _("The required field 'IP-address' is not set.");
245     }
247     /* check if given ip is valid ip*/
248     $num="(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
249     if (!preg_match("/^$num\\.$num\\.$num\\.$num$/", $this->ipHostNumber)){
250       $message[]= _("Wrong IP format in field IP-address.");
251     }
253     /* Check if given mac is valid mac */
254     $tr = count(split(":",$this->macAddress));
255     if($tr!=6){
256       $message[]=(_("The given macaddress is invalid. There must be 6 1byte segments seperated by ':'."));
257     }
259     /* only perfrom this checks if this is a valid DNS account */
260     if($this->DNS_is_account){
261       foreach($this->types as $name => $values){
263         /* Check if there is an aRecord defined which uses the same IP as used in IPhostAddress */
264         if(($values['type'] == "aRecord")&&($values['value'] == $this->ipHostNumber)&&($values['status']!="deleted")){
265           $message[]=sprintf(_("The device IP '%s' is added as 'A Record', this will be done automatically, please remove the record."), 
266                $this->ipHostNumber);
267         }
269         /* only lower-case is allowed in record entries ... */
270         if($values['value'] != strtolower($values['value'])){
271           $message[] = sprintf(_("Only lowercase is allowed, please check your '%ss'."),$values['type']);
272         }
273       }
274     }
275   
276     return ($message);
277   }
280   /* Save to LDAP */
281   function save($dn)
282   {
283     $ldap= $this->config->get_ldap_link();
284    
285     /*******************/ 
286     /* IP-MAC HANDLING */
287     /*******************/ 
289     /* $dn was posted as parameter */
290     $this->dn = $dn;
291     
292     /* Save DNS setting & ip/Mac*/
293     plugin::save();
295     /* Write back to ldap */
296     $ldap->cd($this->dn);
297     $ldap->modify($this->attrs);
299     /****************/ 
300     /* DNS HANDLING */
301     /****************/ 
303     /* If isn't DNS account but initially was DNS account 
304        remove all DNS entries 
305      */ 
306     if(!$this->DNS_is_account){
307       if($this->DNSinitially_was_account){
308         $tmp = array();
309         foreach($this->types as $type){
310           $dn = $type['dn'];
311           if(!isset($tmp[$dn])) {
312             $ldap->cd($dn);
313             $ldap->rmDir($dn);
314           }
315           $tmp[$dn]=$dn;
316         }
317       }
318     }else{
319     
320       /* DNS is enabled, check what we have to do */
321       $delete = array();
322   
323       /* Generate a list of new ldap entries, 
324           & $delete contains all dns which should be deleted 
325        */
326       $entries = $this->generate_LDAP_entries(&$delete);
328       /* Delete dns */
329       foreach($delete as $dn => $del){
330         $ldap->cd($dn);
331         $ldap->rmDir($dn);
332       }
334       /* Add || Update new DNS entries */
335       foreach($entries as $dn => $attrs){
336         $ldap->cd($dn);
337         $ldap->cat($dn);
338         
339         if(count($ldap->fetch())){
340           $ldap->cd($dn);
341           $ldap->modify($attrs);
342         }else{
343           $ldap->cd($dn);
344           $ldap->add($attrs);
345         }
346       }
347     }
348     if($ldap->get_error() != "Success"){
349       show_ldap_error($ldap->get_error()); 
350     }
351     
352   }
354   /*  Create html table with all used record types
355    */
356   function generateRecordsList($changeStateForRecords)
357   {
358     $changeStateForRecords = "";
359     
360     if(!$this->DNS_is_account) {
361       $str = "<input type='submit' value='"._("Add")."' name='AddNewRecord' id='AddNewRecord' disabled>";
362       return $str;
363     }
364  
365     $str = "<table summary=''>";
366     foreach($this->types as $key => $entry){
367         if($entry['status'] == "deleted") continue;
369         $changeStateForRecords.= "changeState('RecordTypeSelectedFor_".$key."');\n";
370         $changeStateForRecords.= "changeState('RecordValue_".$key."');\n";
371         $changeStateForRecords.= "changeState('RemoveRecord_".$key."');\n";
373         $str.=" <tr>".
374           "   <td>".$this->generateRecordListBox($entry['type'],"RecordTypeSelectedFor_".$key)."</td>".
375           "   <td><input type='text' value='".$entry['value']."' name='RecordValue_".$key."' id='RecordValue_".$key."'></td>".
376           "   <td><input type='submit' name='RemoveRecord_".$key."' value='"._("Delete")."' id='RemoveRecord_".$key."'></td>".
377           "</tr>";
378     }
380     $str.= "  <tr>".
381            "    <td colspan=2></td><td>".
382            "      <input type='submit' value='"._("Add")."' name='AddNewRecord'>".
383            "    </td>".
384            "  </tr>".
385            "</table>";
386     return($str);
387   }
389   /* Create a html select box which allows us to select different types of records */
390   function generateRecordListBox($selected,$name)
391   {
392     $str = "<select name='".$name."' id='".$name."'>";
393     foreach($this->RecordTypes as $type => $value){
394       $use = "";
395       if($type == $selected){
396         $use = " selected ";
397       }
398       $str.="\n <option value='".$type."' ".$use.">".$type."</option>";
399     }
400     $str.="</select>";
401     return($str); 
402   }
404   /* return all Zone names */
405   function get_Zones()
406   {
407     $ret = array();
408     $ldap = $this->config->get_ldap_link();
409     $ldap-> cd ($this->config->current['BASE']);
410     $ldap->search("(&(objectClass=dNSZone)(sOARecord=*))",array("*"));
411     
412     while($at = $ldap->fetch()){
413       if(preg_match("/\.in\-addr\.arpa/",$at['zoneName'][0])){
414         $ret[$at['relativeDomainName'][0]]['addr']= $at['zoneName'][0];
415       }else{
416         $ret[$at['relativeDomainName'][0]]['name']= $at['zoneName'][0];
417       }
418     }
420     $tmp  =array();
421     foreach($ret as $name => $entry){
422       if((isset($entry['addr']))&&(isset($entry['name']))){
423         $tmp[$entry['addr']]=$entry['name'];
424       }
425     }
426     $ret = $tmp;
427     return($ret); 
428   } 
430   /* this is used to generate ldap friendly output of our 
431      dns configuration
432   */
433   function generate_LDAP_entries($delete)
434   {
435     $entries = array();    
436     $delete  = array();
438     /* Generate Main Entry */
439     $dn = "relativeDomainName=".$this->cn.",".$this->dn;
440     $entries[$dn]['dNSClass']           = $this->dNSClass;      
441     $entries[$dn]['zoneName']           = $this->zoneName;      
442     $entries[$dn]['dNSTTL']             = $this->dNSTTL;      
443     $entries[$dn]['relativeDomainName'] = $this->cn;      
445     /* Generate cNAMERecord */
446     $aRecords = array();
447     foreach($this->types as $type){
448       if($type['type'] == "cNAMERecord"){
449           
450         $Cdn = "relativeDomainName=".$type['value'].",".$this->dn;
451         if($type['status']=="deleted"){
452           $delete [$type['dn']] = $Cdn;
453         }else{
454           $entries[$Cdn] = $entries[$dn];
455           $entries[$Cdn]['relativeDomainName']  = $type['value'];
456           $entries[$Cdn]['cNAMERecord']         = $this->cn.".".$this->zoneName;
457         }
458       }
459     }
461     /* Generate tXTRecord */
462     $aRecords = array();
463     foreach($this->types as $type){
464       if(($type['type'] == "tXTRecord")&&($type['status']!="deleted")){
465         $entries[$dn]['tXTRecord'][] = $type['value'];
466       }
467     }
469     /* Generate mDRecord */
470     $aRecords = array();
471     foreach($this->types as $type){
472       if(($type['type'] == "mDRecord")&&($type['status']!="deleted")){
473         $entries[$dn]['mDRecord'][] = $type['value'];
474       }
475     }
477     /* Generate mXRecord */
478     $aRecords = array();
479     foreach($this->types as $type){
480       if(($type['type'] == "mXRecord")&&($type['status']!="deleted")){
481         $entries[$dn]['mXRecord'][] = $type['value'];
482       }
483     }
484  
485     /* Generate hInfoRecord */
486     $aRecords = array();
487     foreach($this->types as $type){
488       if(($type['type'] == "hInfoRecord")&&($type['status']!="deleted")){
489         $entries[$dn]['hInfoRecord'][] = $type['value'];
490       }
491     }
493     /* Generate mInfoRecord */
494     $aRecords = array();
495     foreach($this->types as $type){
496       if(($type['type'] == "mInfoRecord")&&($type['status']!="deleted")){
497         $entries[$dn]['mInfoRecord'][] = $type['value'];
498       }
499     }
500  
501     /* Generate aFSDBRecord */
502     $aRecords = array();
503     foreach($this->types as $type){
504       if(($type['type'] == "aFSDBRecord")&&($type['status']!="deleted")){
505         $entries[$dn]['aFSDBRecord'][] = $type['value'];
506       }
507     }
508  
509     /* Generate some attrs  */
510     $arr = array("SigRecord","KeyRecord","aAAARecord","nSRecord",
511         "LocRecord","nXTRecord","sRVRecord","nAPTRRecord","kXRecord","certRecord","a6Record","dSRecord","sSHFPRecord","rRSIGRecord","nSECRecord");
512     $aRecords = array();
513     foreach($arr as $ar){
514       foreach($this->types as $type){
515         if(($type['type'] == $ar)&&($type['status']!="deleted")){
516           $entries[$dn][$ar][] = $type['value'];
517         }
518       }
519     }
520  
521  
522     /* Generate A Records (IP Address relation) */
523     $aRecords = array();
524     foreach($this->types as $type){
525       if(($type['type'] == "aRecord")&&($type['status']!="deleted")){
526         $aRecords[] = $type['value'];
527       }
528     }
529     if(count($aRecords)){
530       
531       /* Add ipHostNumber as default aRecord */
532       $aRecords[] = $this->ipHostNumber;
534       $dn = "relativeDomainName=".$this->cn.",".$this->dn;
535       foreach($aRecords as $rec){
536         $entries[$dn]['aRecord'][] = $rec;      
537       }
538     }
540     /* Generate pTRRecord Records */
541     foreach($this->types as $type){
542       if($type['type'] == "pTRRecord"){
543         $PTRdn= "relativeDomainName=".$type['value'].",".$this->dn;
544         if($type['status']=="deleted"){        
545           $delete [$type['dn']] = $PTRdn;
546         }else{
547           $zones = array_flip($this->Zones);
548           $zone = $zones[$this->zoneName];  
549           $entries[$PTRdn]['relativeDomainName'] = $type['value'];
550           $entries[$PTRdn]['pTRRecord']         = $this->cn.".".$this->zoneName;
551           $entries[$PTRdn]['zoneName']            =  $zone;
552         }
553       }
554     }
556     /* add ObjectClasses */
557     foreach($entries as $key => $entry ){
558       $entries[$key]['objectClass']=array("top","dNSZone");
559       $entries[$key] = array_reverse($entries[$key]);
560     }
562     /* Check if record type has changed, and if we need to delete this record attribute from ldap entry */
563     foreach($this->types as $type){
564       if(isset($type['inittype'])){
565         if(!isset($entries[$dn][$type['inittype']])){
566           $entries[$dn][$type['inittype']] = array();
567         }
568       }
569     }
571     return($entries); 
572   }
575 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
576 ?>