Code

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