Code

Updated zone editor
[gosa.git] / plugins / admin / systems / class_servDNSeditZoneEntries.inc
1 <?php
3 class servDNSeditZoneEntries extends plugin
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     = TRUE;
12   var $attributes         = array();
13   var $objectclasses      = array("whatever");
15   var $Devices            = array();
17   var $zoneName           = "";   // ZoneName of currently edited Zone
18   var $reverseName        = "";   // ReverseZone of the currently edited Zone
20   var $RecordTypes        = array();  // Possible record type.
22   var $disableDialog      = false; // Dialog will be disabled, if this zone is new 
24   function servDNSeditZoneEntries ($config,$dn, $zoneObject)
25   {
26     plugin::plugin ($config, $dn);
28     /* Initialise class
29      */
30     $this->RecordTypes  = getDnsRecordTypes();
31     $this->dn           = "zoneName=".$zoneObject['InitialzoneName'].",".$dn; 
32     $this->zoneName     = $zoneObject['InitialzoneName'];
33     $this->reverseName  = $zoneObject['InitialReverseZone'];
35     /* Remove nSRecord from listed types */
36     if(isset($this->RecordTypes['nSRecord'])){
37       unset($this->RecordTypes['nSRecord']);
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]] = 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();
68     /* Fill templating stuff */
69     $smarty= get_smarty();
70     $display= "";
72     $table = "";
73     foreach($this->Devices as $key => $dev){
74       $table .= $this->generateRecordConfigurationRow($key);
75     }
77     $smarty->assign("disableDialog",$this->disableDialog);
78     $smarty->assign("table",$table);;
79     $display.= $smarty->fetch(get_template_path('servDNSeditZoneEntries.tpl', TRUE));
80     return($display);
81   }
84   function save_object()
85   {
86     /* Check posts for operations ...  
87      */
88     $once = true;
89     foreach($_POST as $name => $value){
91       /* Add a new Record in given object  
92        */
93       
94       $tmp    = preg_replace("/^.*_(.*)_.*$/","\\1",$name);
95       $tmp2   = split("\|",$tmp);
97       /* Add new host entry
98        */
99       if((preg_match("/^UserRecord_?/",$name)) && ($once)){
100         $once = false;
101         $entry = getDNSHostEntries($this->config,"",true);     
102         $entry['exists']    = true;
103         $entry['zoneName']  = strtoupper($this->attrs['cn'][0])."/".$this->zoneName; 
104         $entry['RECORDS'][] = array("type" => "aRecord" , "value"=>"");
105         $this->Devices[_("New entry")] = $entry;
106       }
108       if(count($tmp2) != 2) continue;
110       $Name     = base64_decode($tmp2[0]);
111       $RecordID = $tmp2[1];
113       /* Add new REcord
114        */
115       if((preg_match("/^AddRecord_/",$name)) && ($once)){
116         $once = false;
117         $this->Devices[$Name]['RECORDS'][] = $this->Devices[$Name]['RECORDS'][$RecordID];
118       }
120       /* Remove record from given dn
121        */
122       if((preg_match("/^RemoveRecord_/",$name)) && ($once)){
123         $once   = false;
124         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
125           unset($this->Devices[$Name]['RECORDS'][$RecordID]);
126         }
127       }
129       /* Add PTR record 
130        */
131       if((preg_match("/^AddPtr_/",$name)) && ($once)){
132         $once   = false;
133         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
134           $tmp = $this->Devices[$Name]['RECORDS'][$RecordID];
135           $ip = $tmp['value'];
136           $match = preg_replace("/^[^\/]*+\//","",$this->reverseName);
137           $ip = preg_replace("/^".normalizePreg($match)."/","",$ip);
138           $ip = preg_replace("/^\./","",$ip);
139           $tmp['type'] = "pTRRecord";
140           $tmp['value'] = $ip;
141           $this->Devices[$Name]['RECORDS'][] = $tmp;
142         }
143       }
144     }
146     /* Possible attributes posted 
147      */
148     foreach($_POST as $name => $value){
150       /* Extract informations out of post name 
151        */
152       $tmp    = preg_replace("/^.*_/","\\1",$name);
153       $tmp2   = split("\|",$tmp);      
154  
155       if(count($tmp2) != 2) continue;
157       $Name     = base64_decode($tmp2[0]);
158       $RecordID = $tmp2[1];
160       /* Check for value change 
161        */          
162       if(preg_match("/ValueSelection_/",$name)){
163         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
164           $this->Devices[$Name]['RECORDS'][$RecordID]['value'] = $value;
165         }
166       }
168       /* record type changed
169        */        
170       if(preg_match("/^RecordTypeSelection_/",$name)){
171         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
172           $this->Devices[$Name]['RECORDS'][$RecordID]['type'] = $value;
173         }  
174       }   
175     }
176     
177     /* check for renamed entries 
178      */ 
179     foreach($_POST as $name => $value){
181       /* Extract informations out of post name 
182        */
183       $tmp    = preg_replace("/^.*_/","\\1",$name);
184       $tmp2   = split("\|",$tmp);      
185  
186       if(count($tmp2) != 2) continue;
188       $Name     = base64_decode($tmp2[0]);
189       $RecordID = $tmp2[1];
191       /* Host renamed
192        */
193       if(preg_match("/RenameHost_/",$name)){
194         if((isset($this->Devices[$Name])) && ($Name != $value)){
195     
196           if(isset($this->Devices[$value])){
197             print_red(sprintf(_("Can't rename '%s' to '%s' there is already an entry with the same name in our zone editing dialog."),$Name,$value));
198           }else{
199             $this->Devices[$value] = $this->Devices[$Name];
200             unset($this->Devices[$Name]);
201           }
202         }
203       }
204     }
205   }
208   /*  check something 
209    */
210   function check()
211   {
212     /* Call common method to give check the hook */
213     $message= plugin::check();
214     
215     $ldap = $this->config->get_ldap_link();
216     $ldap->cd($this->config->current['BASE']);
218     $names = array();
219     foreach($this->Devices as $DevName => $device){
221       /* Don't need to check empty values ... */
222       if(!count($device['RECORDS'])) continue;
224       /* Checking entry name
225        */
226       if(!preg_match("/^[a-z0-9_\.-]+$/i", $DevName) || (empty($DevName))){
227         $message[] = sprintf(_("Entry name '%s' contains invalid characters."), $DevName);
228       }      
230       /* Renaming check for existing devices 
231        */
232       if(isset($device['OrigCn'])  && ($DevName != $device['OrigCn'] )){
233         $ldap->cd($this->config->current['BASE']);
234         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
235         if($ldap->count()){
236           $message[] = sprintf(_("Can not rename '%s' to '%s',the destination name already exists."),$device['OrigCn'],$DevName);
237         }
238       }elseif(!isset($device['OrigCn'])){
239         $ldap->cd($this->config->current['BASE']);
240         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
241         if($ldap->count()){
242           $message[] = sprintf(_("Can not create '%s',the destination name already exists."),$DevName);
243         }
244       }
246       /* Check names 
247        */
248       if(!isset($names[$DevName])){
249         $names[$DevName] = "";
250       }else{
251         $message[] = sprintf(_("The name '%s' is used more than once."),$DevName);
252       }
254       /* Names should be written in lowercase
255        */
256 #      if(strtolower($DevName) != $DevName){
257 #        $message[] = sprintf(_("The host name '%s' should be written in lowercase."), $DevName);
258 #      }
260       /* Check records
261        */                 
262       $singleEntries = array("cNAMERecord","pTRRecord");
264       $tmp  = array();
265       $tmp2 = array();
266       foreach($device['RECORDS'] as $Num => $Rec){
268         /* Check for multiple use of unique record types
269          */
270         if(in_array($Rec['type'],$singleEntries)){
271           if(!isset($tmp[$Rec['type']])){
272             $tmp[$Rec['type']] = "";
273           }else{
274             $message[] = sprintf(_("The record type '%s' is a unique type and can't be defined twice."),$type);
275           }
276         }
278         /* Check for empty / duplicate entries in record array 
279          */
280         if(empty($Rec['value'])){
281           $message[] = sprintf(_("There is an empty '%s' for host '%s'."),$Rec['type'],$DevName);
282         }
284         /* Check for duplicate record entries 
285          */
286         if(!isset($tmp[$Rec['type']][$Rec['value']])){
287           $tmp[$Rec['type']][$Rec['value']] = "";
288         }else{
289           $message[] = sprintf(_("There is a duplicate entry in '%s' for '%s'."),$Rec['type'],$DevName); 
290         }
291       }
292     }
293     return ($message);
294   }
296   function save()
297   {
298     if($this->disableDialog) return;
300     $todo = array(); 
302     /* Create todolist
303      */
304     foreach($this->Devices as $name => $dev){
305       if(isset($dev['OrigCn'])){
306         if(count($dev['RECORDS'])){
307           $todo[] = getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
308         }else{
309           $dev['exists'] = false;
310           $todo[] = getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
311         }
312       }else{
313         if(count($dev['RECORDS'])){
314           $todo[] = getDNSHostEntriesDiff($this->config,"",$dev,$name);
315         }else{
316           $dev['exists'] = false;
317           $todo[] = getDNSHostEntriesDiff($this->config,"",$dev,$name);
318         }
319       }
320     }
322     $tmp = array();
323     $tmp['del']   = array();
324     $tmp['add']   = array();
325     $tmp['move']  = array();
326     foreach($todo as $to){
327       foreach($to as $type => $entries){
328         $tmp[$type] = array_merge($tmp[$type],$entries);
329       }
330     }
332     /* Get ldap link
333      */
334     $ldap = $this->config->get_ldap_link();
335     $ldap->cd ($this->config->current['BASE']);
337     /* move follwoing entries
338      */
339     foreach($tmp['move'] as $src => $dst){
340       $this->recursive_move($src,$dst);
341     }
343     /* Delete dns */
344     foreach($tmp['del'] as $dn => $del){
345       $ldap->cd($dn);
346       $ldap->rmdir_recursive($dn);
347     }
349     /* Add || Update new DNS entries
350      */
351     foreach($tmp['add'] as $dn => $attrs){
352       $ldap->cd($dn);
353       $ldap->cat($dn, array('dn'));
354       if(count($ldap->fetch())){
355         $ldap->cd($dn);
356         $ldap->modify ($attrs);
357       }else{
358         $ldap->cd($dn);
359         $ldap->add($attrs);
360       }
361     }
362   }
365   /* Create html table out of given entry 
366    */
367   function generateRecordConfigurationRow($objKey){
369     /* Get some basic informations 
370      */
371     $obj        = $this->Devices[$objKey];
372     $objectName = $objKey;
374     /* Abort if emtpy
375      */
376     if(count($obj['RECORDS']) == 0) return "";
378     /* Set title 
379      */
380     $str= "<br>";
382     $hostNameOnce = true;
384     /* Walk through all defined records 
385      */
386     $str.= "<table cellspacing='0' cellpadding='0'>";
387     foreach($obj['RECORDS'] as $id => $record){
389       /* Create unique post name
390        */
391       $name = base64_encode($objKey)."|".$id;
393       $str .= "<tr><td style='width:170px;'>\n";
395       /* Only first host entry name should be editable
396        */
397       if($hostNameOnce){
398         $hostNameOnce = false;  
399         $str .="<input type='text' name='RenameHost_".$name."' value='".$objectName."'>\n";
400       }
402       /* Create rest. Selectbox, icons ...
403        */
404       $str .="
405         </td>
406         <td style='width:90px;'>
407           ".$this->createRecordTypeSelection($record['type'],$name)."
408         </td>
409         <td>
410           <input type='text'  value='".$record['value']."' name='ValueSelection_".$name."' style='width:250px;'>
411         </td>
412         <td style='width:75px;text-align:right;'>
413           <input type='image' name='AddRecord_".$name."'   src='images/list_new.png' alt='"._("Add")."' title='"._("Add")."'>
414           <input type='image' name='RemoveRecord_".$name."' src='images/edittrash.png'      alt='"._("Remove")."' title='"._("Remove")."'>
415         ";
417         if($record['type'] == "aRecord"){
418           $str .="<input type='image' name='AddPtr_".$name."' src='images/network.png' 
419                     alt='"._("Add PTR")."' title='"._("Add PTR record")."'>";
420         }else{
421           $str .= "<img src='images/empty.png' alt=''>";
422         }
424       $str.=
425         "</td>
426       </tr>";
427     }
428     $str .="</table>";
429     return($str); 
430   }
433   /* Create selectbox with all available option types 
434    */
435   function createRecordTypeSelection($id,$refID){
437     $str = "\n<select name='RecordTypeSelection_".$refID."'>";
438     foreach($this->RecordTypes as $type => $atr) {
439       if($id == $type){
440         $str .="\n<option value='".$type."' selected >".strtoupper(preg_replace("/record/i","",$type))."</option>";
441       }else{
442         $str .="\n<option value='".$type."'>".strtoupper(preg_replace("/record/i","",$type))."</option>";
443       }
444     }
445     $str.= "\n</select>";
446     return($str);
447   }
450   function remove_from_parent()
451   {
452   }
456 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
457 ?>