Code

- Correcting spelling
[gosa.git] / plugins / admin / systems / class_servDNS.inc
1 <?php
3 class servdns extends plugin
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();
12   var $dialog           = NULL;
14   var $orig_dn          = "";
16   var $DNSinitially_was_account;
18   var $dns_server_list   = array("ENTRIES"=> array(),"FOR_LIST"=> array());
19   var $take_over_id       = -1;
20   var $display_warning  = TRUE;
22   function servdns ($config, $dn= NULL, $parent= NULL)
23   {
24     plugin::plugin ($config, $dn, $parent);
26     $this->orig_dn = $dn;
28     /* Get record types for zones
29      */
30     $this->RecordTypes = getDnsRecordTypes(true);
32     /* Get all zone Informations
33      */
34     $this->Zones = getDNSZoneEntries($config,$dn);
35   
36     /* If there is at least one entry in this -> types, we have DNS enabled 
37      */
38     if(count($this->Zones) == 0){
39       $this->is_account = false;
40       $this->dns_server_list = $this->get_list_of_dns_servers();
41     }else{
42       $this->is_account = true;
43     }
44     $this->DNSinitially_was_account = $this->is_account;
45   }
48   function get_list_of_dns_servers()
49   {
50     $ret = array("ENTRIES"=> array(),"FOR_LIST"=> array());
51     $ldap = $this->config->get_ldap_link();
52     $ldap->cd($this->config->current['BASE']);
53     $ldap->search("(&(objectClass=dNSZone)(zoneName=*))",array("dn","zoneName"));
54     $dns = array();
55     while($attrs = $ldap->fetch()){
56       /* Skip own config */
57       if($this->dn != "new" && preg_match("/".normalizePreg($this->dn)."$/",$attrs['dn'])){
58         continue;
59       }
60       $dn = preg_replace("/^zoneName=[^,]+,/","",$attrs['dn']);
61       if(preg_match("/^cn=/",$dn) && !in_array($dn,$dns)){
62         $dns[] = $dn;
63       }
64     }
65     $i = 0;
66     foreach($dns as $dn){
67       $ldap->cat($dn,array('*'));
68       if($ldap->count()){
69         $i ++;
70         $attrs = $ldap->fetch();
71           $ret['ENTRIES'][$i]   = $attrs;
72           $ret['FOR_LIST'][$i] = $attrs['cn'][0];
73       }
74     }
75     return($ret);
76   }  
79   function execute()
80   {
81     /* Call parent execute 
82      */
83     plugin::execute();
85     /* Fill templating stuff 
86      */
87     $smarty= get_smarty();
88     $smarty->assign("dns_take_over",FALSE);
89     $display= "";
92     /*****************/
93     /* Handle Take Over Actions
94     /*****************/
96     /* Give smarty the required informations */
97     $smarty->assign("dns_server_list", $this->dns_server_list['FOR_LIST']);
98     $smarty->assign("dns_server_list_cnt", count($this->dns_server_list['FOR_LIST']));
100     /* Take over requested, save id */
101     if(isset($_POST['take_over_src']) && isset($_POST['take_over'])){
102       $id = $_POST['take_over_src'];
103       if(isset($this->dns_server_list['ENTRIES'][$id])){
104         $this->take_over_id = $id;
105       }
106     }
108     /* Abort take over action */
109     if(isset($_POST['cancel_take_over'])){
110       $this->dialog =false;
111       $this->take_over_id = -1;
112       $this->dns_server_list = $this->get_list_of_dns_servers();
113     }
115     /* Display informartion about take over that will be started when saving this server
116      *  and hide default dns output
117      */
118     if($this->take_over_id != -1){
119       $this->dialog = FALSE;
120       $id = $this->take_over_id;
121       $smarty->assign("dns_take_over",TRUE);
122       $warning = sprintf(_("You are going to migrate the DNS setup from server '%s'."),$this->dns_server_list['ENTRIES'][$id]['cn'][0]);
123 #      $warning.= "&nbsp;"._("This includes 'all' DNS zones that are located within this server. Please double check if your really want to do this.");
124       $warning.= "&nbsp;"._("The migration will be started when you save this system. To cancel this action, use the cancel button below.");
126       if($this->display_warning){
127         print_red($warning);
128         $this->display_warning = FALSE;
129       }
130       return($smarty->fetch(get_template_path('servdns.tpl', TRUE)));
131     }
134     /* Do we need to flip is_account state? 
135      */
136     if (isset($_POST['modify_state'])){
138       /* Only change account state if allowed */
139       if($this->is_account && $this->acl == "#all#"){
140         $this->is_account= !$this->is_account;
141         $this->is_modified = true;
142       }elseif(!$this->is_account && chkacl($this->acl,"create") == ""){
143         $this->is_account= !$this->is_account;
144         $this->is_modified = true;
145       }
146     }
148     if ($this->is_account){
149       $display= $this->show_header(_("Remove DNS service"),
150           _("This server has DNS features enabled. You can disable them by clicking below."));
151     } else {
152       $display= $this->show_header(_("Add DNS service"),
153           _("This server has DNS features disabled. You can enable them by clicking below."));
154       return ($display);
155     }
158     /* Edited or Added zone 
159      */
160     if((isset($_POST['SaveZoneChanges'])) && is_object($this->dialog)){
161       $this->dialog->save_object();
163       /* Check for errors  
164        */
165       if(count($this->dialog->check())){
166         foreach($this->dialog->check() as $msgs){
167           print_red($msgs); 
168         }
169       }else{
170         /* add new/edited zone 
171          */
172         $ret = $this->dialog->save();
173         if(!$this->dialog->isNew){
174           unset($this->Zones[$this->dialog->OldZoneName]);
175         }
176         $this->Zones[$ret['zoneName']] = $ret;
177         $this->dialog = NULL;
178       }
179     }
181     /* Cancel zone edit / new 
182      */
183     if(isset($_POST['CancelZoneChanges'])){
184       $this->dialog = NULL;
185     }
187     /* Add empty new zone 
188      */
189     if(isset($_POST['AddZone']) && chkacl($this->acl,"servdns") == ""){
190       $this->dialog = new servdnseditZone($this->config,$this->dn);
191     }
193     /* Check for edit zone request 
194      */
195     $once = false;
196     foreach( $_POST as $name => $value){
197   
198       /* check all post for edit request 
199        */
200       if(preg_match("/^editZone_/",$name)&&!$once && chkacl($this->acl,"servdns") == ""){
201         $once =true;
202         $tmp = preg_replace("/^editZone_/","",$name);
203         $tmp = base64_decode(preg_replace("/_.*$/","",$tmp));
204         $this->dialog= new servdnseditZone($this->config,$this->dn,$this->Zones[$tmp]);
205       }
207       /* check posts for delete zone 
208        */
209       if(preg_match("/^delZone_/",$name)&&!$once && chkacl($this->acl,"servdns") == ""){
211         $once =true;
212         $tmp = preg_replace("/^delZone_/","",$name);
213         $tmp = base64_decode(preg_replace("/_.*$/","",$tmp));
214      
215         /* Initiate deletion
216          */ 
217         $this->RemoveZone($tmp); 
218       }
219     }
221     if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id'])){
222       $id = base64_decode($_GET['id']);
223       if(isset($this->Zones[$id])){
224          $this->dialog= new servdnseditZone($this->config,$this->dn,$this->Zones[$id]);
225       }
226     }
228     /* Show dialog 
229      */
230     if($this->dialog!= NULL){
231       $this->dialog->save_object();
232       $this->dialog->parent = $this;
233       return($this->dialog->execute());
234     }
236     /* Create Listbox with existing Zones 
237      */
238     $ZoneList = new divSelectBox("dNSZones");
239     $ZoneList -> SetHeight(300);
241     /* Add entries to divlist
242      */
243     $editImg = "<input type='image' src='images/edit.png' name='editZone_%s'>
244       <input type='image' src='images/edittrash.png' name='delZone_%s'>";
245     foreach($this->Zones as $zone => $values ){
246       $link = "<a href='?plug=".$_GET['plug']."&act=edit&id=%s'>%s</a>";
247       $ZoneList->AddEntry(array(
248             array("string" => sprintf($link,base64_encode($zone),getNameFromMix($zone))),
249             array("string" => sprintf($link,base64_encode($zone),_("Reverse zone")." : ".getNameFromMix($values['ReverseZone']))),
250             array("string" => _("TTL")." : ".$values['sOAttl']),
251             array("string" => _("Class")." : ".$values['dNSClass']),
252             array("string" => str_replace("%s",base64_encode($zone),$editImg))
253             ));
254     }    
255   
256     $smarty->assign("servdnsACL",chkacl($this->acl,"servdns"));
257   
258     /* Display tempalte 
259      */
260     $smarty->assign("ZoneList",$ZoneList->DrawList());
261     $display.= $smarty->fetch(get_template_path('servdns.tpl', TRUE));
262     return($display);
263   }
266   /* Delete specified zone
267    */
268   function RemoveZone($id)
269   {
270     $zones =  $this->getUsedZoneNames();
271     $rev  ="";
272   
273     if(isset($this->Zones[$id]['InitialReverseZone'])){
274       $rev = FlipIp(getNameFromMix($this->Zones[$id]['InitialReverseZone']));
275     }elseif(isset($this->Zones[$id]['ReverseZone'])){
276       $rev = FlipIp(getNameFromMix($this->Zones[$id]['ReverseZone']));
277     }
279     $zonename = "";
280     if(isset($this->Zones[$id]['InitialzoneName'])){
281       $zonename= getNameFromMix($this->Zones[$id]['InitialzoneName']);
282     }
284     $used = array();
286     /* Add Records which use this zoneName
287      */
288     if(isset($zones[$zonename])){
289       $used = array_merge($used,$zones[$zonename]);
290     }
292     /* Add Records which uses this reverse zone
293      */
294     if(isset($zones[$rev.".in-addr.arpa"])){
295       $used = array_merge($used,$zones[$rev.".in-addr.arpa"]);
296     } 
298     /* There are still entries using this configuration
299      *  Abort deletion
300      */ 
301     if(count($used)){
302       $i = 2;
303       $str ="";
304       foreach($used as $dn){
305         if($i > 0 ){
306           $i --;
307           $str.=$dn." ";
308         }
309       }
311       /*  Only show 2 dns in the error message 
312        */
313       if(count($used)> 2) {
314         $str .=" ... ";
315       }
316       print_red(sprintf(_("Can't delete the selected zone, because it is still in use by these entry/entries '%s'"),trim($str)));
318     }else{
319       unset($this->Zones[$id]);
320       return(true);
321     }
322     return(false);
323   } 
326   /* This funtion returns all used Zonenames 
327    */
328   function getUsedZoneNames()
329   {
330     $ret = array();
331     $ldap = $this->config->get_ldap_link();
332     $ldap->cd($this->config->current['BASE']);
333     $ldap->search("(&(objectClass=dNSZone)(!(relativeDomainName=@))(zoneName=*))",array("zoneName","relativeDomainName"));
334     while($attr = $ldap->fetch()){
335       $ret[$attr['zoneName'][0]][] = $attr['dn'];
336     }
337     return($ret);
338   }
342     /* Remove dns service
343    */
344   function remove_from_parent()
345   {
346     if($this->DNSinitially_was_account){
347       $this->is_account = FALSE;
348       $bool = true;
349       foreach($this->Zones as $key => $zone){
350         $bool= $bool & $this->RemoveZone($key);
351       }
353       if($bool){
354         $this->save();
355       }
356       return($bool);
357     }
358   }
362   /* Save to LDAP */
363   function save()
364   {
366     /* Take over handling
367      * - Create list of zones managed by source server 
368      * - Copy ldap entries to destination server 
369      * - Remove old zone entries from source
370      */
371     if($this->take_over_id != -1){
372       $del = array();
373       $id = $this->take_over_id;
374       $src = $this->dns_server_list['ENTRIES'][$id]['dn'];
375       $ldap = $this->config->get_ldap_link(); 
376       $ldap->ls("(objectClass=dnsZone)",$src,array('cn'));
377       while($attrs = $ldap->fetch()){
378         $src_zone = $attrs['dn'];
379         $dst_zone = preg_replace("/".normalizePreg($src)."$/",$this->dn,$src_zone);
380         $res = plugin::recursive_move($src_zone, $dst_zone);
382         if($res){
383           $del [] = $src_zone;
384         }
385       }
386       foreach($del as $src_zone){
387         $ldap->rmdir_recursive($src_zone);
388       }
389       return;
390     }
393     $ldap = $this->config->get_ldap_link();
394     $ldap->cd($this->config->current['BASE']);  
395   
396     /* Get differences 
397      */
399     $old_dn =  $this->orig_dn;
400     if($old_dn == "new"){
401       $old_dn = $this->dn;
402     }
403  
404     /* Update dns to current object dn */ 
405     $tmp = getDNSZoneEntriesDiff($this->config,$this->Zones,$old_dn);
406     $tmp2 = array();
407     foreach($tmp as $key1 => $data1){
408       $tmp2[$key1] = array();
409       foreach($data1 as $key2 => $data2){
410         $tmp2[$key1][preg_replace("/".normalizePreg($old_dn)."$/",$this->dn,$key2)] = $data2;
411       }
412     }
413     $tmp = $tmp2;
415     /* Updated zone entries if reverser or forward name has changed  
416      * Must be done before moving entries, else the given dn is invalid
417      */
418     if(isset($tmp['zoneUpdates'])){
419       foreach($tmp['zoneUpdates'] as $dn => $attrs){
420         $ldap->cd($dn);
421         $ldap->modify($attrs);
422         show_ldap_error("Zone:".$ldap->get_error(), _("Updating DNS service failed"));
423       }
424     }
426     /* Delete dns 
427      */
428     foreach($tmp['del'] as $dn => $del){
429       $for = getNameFromMix($del['InitialzoneName']);
430       $rev = FlipIp(getNameFromMix($del['InitialReverseZone'])).".in-addr.arpa";
431       $ldap->cd($dn);
432       $ldap->rmdir_recursive($dn);
433       show_ldap_error($ldap->get_error(), _("Removing DNS entries failed"));
435       /* Handle Post events */
436       if(preg_match("/^zoneName=/",$dn)){
437         $this->handle_post_events("remove",array("dn" => $dn,"zoneName" => $for));
438         $this->handle_post_events("remove",array("dn" => $dn,"zoneName" => $rev));
439       }
440     }
442     /* move follwoing entries
443      */
444     foreach($tmp['move'] as $src => $dst){
445       $this->recursive_move($src,$dst);
446     }
448     /* Add || Update new DNS entries
449      */
450     foreach($tmp['add'] as $dn => $attrs){
451       $ldap->cd($dn);
452       $ldap->cat($dn, array('dn'));
453       if($ldap->count()){
454         $ldap->cd($dn);
455         $ldap->modify ($attrs);
456         show_ldap_error($ldap->get_error(), _("Saving DNS entries failed"));
458         /* Handle Post events */
459         if(preg_match("/^zoneName=/",$dn)){
460           $this->handle_post_events("modify",array("dn" => $dn,"zoneName" => $attrs['zoneName']));
461         }
462       }else{
463         $ldap->cd($dn);
464         $ldap->add($attrs);
465         show_ldap_error($ldap->get_error(), _("Saving DNS entries failed"));
467         /* Handle Post events */
468         if(preg_match("/^zoneName=/",$dn)){
469           $this->handle_post_events("add",array("dn" => $dn,"zoneName" => $attrs['zoneName']));
470         }
471       }
472     }
473   }
475 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
476 ?>