Code

Moved folder image
[gosa.git] / gosa-plugins / dns / admin / systems / services / dns / class_servDNS.inc
1 <?php
3 class servdns extends goService
4 {
5   /* attribute list for save action */
6   var $ignore_account   = FALSE;
7   var $attributes       = array(); 
8   var $objectclasses    = array("whatever");
10   var $RecordTypes      = array();
11   var $Zones            = array();
13   var $orig_dn          = "";
15   var $initially_was_account;
16   
17   /* ServerService tab vars */
18   var $conflicts        = array("servdns");
19   var $DisplayName      = "";
20   var $StatusFlag       = "";
21   var $view_logged      = FALSE;
23   var $dns_server_list   = array("ENTRIES"=> array(),"FOR_LIST"=> array());
24   var $take_over_id       = -1;
27   function servdns (&$config, $dn= NULL, $parent= NULL)
28   {
29     plugin::plugin ($config, $dn, $parent);
31     $this->DisplayName = _("DNS service");
33     $this->orig_dn = $dn;
35     /* Get record types for zones
36      */
37     $this->RecordTypes = DNS::getDnsRecordTypes(true);
39     /* Get all zone Informations
40      */
41     $this->Zones = DNS::getDNSZoneEntries($config,$dn);
42     
43     /* If there is at least one entry in this -> types, we have DNS enabled 
44      */
45     if(count($this->Zones) == 0){
46       $this->is_account = false;
47       $this->dns_server_list = $this->get_list_of_dns_servers();
48     }else{
49       $this->is_account = true;
50     }
51     $this->initially_was_account = $this->is_account;
52   }
55   function get_list_of_dns_servers()
56   {
57     $ret = array("ENTRIES"=> array(),"FOR_LIST"=> array());
58     $ldap = $this->config->get_ldap_link();
59     $ldap->cd($this->config->current['BASE']);
60     $ldap->search("(&(objectClass=dNSZone)(zoneName=*))",array("dn","zoneName"));
61     $dns = array();
62     while($attrs = $ldap->fetch()){
63       /* Skip own config */
64       if($this->dn != "new" && preg_match("/".normalizePreg($this->dn)."$/",$attrs['dn'])){
65         continue;
66       }
67       $dn = preg_replace("/^zoneName=[^,]+,/","",$attrs['dn']);
68       if(preg_match("/^cn=/",$dn) && !in_array($dn,$dns)){
69         $dns[] = $dn;
70       }
71     }
72     $i = 0;
73     foreach($dns as $dn){
74       $ldap->cat($dn,array('*'));
75       if($ldap->count()){
76         $i ++;
77         $attrs = $ldap->fetch();
78           $ret['ENTRIES'][$i]   = $attrs;
79           $ret['FOR_LIST'][$i] = $attrs['cn'][0];
80       }
81     }
82     return($ret);
83   }  
86   function get_dns_info_string($id)
87   {
88     $ret="";
89     $ldap = $this->config->get_ldap_link();
90     $ldap->cd($this->dns_server_list['ENTRIES'][$id]['dn']);
91     $ldap->search("(|(zoneName=*)(relativeDomainName=*))",array("dn"));
92     while($attrs = $ldap->fetch()){
93       $ret .= $attrs['dn']."\n";
94     }
95     return($ret);
96   }
99   function execute()
100   {
101     /* Call parent execute 
102      */
103     plugin::execute();
105     if($this->is_account && !$this->view_logged){
106       $this->view_logged = TRUE;
107       new log("view","server/".get_class($this),$this->dn);
108     }
110     /* Fill templating stuff 
111      */
112     $smarty= get_smarty();
113     $smarty->assign("dns_take_over",FALSE);
114     $smarty->assign("is_createable",$this->acl_is_createable());
115     $display= "";
118     $this->initially_was_account= $this->is_account;
119     /*****************/
120     /* Handle Take Over Actions
121     /*****************/
123     /* Give smarty the required informations */
124     $smarty->assign("dns_server_list", $this->dns_server_list['FOR_LIST']);
125     $smarty->assign("dns_server_list_cnt", count($this->dns_server_list['FOR_LIST']));
127     /* Take over requested, save id */
128     if(isset($_POST['take_over_src']) && isset($_POST['take_over'])){
129       $id = $_POST['take_over_src'];
130       if(isset($this->dns_server_list['ENTRIES'][$id])){
131         $this->take_over_id = $id;
132       }
133     }
135     /* Abort take over action */
136     if(isset($_POST['cancel_take_over'])){
137       $this->dialog =false;
138       $this->take_over_id = -1;
139       $this->dns_server_list = $this->get_list_of_dns_servers();
140     }
142     /* Display informartion about take over that will be started when saving this server
143      *  and hide default dns output
144      */
145     if($this->take_over_id != -1){
146       $this->dialog = FALSE;
147       $id = $this->take_over_id;
148       $info = $this->get_dns_info_string($id);
149       $smarty->assign("dns_take_over",TRUE);
150       $smarty->assign("info",$info);
151       $warning = sprintf(_("You are going to migrate the DNS setup from server '%s'."),$this->dns_server_list['ENTRIES'][$id]['cn'][0]);
152       $warning2 = _("The migration will be started when you save this system. To cancel this action, use the cancel button below.");
153       $smarty->assign("warning",$warning);
154       $smarty->assign("warning2",$warning2);
155       return($smarty->fetch(get_template_path('servdns.tpl', TRUE, dirname(__FILE__))));
156     }
159     /* Do we need to flip is_account state? 
160      */
161     if (isset($_POST['modify_state'])){
162       $this->is_account= !$this->is_account;
163     }
165     if ($this->is_account){
166       $display= $this->show_disable_header(_("Remove DNS service"),
167           _("This server has DNS features enabled. You can disable them by clicking below."));
168     } else {
169       $display= $this->show_enable_header(_("Add DNS service"),
170           _("This server has DNS features disabled. You can enable them by clicking below."));
171       return ($display);
172     }
175     /* Edited or Added zone 
176      */
177     if(isset($_POST['SaveZoneChanges'])){
178       $this->dialog->save_object();
180       /* Check for errors  
181        */
182       if(count($this->dialog->check())){
183         foreach($this->dialog->check() as $msgs){
184           msg_dialog::display(_("Error"), $msgs, ERROR_DIALOG);
185         }
186       }else{
187         /* add new/edited zone 
188          */
189         $ret = $this->dialog->save();
190         if(!$this->dialog->isNew){
191           unset($this->Zones[$this->dialog->OldZoneName]);
192         }
193         $this->Zones[$ret['zoneName']] = $ret;
194         $this->dialog = FALSE;
195       }
196     }
198     /* Cancel zone edit / new 
199      */
200     if(isset($_POST['CancelZoneChanges'])){
201       $this->dialog = FALSE;
202     }
204     /* Add empty new zone 
205      */
206     if(isset($_POST['AddZone'])){
207       $this->dialog = new servdnseditZone($this->config,$this->dn);
208     }
210     /* Check for edit zone request 
211      */
212     $once = false;
213     foreach( $_POST as $name => $value){
214   
215       /* check all post for edit request 
216        */
217       if(preg_match("/^editZone_/",$name)&&!$once){
218         $once =true;
219         $tmp = preg_replace("/^editZone_/","",$name);
220         $tmp = base64_decode(preg_replace("/_.*$/","",$tmp));
221         $this->dialog= new servdnseditZone($this->config,$this->dn,$this->Zones[$tmp]);
222       }
224       /* check posts for delete zone 
225        */
226       if(preg_match("/^delZone_/",$name)&&!$once){
228         $once =true;
229         $tmp = preg_replace("/^delZone_/","",$name);
230         $tmp = base64_decode(preg_replace("/_.*$/","",$tmp));
231      
232         /* Initiate deletion
233          */ 
234         $this->RemoveZone($tmp); 
235       }
236     }
238     if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id'])){
239       $id = base64_decode($_GET['id']);
240       if(isset($this->Zones[$id])){
241          $this->dialog= new servdnseditZone($this->config,$this->dn,$this->Zones[$id]);
242       }
243     }
245     if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id'])){
246       $id = base64_decode($_GET['id']);
247       if(isset($this->Zones[$id])){
248          $this->dialog= new servdnseditZone($this->config,$this->dn,$this->Zones[$id]);
249       }
250     }
252     /* Show dialog 
253      */
254     if(is_object($this->dialog)){
255       $this->dialog->save_object();
256       $this->dialog->parent = $this;
257       return($this->dialog->execute());
258     }
260     /* Create Listbox with existing Zones 
261      */
262     $ZoneList = new divSelectBox("dNSZones");
263     $ZoneList -> SetHeight(254);
265     /* Add entries to divlist
266      */
267     $editImg = "<input type='image' src='images/lists/edit.png' name='editZone_%s'>";
268     if($this->acl_is_removeable()){
269       $editImg.= "<input type='image' src='images/lists/trash.png' name='delZone_%s'>";
270     }
272     $link = "<a href='?plug=".$_GET['plug']."&act=edit&id=%s'>%s</a>";
273     foreach($this->Zones as $zone => $values ){
274       $ZoneList->AddEntry(array(
275             array("string" => sprintf($link,base64_encode($zone),($zone))),
276             array("string" => sprintf($link,base64_encode($zone),_("Reverse zone")." : ".($values['ReverseZone']))),
277             array("string" => _("TTL")." : ".$values['sOAttl']),
278             array("string" => _("Class")." : ".$values['dNSClass']),
279             array("string" =>str_replace("%s",base64_encode($zone),$editImg))
280             ));
281     }    
283     /* Display tempalte 
284      */
285     $smarty->assign("ZoneList",$ZoneList->DrawList());
286     $display.= $smarty->fetch(get_template_path('servdns.tpl', TRUE, dirname(__FILE__)));
287     return($display);
288   }
291   /* Delete specified zone
292    */
293   function RemoveZone($id)
294   {
295     $zones =  $this->getUsedZoneNames();
297     if(isset($this->Zones[$id]['InitialReverseZone'])){
298       $rev = DNS::FlipIp($this->Zones[$id]['InitialReverseZone']);
299     }else{
300       $rev = DNS::FlipIp($this->Zones[$id]['ReverseZone']);
301     }
303     $zonename = "";
304     if(isset($this->Zones[$id]['InitialzoneName'])){
305       $zonename= $this->Zones[$id]['InitialzoneName'];
306     }
308     $used = array();
310     /* Add Records which use this zoneName
311      */
312     if(isset($zones[$zonename])){
313       $used = array_merge($used,$zones[$zonename]);
314     }
316     /* Add Records which uses this reverse zone
317      */
318     if(isset($zones[$rev.".in-addr.arpa"])){
319       $used = array_merge($used,$zones[$rev.".in-addr.arpa"]);
320     } 
322     /* There are still entries using this configuration
323      *  Abort deletion
324      */
325     if(count($used)){
326       $i = 2;
327       $str ="";
328       foreach($used as $dn){
329         if($i > 0 && !preg_match("/,relativeDomainName=/",$dn)){
330           $i --;
331           $name = preg_replace("/^[^=]+=([^,]*),.*$/","\\1",$dn);
332           $zone = preg_replace("/^.*zoneName=([^,]*),.*$/","\\1",$dn);
333           $str.= $name.".".$zone." ";
334         }
335       }
337       /*  Only show 2 dns in the error message 
338        */
339       if(count($used)> 2) {
340         $str .=" ... ";
341       }
342       msg_dialog::display(_("Error"), sprintf(_("Cannot delete the selected zone. It is still in use by '%s'"), trim($str)), ERROR_DIALOG);
343       return(false);
344     }else{
345       unset($this->Zones[$id]);
346       return(true);
347     }
348   } 
351   /* This funtion returns all used Zonenames 
352    */
353   function getUsedZoneNames()
354   {
355     $ret = array();
356     $ldap = $this->config->get_ldap_link();
357     $ldap->cd($this->config->current['BASE']);
358     $ldap->search("(&(objectClass=dNSZone)(!(relativeDomainName=@))(zoneName=*))",array("zoneName","relativeDomainName"));
359     while($attr = $ldap->fetch()){
360       $ret[$attr['zoneName'][0]][] = $attr['dn'];
361     }
362     return($ret);
363   }
366   /* Remove dns service 
367    */
368   function remove_from_parent()
369   {
370     if($this->initially_was_account){
371       $bool = true;
372       $this->is_account = FALSE;
373       foreach($this->Zones as $key => $zone){
374         $bool= $bool & $this->RemoveZone($key);
375       }
377       if($bool){
378         $this->save();
379       }
380       return($bool);
381     }
382   }
385   /* Save to LDAP */
386   function save()
387   {
389     /* Take over handling
390      * - Create list of zones managed by source server 
391      * - Copy ldap entries to destination server 
392      * - Remove old zone entries from source
393      */
394     if($this->take_over_id != -1){
395       $del = array();
396       $id = $this->take_over_id;
397       $src = $this->dns_server_list['ENTRIES'][$id]['dn'];
398       $ldap = $this->config->get_ldap_link(); 
399       $ldap->ls("(objectClass=dnsZone)",$src,array('cn'));
400       while($attrs = $ldap->fetch()){
401         $src_zone = $attrs['dn'];
402         $dst_zone = preg_replace("/".normalizePreg($src)."$/",$this->dn,$src_zone);
403         $res = plugin::recursive_move($src_zone, $dst_zone);
405         if($res){
406           $del [] = $src_zone;
407         }
408       }
409       foreach($del as $src_zone){
410         $ldap->rmdir_recursive($src_zone);
411       }
412       return;
413     }
415     /* Save zone editor changes now */
416     foreach($this->Zones as $name => $zone){
417       if(isset($zone['zoneEditor'] ) && $zone['zoneEditor'] != NULL && is_object($zone['zoneEditor'])){
418         $zone['zoneEditor']->save();
419         unset($this->Zones[$name]['zoneEditor']);;
420       }
421     }
423     $ldap = $this->config->get_ldap_link();
424     $ldap->cd($this->config->current['BASE']);  
425   
426     /* Get differences 
427      */
428     $old_dn = $this->orig_dn;
429     if($old_dn == "new"){
430       $old_dn = $this->dn;
431     }
433     /* Update dns to current object dn */ 
434     $tmp = DNS::getDNSZoneEntriesDiff($this->config,$this->Zones,$old_dn);
435     $tmp2 = array();
436     foreach($tmp as $key1 => $data1){
437       $tmp2[$key1] = array();
438       foreach($data1 as $key2 => $data2){
439         $tmp2[$key1][preg_replace("/".normalizePreg($old_dn)."$/",$this->dn,$key2)] = $data2;
440       }
441     }
442     $tmp = $tmp2;
444     /* Updated zone entries if reverser or forward name has changed  
445      * Must be done before moving entries, else the given dn is invalid
446      */
447     if(isset($tmp['zoneUpdates'])){
448       foreach($tmp['zoneUpdates'] as $dn => $attrs){
449         $ldap->cd($dn);
450         $ldap->modify($attrs);
451         new log("modify","unknown/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
452         if (!$ldap->success()){
453           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
454         }
455       }
456     }
458     /* Delete dns 
459      */
460     foreach($tmp['del'] as $dn => $del){
462       $for = $del['InitialzoneName'];
463       $rev = DNS::FlipIp($del['InitialReverseZone']).".in-addr.arpa";
465       $ldap->cd($dn);
466       $ldap->rmdir_recursive($dn);
467       new log("remove","unknown/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
468       if (!$ldap->success()){
469         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
470       }
472       /* Handle Post events */
473       if(preg_match("/^zoneName=/",$dn)){
474 #        $this->handle_post_events("remove",array("dn" => $dn,"zoneName" => $for));
475 #        $this->handle_post_events("remove",array("dn" => $dn,"zoneName" => $rev));
476       }
477     }
479     /* move follwoing entries
480      */
481     foreach($tmp['move'] as $src => $dst){
482       $this->recursive_move($src,$dst);
483     }
485     /* Add || Update new DNS entries
486      */
487     foreach($tmp['add'] as $dn => $attrs){
488       $ldap->cd($dn);
489       $ldap->cat($dn, array('dn'));
490       if($ldap->fetch()){
491         $ldap->cd($dn);
492         $ldap->modify ($attrs);
493         if (!$ldap->success()){
494           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
495         }
497         /* Handle Post events */
498         if(preg_match("/^zoneName=/",$dn)){
499 #          $this->handle_post_events("modify",array("dn" => $dn,"zoneName" => $attrs['zoneName']));
500         }
501       }else{
502         $ldap->cd($dn);
503         $ldap->add($attrs);
504         if (!$ldap->success()){
505           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_ADD, get_class()));
506         }
508         /* Handle Post events */
509         if(preg_match("/^zoneName=/",$dn)){
510 #          $this->handle_post_events("add",array("dn" => $dn,"zoneName" => $attrs['zoneName']));
511         }
512       }
513     }
514     $this->handle_post_events("modify");
515   }
518   /* Directly save new status flag */
519   function setStatus($value)
520   {
521     if($value == "none") return;
522     if(!$this->initially_was_account) return;
523     if(empty($this->StatusFlag)) return;
524     $ldap = $this->config->get_ldap_link();
525     $ldap->cd($this->dn);
526     $ldap->cat($this->dn,array("objectClass"));
527     if($ldap->count()){
529       $tmp = $ldap->fetch();
530       for($i = 0; $i < $tmp['objectClass']['count']; $i ++){
531         $attrs['objectClass'][] = $tmp['objectClass'][$i];
532       }
533       $flag = $this->StatusFlag;
534       $attrs[$flag] = $value;
535       $this->$flag = $value;
536       $ldap->modify($attrs);
537       if (!$ldap->success()){
538         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
539       }
540       $this->action_hook();
541     }
542   }
545   function getListEntry()
546   {
547     $fields               = goService::getListEntry(); 
548     $fields['Message']    = _("DNS service");
549     $fields['AllowEdit']  = true;
550     return($fields);
551   }
554   /* Get updates for status flag */
555   function updateStatusState()
556   {
557     if(empty($this->StatusFlag)) return;
559     $attrs = array();
560     $flag = $this->StatusFlag;
561     $ldap = $this->config->get_ldap_link();
562     $ldap->cd($this->cn);
563     $ldap->cat($this->dn,array($flag));
564     if($ldap->count()){
565       $attrs = $ldap->fetch();
566     }
567     if(isset($attrs[$flag][0])){
568       $this->$flag = $attrs[$flag][0];
569     }
570   }
573   /* Return plugin informations for acl handling */
574   static function plInfo()
575   {
576     return (array(
577           "plShortName"   => _("DNS service"),
578           "plDescription" => _("DNS service")." ("._("Services").")",
579           "plSelfModify"  => FALSE,
580           "plDepends"     => array(),
581           "plPriority"    => 83,
582           "plSection"     => array("administration"),
583           "plCategory"    => array("server"),
585           "plProvidedAcls"=> array(
586             "zoneName"      =>_("Zone name"),
587             "ReverseZone"   =>_("Reverse zone"),
588             "sOAprimary"    =>_("Primary dns server"),
589             "sOAmail"       =>_("Mail address"),
590             "sOAserial"     =>_("Serial"),
591             "sOArefresh"    =>_("Refresh"),
592             "sOAretry"      =>_("Retry"),
593             "sOAexpire"     =>_("Expire"),
594             "sOAttl"        =>_("TTL"),
595             "zoneRecords"   =>_("Zone records"))
596     ));
597   }
600 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
601 ?>