Code

Added initial dhcp client settings.
[gosa.git] / plugins / admin / systems / class_termDNS.inc
1 <?php
3 class termDNS extends plugin
4 {
5   /* attribute list for save action */
6   var $ignore_account = true;
7   var $autonet        = false;
9   /* Basic informations 
10    */
11   var $attributes     = array("ipHostNumber","macAddress");
12   var $objectclasses  = array("whatever");
14   var $ipHostNumber   = "";    // IP address 
15   var $macAddress     = "";    // Mac address 
16   var $cn             = "";    // CN of currently edited device 
17   var $OrigCn         = "";    // Initial cn
18   var $IPisMust       = false;
19   var $MACisMust      = false;
20   var $dialog;
22   /* DCHP Attributes 
23    */
24   var $dhcpAttributes           = array("dhcpParentNode");
25   var $dhcpEnabled              = FALSE;
26   var $dhcp_is_Account          = FALSE;
27   var $dhcpParentNodes          = array();
28   var $dhcpParentNode           = "";
29   var $dhcpHostEntry            = array();
30   var $initial_dhcpParentNode   = "";
31   var $initial_dhcpHostEntry    = array();
34   /* DNS attributes  
35    */
36   var $DNSattributes            = array("dNSClass","zoneName","dNSTTL");
37   var $DNS_is_Account           = false;
38   var $DNSinitially_was_account = false;
39   var $dnsEntry                 = array();
40   var $DNSenabled               = false;
42   /*  Terminal dns 
43    */
44   function termDNS ($config, $dn,$objectClasses,$IPisMust = false)
45   {
46     /* We need to know which objectClasses are used, to store the ip/mac
47      * Because of different type of devices   
48      */
49     $this->objectclasses  =  $objectClasses;
50     $this->IPisMust       = $IPisMust;
52     plugin::plugin ($config, $dn);
54     if(isset($this->attrs['cn'][0])){
55       $this->OrigCn = preg_replace("/\\\$\$/","",$this->attrs['cn'][0]);
56       $this->cn = preg_replace("/\\\$\$/","",$this->attrs['cn'][0]);
57     }
59  
60     /************
61      * DHCP 
62      ************/
64     /* Hide all dhcp specific code, if dhcp plugin is not present in config */
65     $dhcpEnabled = FALSE;
66     foreach($this->config->data['TABS']['SERVTABS'] as $tab){
67       if(preg_match("/^servdhcp$/",$tab['CLASS'])){
68         $this->dhcpEnabled = TRUE;
69       }
70     }
71     if($this->dhcpEnabled){
72       $this->dhcpParentNodes = $this->get_dhcp_parent_nodes();
73       $this->dhcpParentNode  = $this->get_dhcp_parent_node();
74       if($this->dhcpParentNode){
75         $this->dhcp_is_Account = TRUE;
76         $this->dhcpHostEntry  = $this->get_dhcp_host_entry();    
77       }
78       $this->initial_dhcpHostEntry = $this->dhcpHostEntry;
79       $this->initial_dhcpParentNode= $this->dhcpParentNode;
80     }
83     /************
84      * Autonetwork hook 
85      ************/
86  
87     /* Do we have autonet support? */
88     if (isset($this->config->data['MAIN']['AUTO_NETWORK_HOOK'])){
89       $this->autonet= true;
90     }
93     /************
94      * DNS
95      ************/
96  
97     /* Hide all dns specific code, if dns is not available 
98      */
99     $DNSenabled = false;
100     foreach($this->config->data['TABS']['SERVTABS'] as $tab){
101       if(preg_match("/^servdns$/",$tab['CLASS'])){
102         $this->DNSenabled = true;
103       }
104     }
105     if(!$this->DNSenabled){
106       $this->DNS_is_account = false;
107       return;
108     }
110     if($this->DNSenabled){
112       /* Get Zones  
113        */
114       $this->Zones        = getAvailableZones($config);
116       /* Get Entry 
117        */
118       $this->dnsEntry     = getDNSHostEntries($config,$this->OrigCn);
120       /* Remove A record which equals $this->ipHostNumber
121        */
122       foreach($this->dnsEntry['RECORDS'] as $key => $rec){
123         if(($rec['type'] == "aRecord") && ($rec['value'] == $this->ipHostNumber)){
124           unset($this->dnsEntry['RECORDS'][$key]);
125         }
126       }
128       /* Get Record types 
129        */
130       $this->RecordTypes  = getDnsRecordTypes();
132       /* If there is at least one entry in this -> types, we have DNS enabled 
133        */
134       if($this->dnsEntry['exists']){
135         $this->DNS_is_account = true;
136       }else{
137         $this->DNS_is_account = false;
138       }
139    
140     }
141  
142     /* Store initally account settings 
143      */
144     $this->DNSinitially_was_account = $this->DNS_is_account;
145   }
148   function netmaskIsCoherent($idZone) 
149   {
150     $netmask = FlipIp(str_replace(".in-addr.arpa","",getNameFromMix($idZone)));
151     if(!strstr($this->ipHostNumber, $netmask)){
152       return false;
153     }else{
154       return true;
155     }
156   }
159   function getVarsForSaving($attrs) 
160   {
161     foreach($this->attributes as $attr){
162       if(!empty($this->$attr)){
163         $attrs[$attr] = $this->$attr;
164       }
165     }
166     return($attrs); 
167   }
169   function execute()
170   {
171           /* Call parent execute */
172     $smarty= get_smarty();
173     $display= "";
175     $smarty->assign("staticAddress", ""); 
176     $smarty->assign("autonet", $this->autonet);
177  
178     /* Check for autonet button */
179     if ($this->autonet && isset($_POST['autonet'])){
180       $cmd= $this->config->data['MAIN']['AUTO_NETWORK_HOOK'];
181       if(!empty($cmd) && $this->cn != ""){
182         $res = shell_exec($cmd." ".$this->cn);
183         if(!$res){
184           print_red(sprintf(_("Can't execute specified AUTO_NETWORK_HOOK '%s'. Please check your gosa.conf."),$cmd));
185         } else {
186           $res= split(';', trim($res));
187           if (isset($res[0]) && $res[0] != ""){
188             $this->ipHostNumber= $res[0];
189           }
190           if (isset($res[1]) && $res[1] != ""){
191             $this->macAddress= $res[1];
192           }
193         }
194       }
195     }
197     
198   
199     /**********
200      * DHCP Handling
201      **********/
202  
203     if(isset($_POST['dhcpEditOptions'])){
204       $this->dialog = new dhcpHost($this->dhcpHostEntry);
205     }
207     if(isset($_POST['cancel_dhcp'])){
208       $this->dialog = FALSE; 
209     }
211     if(isset($_POST['save_dhcp'])){
212       $this->dialog = FALSE; 
213     }
215     if(isset($this->dialog) && $this->dialog != FALSE){
216       return($this->dialog->execute());
217     }
218  
219     $smarty->assign("dhcpEnabled",    $this->dhcpEnabled);
220     $smarty->assign("dhcp_is_Account",$this->dhcp_is_Account);
221     $smarty->assign("dhcpParentNode", $this->dhcpParentNode);
222     $smarty->assign("dhcpParentNodes",$this->dhcpParentNodes);
229     /* There is no dns available 
230      */
231     if($this->DNSenabled == false){
232        
233       /* Is IP address must ? */ 
234       $smarty->assign("DNS_is_account",false);  
235       $smarty->assign("IPisMust",(($this->IPisMust)||($this->DNS_is_account)));
236     
237       /* Assign smarty all non DNs attributes */
238       foreach($this->attributes as $attr){
239         $smarty->assign($attr,$this->$attr);
240         $smarty->assign($attr."ACL",chkacl($this->acl,$attr));
241       }
242       $smarty->assign("staticAddress","<font class=\"must\">*</font>");
244       $display.= $smarty->fetch(get_template_path('network.tpl', TRUE));
245     }else{
246       $smarty->assign("DNS_is_account",true); 
248       /* Add new empty array to our record list */
249       if(isset($_POST['AddNewRecord'])){
250         $this->dnsEntry['RECORDS'][]  =array("type"=>"aRecord","value"=>"");
251       }
253       /* Handle all posts */ 
254       $only_once =true;
255       foreach($_POST as $name => $value){
257         /* Check if we have to delete a record entry */
258         if((preg_match("/RemoveRecord_/",$name))&&($only_once)) {
260           /* Avoid performing this once again */
261           $only_once = false;
263           /* Extract id for specified entry */
264           $id = preg_replace("/RemoveRecord_/","",$name);
265           $id = preg_replace("/_.*$/","",$id);
267           /* Delete this record, mark edited entries to be able to delete them */
268           if(isset($this->dnsEntry['RECORDS'][$id])){
269             unset($this->dnsEntry['RECORDS'][$id]);
270           }
271         }
272       }
274       /* Assign smarty all non DNs attributes */
275       foreach($this->attributes as $attr){
276         $smarty->assign($attr,$this->$attr);
277         $smarty->assign($attr."ACL",chkacl($this->acl,$attr));
278       }
280       /* Assign smarty all DNS attributes */
281       foreach($this->DNSattributes as $attr){
282         $smarty->assign($attr,$this->dnsEntry[$attr]);
283         $smarty->assign($attr."ACL",chkacl($this->acl,$attr));
284       }
286       /* Assign all needed vars */
287       $smarty->assign("DNSaccountACL",chkacl($this->acl,"termDNS"));
289       $smarty->assign("DNSAccount",$this->DNS_is_account);
290       $smarty->assign("Zones",$this->Zones);
291       $smarty->assign("ZoneKeys",($this->Zones));
292       $smarty->assign("IPisMust",(($this->IPisMust)||($this->DNS_is_account)));
294       /* Create zone array */
295       $idZones = array();
296       foreach($this->Zones as $id => $zone){
297         if($this->netmaskIsCoherent($id)) {
298           $idZones[$id] = $zone;
299         }else{
300           $idZones[$id] = $zone."&nbsp;("._("Not matching").")";
301         }
302       }    
303       $smarty->assign("Zones",$idZones);
304       $smarty->assign("ZoneKeys", $this->Zones);
306       $tmp = $this->generateRecordsList();
308       $changeStateForRecords = $tmp['changeStateForRecords'];
310       $smarty->assign("records",$tmp['str']);
311       $smarty->assign("changeStateForRecords",$changeStateForRecords);
312       $smarty->assign("staticAddress","<font class=\"must\">*</font>");
314       $display.= $smarty->fetch(get_template_path('network.tpl', TRUE));
315     }
316     return($display);
317   }
319   function remove_from_parent()
320   {
321     /*
322     $ldap = $this->config->get_ldap_link();
323     $ldap->cd($this->orig_dn);
324     $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("relativeDomainName","zoneName"));
325     while($attr = $ldap->fetch()){  
326       $ldap->cd($attr['dn']);
327       $ldap->rmDir($attr['dn']);
328       show_ldap_error("Record:".$ldap->get_error(), _("Removing terminal from DNS object failed")); 
329     }
330     */
331   }
333   /* Save data to object */
334   function save_object()
335   {
336     /* Save all posted vars */
337     plugin::save_object();
338   
340     /* Handle DHCP Posts*/ 
341     if($this->dhcpEnabled && isset($_POST['network_tpl_posted'])){
342       if(isset($_POST['dhcp_is_Account'])){
343         $this->dhcp_is_Account = TRUE;
344       }else{
345         $this->dhcp_is_Account = FALSE;
346       }
347       foreach($this->dhcpAttributes as $attr){
348         if(isset($_POST[$attr])){
349           $this->$attr = $_POST[$attr];
350         }
351       }
352     }
353  
354  
355     /* Get dns attributes */
356     if(($this->DNSenabled) && (isset($_POST['network_tpl_posted'])) && chkacl($this->acl,"termDNS") == ""){
358       /* Check for posted record changes */
359       if(is_array($this->dnsEntry['RECORDS'])){
360         foreach($this->dnsEntry['RECORDS'] as $key => $value){
362           /* Check if type has changed */
363           if(isset($_POST['RecordTypeSelectedFor_'.$key])){
364             $this->dnsEntry['RECORDS'][$key]['type'] = $_POST['RecordTypeSelectedFor_'.$key];
365           }
366           /* Check if value has changed */
367           if(isset($_POST['RecordValue_'.$key])){
368             $this->dnsEntry['RECORDS'][$key]['value'] = $_POST['RecordValue_'.$key];
369           }
370         }
371       }
372       /* Get all basic DNS attributes (TTL, Clas ..)*/
373       foreach($this->DNSattributes as $attr){
374         if(isset($_POST[$attr])){
375           $this->dnsEntry[$attr] = $_POST[$attr];
376         }
377       }
379       /* Enable diable DNS */
380       if(isset($_POST['enableDNS'])){
381         $this->DNS_is_account = true;
382       }else{
383         $this->DNS_is_account = false;
384       }
385     }
386   }
389   /* Check supplied data */
390   function check()
391   {
392     /* Call common method to give check the hook */
393     $message= plugin::check();
395     /* Check if ip must be given
396      */  
397     if(($this->IPisMust)||($this->DNS_is_account)){
398   
399       /* Check if ip is empty 
400        */
401       if ($this->ipHostNumber == "" && chkacl ($this->acl, "ipHostNumber") == ""){
402         $message[]= _("The required field 'IP-address' is not set.");
403       }
405     }
407     /* check if given ip is valid ip */
408     if ($this->ipHostNumber != "" && !is_ip($this->ipHostNumber)){
409       $message[]= _("Wrong IP format in field IP-address.");
410     }
412     /* Check if mac is empty 
413      */
414     if ($this->macAddress == "" && chkacl ($this->acl, "macAddress") == ""){
415       $message[]= _("The required field 'MAC-address' is not set.");
416     }
418     /* Check if given mac is valid mac 
419      */
420     if(!is_mac($this->macAddress)){
421       $message[]=(_("The given macaddress is invalid. There must be 6 2byte segments seperated by ':'."));
422     }
424     /* only perfrom this checks if this is a valid DNS account */
425     if($this->DNS_is_account){
427       $checkArray = array();
428       $onlyOnce   = array();
430       $tmp = array_flip($this->Zones);
431       $tmp2 = $tmp[$this->dnsEntry['zoneName']];
432       if(!$this->netmaskIsCoherent($tmp2)){ //this->dnsEntry['zoneName'])){
433         $tmp2 = preg_replace("/^.*\//","",$tmp2);
434         $message[] =sprintf(_("The specified IP address '%s' is not matching the selected reverse zone entry '%s'."),$this->ipHostNumber,$tmp2);
435       }
437                         // There can be many CNAME records
438       //$onlyOnce['cNAMERecord'] = 0;
440       /* Walk through all entries and detect duplicates or mismatches
441        */  
442       foreach($this->dnsEntry['RECORDS'] as $name => $values){
444         /* Count record values, to detect duplicate entries for a specific record
445          */
446         if(!isset($checkArray[$values['type']][$values['value']])){
447           $checkArray[$values['type']][$values['value']] = 0;
448         }else{
449           $message[] = sprintf(_("Found duplicate value for record type '%s'."),$values['type']);
450         }
452         /* Check if given entries in $onlyOnce are used more than once
453          */
454         if(isset($onlyOnce[$values['type']])){
455           $onlyOnce[$values['type']] ++;
456           if($onlyOnce[$values['type']] > 1){
457             $message[] = sprintf(_("Found more than one entry for the uniqe record type '%s'."),$values['type']);
458           }
459         }
461         /* Skip txt record ... 
462          */
463         if($values['type'] == "tXTRecord") continue;
465         /* Check if there is an aRecord defined which uses the same IP as used in IPhostAddress 
466          */
467         if(($values['type'] == "aRecord")&&($values['value'] == $this->ipHostNumber)){
468           $message[]=sprintf(_("The device IP '%s' is added as 'A Record', this will be done automatically, please remove the record."), 
469                $this->ipHostNumber);
470         }
472         /* only lower-case is allowed in record entries ... 
473          */
474         if($values['value'] != strtolower($values['value'])){
475           $message[] = sprintf(_("Only lowercase is allowed, please check your '%ss'."),$values['type']);
476         }
477       }
478     }
479     return ($message);
480   }
483   /* Save to LDAP */
484   function save($dn)
485   {
486     $ldap= $this->config->get_ldap_link();
487    
488     /*******************/ 
489     /* IP-MAC HANDLING */
490     /*******************/ 
492     /* $dn was posted as parameter */
493     $this->dn = $dn;
494     
495     /* Save DNS setting & ip/Mac*/
496     plugin::save();
498     /* Write back to ldap */
499     $ldap->cd($this->dn);
500     $this->cleanup();
501     $ldap->modify ($this->attrs); 
503     /****************/ 
504     /* DNS HANDLING */
505     /****************/ 
507     /* If isn't DNS account but initially was DNS account 
508        remove all DNS entries 
509      */ 
510     if((!$this->DNSenabled) || (!$this->DNS_is_account && !$this->DNSinitially_was_account)){
511       return;
512     }else{
514       /* Add ipHostNumber to aRecords
515        */
516       if(!empty($this->ipHostNumber)){
517         $this->dnsEntry['RECORDS'][] = array("type"=>"aRecord","value"=>$this->ipHostNumber);
518       }
520       /* Create diff and follow instructions 
521        * If Account was disabled, remove account by setting exists to false
522        */
523       if((!$this->DNS_is_account)&&($this->DNSinitially_was_account)){  
524         $this->dnsEntry['exists'] = false;
525         $tmp = getDNSHostEntriesDiff($this->config,$this->OrigCn,$this->dnsEntry,$this->cn);
526       }else{
527         $this->dnsEntry['exists'] = $this->DNS_is_account;
528         $tmp = getDNSHostEntriesDiff($this->config,$this->OrigCn,$this->dnsEntry,$this->cn);
529       }   
531       /* move follwoing entries 
532        */
533       foreach($tmp['move'] as $src => $dst){
534         $this->recursive_move($src,$dst);
535       }
537       /* Delete dns */
538       foreach($tmp['del'] as $dn => $del){
539         $ldap->cd($dn);
540         $ldap->rmdir_recursive($dn);
541       }
543       /* Add || Update new DNS entries 
544        */
545       foreach($tmp['add'] as $dn => $attrs){
546         $ldap->cd($dn);
547         $ldap->cat($dn, array('dn'));
548         if(count($ldap->fetch())){
549           $ldap->cd($dn);
550           $ldap->modify ($attrs); 
551         }else{
552           $ldap->cd($dn);
553           $ldap->add($attrs);
554         }
555       }
557       /* Display errors 
558        */
559       if($ldap->get_error() != "Success"){
560         show_ldap_error("Record:".$ldap->get_error(), _("Saving terminal to DNS object failed")); 
561       }
562     }
563   }
565   /*  Create html table with all used record types
566    */
567   function generateRecordsList()
568   {
569     $changeStateForRecords = "";
570     
571     if(!$this->DNS_is_account) {
572       $str = "<input type='submit' value='"._("Add")."' name='AddNewRecord' id='AddNewRecord' disabled='disabled'>";
573       return $str;
574     }
575  
576     $str = "<table summary='' width='100%'>";
577     foreach($this->dnsEntry['RECORDS'] as $key => $entry){
579         $changeStateForRecords.= "changeState('RecordTypeSelectedFor_".$key."');\n";
580         $changeStateForRecords.= "changeState('RecordValue_".$key."');\n";
581         $changeStateForRecords.= "changeState('RemoveRecord_".$key."');\n";
583         $str.=" <tr>".
584           "   <td>".$this->generateRecordListBox($entry['type'],"RecordTypeSelectedFor_".$key)."</td>".
585           "   <td><input ".chkacl($this->acl,"termDNS")." type='text' value='".$entry['value']."' name='RecordValue_".$key."' id='RecordValue_".$key."'></td>".
586           "   <td><input ".chkacl($this->acl,"termDNS")." type='submit' name='RemoveRecord_".$key."' value='"._("Delete")."' id='RemoveRecord_".$key."'></td>".
587           "</tr>";
588     }
590     $str.= "  <tr>".
591            "    <td colspan=2 width='50%'></td><td>".
592            "      <input type='submit' value='"._("Add")."' name='AddNewRecord' ".chkacl($this->acl,"termDNS")." >".
593            "    </td>".
594            "  </tr>".
595            "</table>";
596      $ret =  array("str" => $str, "changeStateForRecords" => $changeStateForRecords);
597     return($ret);
598   }
601   /* Create a html select box which allows us to select different types of records 
602    */
603   function generateRecordListBox($selected,$name)
604   {
605     $str = "<select ".chkacl($this->acl,"termDNS")."  name='".$name."' id='".$name."'>";
606     foreach($this->RecordTypes as $type => $value){
607       $use = "";
608       if($type == $selected){
609         $use = " selected ";
610       }
611       $str.="\n <option value='".$type."' ".$use.">".strtoupper(preg_replace("/record/i","",$type))."</option>";
612     }
613     $str.="</select>";
614     return($str); 
615   }
617   
618   function get_dhcp_host_entry()
619   {
620     $attrs = array();
621     $dn = $this->get_dhcp_host_entry_dn();
622     if($dn){
623       $ldap = $this->config->get_ldap_link();
624       $ldap->cd($this->config->current['BASE']);
625       $ldap->cat($dn,array("*"));
626       if($ldap->count()){
627         $attrs = $ldap->fetch();
628         foreach($attrs as $key => $value){
629           if(is_numeric($key) || ($key == "count")){
630             unset($attrs[$key]);
631           }
632           if(is_array($value) && isset($value['count'])){
633             unset($attrs[$key]['count']);
634           }
635         }
636       }
637     }
638     return($attrs);
639   }
642   function get_dhcp_host_entry_dn()
643   {
644     $ldap = $this->config->get_ldap_link();
645     $ldap->cd($this->config->current['BASE']);
646     $ldap->search ("(&(objectClass=dhcpHost)(cn=".$this->cn."))",array("cn","dn"));
648     if($ldap->count()){
649       $attr = $ldap->fetch();
650       return($attr['dn']);
651     }else{
652       return("");
653     }
654   }  
657   function get_dhcp_parent_node()
658   {
659     return(preg_replace("/^cn=".normalizePreg($this->cn).",/","",$this->get_dhcp_host_entry_dn()));
660   }
663   function get_dhcp_parent_nodes()
664   {
665     $ldap = $this->config->get_ldap_link();
666     $ldap->cd($this->config->current['BASE']);
667     $ldap->search("(objectClass=dhcpService)",array("dhcpPrimaryDN"));
668     
669     $dhcp_dns = array();
670     while($attr = $ldap->fetch()){
671       $dhcp_dns[$attr['dn']] = $attr['dhcpPrimaryDN'][0];
672     }
673   
674     foreach($dhcp_dns as $key => $pri_dns){
675       $ldap->cat($pri_dns,array("cn"));
676       $tmp = $ldap->fetch();
677       $dhcp_dns[$key] = $tmp['cn'][0];
678     }
679  
680     foreach($dhcp_dns as $dn => $cn){
681       $ldap->cd($dn);
682       $ldap->search("(|(objectClass=dhcpService)(objectClass=dhcpGroup)".
683                     "(objectClass=dhcpSubnet)(objectClass=dhcpSharedNetwork))",array("cn"));
684       $tmp = array();
685       while($attr = $ldap->fetch()){
686         $tmp[$attr['dn']] = $attr['cn'][0];
687       }
688       $tmp2 = $this->create_tree($tmp,preg_replace("/^[^,]+,/i","",$dn),"(".$cn.")&nbsp;");
689     }
690     return($tmp2);
691   }
693   
694   function create_tree($arr,$base,$current = "")
695   {
696     $ret = array();
697     foreach($arr as $r => $name){
698       $base_part = str_replace($base,"",$r);
699       if(preg_match("/^[a-z]*=".normalizePreg($name)."(|,)$/i",$base_part)){
700         $ret[$r] = $current.$name;
701         $tmp = $this->create_tree($arr,$r,$current.".&nbsp;");
702         foreach($tmp as $sub_key => $sub_name){
703           $ret[$sub_key] = $sub_name;
704         }
705       } 
706     }
707     return($ret);
708   }
711 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
712 ?>