Code

78b9be741e3819c429ec63295341b81302612168
[gosa.git] / branches / old / gosa-plugins / dns / admin / systems / services / dns / class_servDNSeditZoneEntries.inc
1 <?php
3 class servDNSeditZoneEntries extends plugin
4 {
5   /* attribute list for save action */
6   var $ignore_account     = TRUE;
7   var $attributes         = array();
8   var $objectclasses      = array("whatever");
10   var $Devices            = array();
12   var $zoneName           = "";   // ZoneName of currently edited Zone
13   var $reverseName        = "";   // ReverseZone of the currently edited Zone
15   var $RecordTypes        = array();  // Possible record type.
16   var $acl                = "";
17   var $disableDialog      = false; // Dialog will be disabled, if this zone is new 
20   function servDNSeditZoneEntries (&$config,$dn, &$zoneObject)
21   {
22     plugin::plugin ($config, $dn);
24     /* Initialise class
25      */
26     $this->RecordTypes  = DNS::getDnsRecordTypes();
27     $this->dn           = "zoneName=".$zoneObject['InitialzoneName'].",".$dn; 
28     $this->zoneName     = $zoneObject['InitialzoneName'];
29     $this->reverseName  = $zoneObject['InitialReverseZone'];
31     /* Remove nSRecord from listed types */
32     if(isset($this->RecordTypes['nSRecord'])){
33       unset($this->RecordTypes['nSRecord']);
34     }
35     /* Remove nSRecord from listed types */
36     if(isset($this->RecordTypes['pTRRecord'])){
37       unset($this->RecordTypes['pTRRecord']);
38     }
40     /* Get ldap connection 
41      */
42     $ldap = $this->config->get_ldap_link();
43     $ldap->cd($this->config->current['BASE']);
45     /* Get zone content
46      */
47     $ldap->ls("(&(objectClass=dNSZone)(!(relativeDomainName=@)))",$this->dn,array("relativeDomainName"));
48     
49     while($attrs = $ldap->fetch()){
50       $this->Devices[$attrs['relativeDomainName'][0]] = DNS::getDNSHostEntries($config,$attrs['relativeDomainName'][0],true);
51       $this->Devices[$attrs['relativeDomainName'][0]]['OrigCn'] = $attrs['relativeDomainName'][0];
52     }
54     $ldap->cat($this->dn,array("objectClass"));
56     $this->disableDialog = true;
57     if(count($this->Devices)|| $ldap->count()){
58       $this->disableDialog = false;
59     }
60   }
62   function execute()
63   {
64     plugin::execute();
66     /* Fill templating stuff */
67     $smarty= get_smarty();
68     $display= "";
70     $table = "";
71     foreach($this->Devices as $key => $dev){
72       $table .= $this->generateRecordConfigurationRow($key);
73     }
75     $smarty->assign("acl",$this->acl);
76     $smarty->assign("disableDialog",$this->disableDialog);
77     $smarty->assign("table",$table);;
78     $display.= $smarty->fetch(get_template_path('servDNSeditZoneEntries.tpl', TRUE, dirname(__FILE__)));
79     return($display);
80   }
83   function save_object()
84   {
85     /* Check posts for operations ...  
86      */
87     $once = true;
88     $ptr_updates = array();
89     if(!preg_match("/w/",$this->acl)) return;
91     foreach($_POST as $name => $value){
93       /* Add a new Record in given object  
94        */
95       
96       $tmp    = preg_replace("/^.*_(.*)_.*$/","\\1",$name);
97       $tmp2   = split("\|",$tmp);
99       /* Add new host entry
100        */
101       if((preg_match("/^UserRecord_?/",$name)) && ($once)){
102         $once = false;
103         $entry = DNS::getDNSHostEntries($this->config,"",true);     
104         $entry['exists']    = true;
105         $entry['zoneName']  = strtoupper($this->attrs['cn'][0])."/".$this->zoneName; 
106         $entry['RECORDS'][] = array("type" => "aRecord" , "value"=>"");
107         $this->Devices[_("New entry")] = $entry;
108       }
110       if(count($tmp2) != 2) continue;
112       $Name     = base64_decode($tmp2[0]);
113       $RecordID = $tmp2[1];
115       /* Add new REcord
116        */
117       if((preg_match("/^AddRecord_/",$name)) && ($once)){
118         $once = false;
119         $this->Devices[$Name]['RECORDS'][] = $this->Devices[$Name]['RECORDS'][$RecordID];
120       }
122       /* Remove record from given dn
123        */
124       if((preg_match("/^RemoveRecord_/",$name)) && ($once)){
125         $once   = false;
126         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
127           unset($this->Devices[$Name]['RECORDS'][$RecordID]);
128         }
130         /* Check if there is at least one visible record. Else remove complete entry */
131         $visible = false;
132         foreach($this->Devices[$Name]['RECORDS'] as $rec){
133           if(in_array($rec['type'],$this->RecordTypes)){
134             $visible = true;  
135             break;
136           }
137         }
138         if(!$visible && isset($this->Devices[$Name]['RECORDS'])){
139           $this->Devices[$Name]['RECORDS'] = array();
140         }
141       }
142     }
144     /* Possible attributes posted 
145      */
146     foreach($_POST as $name => $value){
148       /* Extract informations out of post name 
149        */
150       $tmp    = preg_replace("/^.*_/","\\1",$name);
151       $tmp2   = split("\|",$tmp);      
152  
153       if(count($tmp2) != 2) continue;
155       $Name     = base64_decode($tmp2[0]);
156       $RecordID = $tmp2[1];
158       /* Check for value change 
159        */          
160       if(preg_match("/ValueSelection_/",$name)){
161         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
162          
163           /* Update value */ 
164           $old = $this->Devices[$Name]['RECORDS'][$RecordID]['value'];
165           $this->Devices[$Name]['RECORDS'][$RecordID]['value'] = $value;
167           /* Handle pTRRecord */
168           if(!isset($ptr_updates[$Name]) && $this->Devices[$Name]['RECORDS'][$RecordID]['type'] == "aRecord"){
169     
170             $found = false;
171             $ip = $value;
172             $match = preg_replace("/^[^\/]*+\//","",$this->reverseName);
173             $ip = preg_replace("/^".normalizePreg($match)."/","",$ip);
174             $ip = preg_replace("/^\./","",$ip);
176             foreach($this->Devices[$Name]['RECORDS'] as $key => $dev){
177               if($dev['type'] == "pTRRecord"){
178                 $ptr_updates[$Name] = $Name;
179                 $this->Devices[$Name]['RECORDS'][$key]['value'] = $ip;
180                 $found = true;
181                 break;
182               }
183             }
184             if(!$found){
185               $dev = array('type'=> 'pTRRecord', 'value' => $ip);
186               $this->Devices[$Name]['RECORDS'][] = $dev;
187             }
188           }
189         }
190       }
192       /* record type changed
193        */        
194       if(preg_match("/^RecordTypeSelection_/",$name)){
195         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
196           $this->Devices[$Name]['RECORDS'][$RecordID]['type'] = $value;
197         }  
198       }   
199     }
200     
201     /* check for renamed entries 
202      */ 
203     foreach($_POST as $name => $value){
205       /* Extract informations out of post name 
206        */
207       $tmp    = preg_replace("/^.*_/","\\1",$name);
208       $tmp2   = split("\|",$tmp);      
209  
210       if(count($tmp2) != 2) continue;
212       $Name     = base64_decode($tmp2[0]);
213       $RecordID = $tmp2[1];
215       /* Host renamed
216        */
217       if(preg_match("/RenameHost_/",$name)){
218         if((isset($this->Devices[$Name])) && ($Name != $value)){
219     
220           if(isset($this->Devices[$value])){
221             msg_dialog::display(_("Error"), sprintf(_("Cannot rename '%s' to '%s'. Name is already in use!"), $Name, $value), ERROR_DIALOG);
222           }else{
223             $this->Devices[$value] = $this->Devices[$Name];
224             unset($this->Devices[$Name]);
225           }
226         }
227       }
228     }
229   }
232   /*  check something 
233    */
234   function check()
235   {
236     /* Call common method to give check the hook */
237     $message= plugin::check();
238    
239     if(!preg_match("/w/",$this->acl)) return($message);
240  
241     $ldap = $this->config->get_ldap_link();
242     $ldap->cd($this->config->current['BASE']);
244     $names = array();
245     foreach($this->Devices as $DevName => $device){
247       /* Don't need to check empty values ... */
248       if(!count($device['RECORDS'])) continue;
250       /* Checking entry name
251        */
252       if(!preg_match("/^[a-z0-9_\.-]+$/i", $DevName) || (empty($DevName))){
253         $message[] = msgPool::invalid(_("Name"),$DevName,"/[a-z0-9_\.-]/i");
254       }      
256       /* Renaming check for existing devices 
257        */
258       if(isset($device['OrigCn'])  && ($DevName != $device['OrigCn'] )){
259         $ldap->cd($this->config->current['BASE']);
260         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
261         if($ldap->count()){
262           $message[] = sprintf(_("Cannot rename '%s' to '%s'. Entry is already in use."),$device['OrigCn'],$DevName);
263         }
264       }elseif(!isset($device['OrigCn'])){
265         $ldap->cd($this->config->current['BASE']);
266         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
267         if($ldap->count()){
268           $message[] = sprintf(_("Cannot create '%s'. Entry is already in use."),$DevName);
269         }
270       }
272       /* Check names 
273        */
274       if(!isset($names[$DevName])){
275         $names[$DevName] = "";
276       }else{
277         $message[] = sprintf(_("Entry '%s' is used more than once."),$DevName);
278       }
280       /* Names should be written in lowercase
281        */
282 #      if(strtolower($DevName) != $DevName){
283 #        $message[] = sprintf(_("The host name '%s' should be written in lowercase."), $DevName);
284 #      }
286       /* Check records
287        */                 
288       $singleEntries = array("pTRRecord");
290       $tmp  = array();
291       $tmp2 = array();
292       foreach($device['RECORDS'] as $Num => $Rec){
294         /* Check for multiple use of unique record types
295          */
296         if(in_array($Rec['type'],$singleEntries)){
297           if(!isset($tmp[$Rec['type']])){
298             $tmp[$Rec['type']] = "";
299           }else{
300             $message[] = sprintf(_("%s records cannot be used more than once."),$Rec['type']);
301           }
302         }
304         /* Check for empty / duplicate entries in record array 
305          */
306         if(empty($Rec['value'])){
307           $message[] = sprintf(_("Please fix the empty %s record for entry '%s'."),$Rec['type'],$DevName);
308         }
310         /* Check for duplicate record entries 
311          */
312         if(!isset($tmp[$Rec['type']][$Rec['value']])){
313           $tmp[$Rec['type']][$Rec['value']] = "";
314         }else{
315           $message[] = sprintf(_("Please fix the duplicate %s record for entry '%s'."),$Rec['type'],$DevName); 
316         }
317       }
318     }
319     return ($message);
320   }
323   function save()
324   {
325     if($this->disableDialog || !preg_match("/w/",$this->acl)) return;
327     $todo = array(); 
331     /* Create todolist
332      */
333     foreach($this->Devices as $name => $dev){
334       if(isset($dev['OrigCn'])){
335         if(count($dev['RECORDS'])){
336           $todo[] = DNS::getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
337         }else{
338           $dev['exists'] = false;
339           $todo[] = DNS::getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
340         }
341       }else{
342         if(count($dev['RECORDS'])){
343           $todo[] = DNS::getDNSHostEntriesDiff($this->config,"",$dev,$name);
344         }else{
345           $dev['exists'] = false;
346           $todo[] = DNS::getDNSHostEntriesDiff($this->config,"",$dev,$name);
347         }
348       }
349     }
351     $tmp = array();
352     $tmp['del']   = array();
353     $tmp['add']   = array();
354     $tmp['move']  = array();
355     foreach($todo as $to){
356       foreach($to as $type => $entries){
357         $tmp[$type] = array_merge($tmp[$type],$entries);
358       }
359     }
361     /* Get ldap link
362      */
363     $ldap = $this->config->get_ldap_link();
364     $ldap->cd ($this->config->current['BASE']);
366     /* move follwoing entries
367      */
368     foreach($tmp['move'] as $src => $dst){
369       $this->recursive_move($src,$dst);
370     }
372     /* Delete dns */
373     foreach($tmp['del'] as $dn => $del){
374       $ldap->cd($dn);
375       $ldap->rmdir_recursive($dn);
376       if(is_object($this->parent->parent)){
377         $this->parent->parent->handle_post_events("remove",array("dn" => $dn));
378       }
379     }
381     /* Add || Update new DNS entries
382      */
383     foreach($tmp['add'] as $dn => $attrs){
384       $ldap->cd($dn);
385       $ldap->cat($dn, array('dn'));
386       if(count($ldap->fetch())){
387         $ldap->cd($dn);
388         $ldap->modify ($attrs);
389         if(is_object($this->parent->parent)){
390           $this->parent->parent->handle_post_events("modify",array("dn" => $dn));
391         }
392       }else{
393         $ldap->cd($dn);
394         $ldap->add($attrs);
395         if(is_object($this->parent->parent)){
396           $this->parent->parent->handle_post_events("create",array("dn" => $dn));
397         }
398       }
399     }
400   }
403   /* Create html table out of given entry 
404    */
405   function generateRecordConfigurationRow($objKey){
407     /* Get some basic informations 
408      */
409     $obj        = $this->Devices[$objKey];
410     $objectName = $objKey;
412     $dis = "";
413     if(!preg_match("/w/",$this->acl)){
414       $dis = " disabled ";
415     }
417     /* Abort if emtpy
418      */
419     if(count($obj['RECORDS']) == 0) return "";
421     /* Set title 
422      */
423     $str= "<br>";
425     $hostNameOnce = true;
427     /* Walk through all defined records 
428      */
429     $str.= "<table cellspacing='0' cellpadding='0'>";
430     foreach($obj['RECORDS'] as $id => $record){
432       /* Skip not selectable entries */
433       if(!isset($this->RecordTypes [$record['type']])) {
434         continue;
435       }
437       /* Create unique post name
438        */
439       $name = base64_encode($objKey)."|".$id;
441       $str .= "<tr><td style='width:170px;'>\n";
443       /* Only first host entry name should be editable
444        */
445       if($hostNameOnce){
446         $hostNameOnce = false;  
447         $str .="<input $dis type='text' name='RenameHost_".$name."' value='".$objectName."'>\n";
448       }
450       /* Create rest. Selectbox, icons ...
451        */
452       $str .="
453         </td>
454         <td style='width:90px;'>
455           ".$this->createRecordTypeSelection($record['type'],$name)."
456         </td>
457         <td>
458           <input type='text' $dis value='".$record['value']."' name='ValueSelection_".$name."' style='width:250px;'>
459         </td>";
461       if(preg_match("/w/",$this->acl)){
462         $str .= "<td style='width:75px;text-align:right;'>
463           <input type='image' name='AddRecord_".$name."'   
464           src='images/lists/new.png' alt='"._("Add")."' title='"._("Add")."'>
465           <input type='image' name='RemoveRecord_".$name."' 
466           src='images/lists/trash.png'      alt='"._("Remove")."' title='"._("Remove")."'>
467           ";
468       }
470       $str.=
471         "</td>
472       </tr>";
473     }
474     $str .="</table>";
475     return($str); 
476   }
479   /* Create selectbox with all available option types 
480    */
481   function createRecordTypeSelection($id,$refID){
483     if(preg_match("/w/",$this->acl)){
484       $str = "\n<select name='RecordTypeSelection_".$refID."'>";
485       foreach($this->RecordTypes as $type => $atr) {
486         if($id == $type){
487           $str .="\n<option value='".$type."' selected >".strtoupper(preg_replace("/record/i","",$type))."</option>";
488         }else{
489           $str .="\n<option value='".$type."'>".strtoupper(preg_replace("/record/i","",$type))."</option>";
490         }
491       }
492       $str.= "\n</select>";
493     }else{
494       $str = "&nbsp;".strtoupper(preg_replace("/record/i","",$id));
495     }
496     return($str);
497   }
500   function remove_from_parent()
501   {
502   }
506 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
507 ?>