Code

check opened zone for duplicate entries
[gosa.git] / plugins / admin / systems / 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("cn");
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.
17   var $disableDialog      = false; // Dialog will be disabled, if this zone is new 
18   var $cn;
20   function servDNSeditZoneEntries ($config,$dn, $zoneObject)
21   {
22     plugin::plugin ($config, $dn);
24     /* Initialise class
25      */
26     $this->RecordTypes  = getDnsRecordTypes();
27     $this->dn           = "zoneName=".getNameFromMix($zoneObject['InitialzoneName']).",".$dn; 
28     $this->zoneName     = $zoneObject['InitialzoneName'];
29     $this->reverseName  = $zoneObject['InitialReverseZone'];
31     /* Get ldap connection 
32      */
33     $ldap = $this->config->get_ldap_link();
34     $ldap->cd($this->config->current['BASE']);
36     /* Get zone content
37      */
38     $ldap->ls("(&(objectClass=dNSZone)(!(relativeDomainName=@)))",$this->dn,array("relativeDomainName"));
39     
40     while($attrs = $ldap->fetch()){
41       $this->Devices[$attrs['relativeDomainName'][0]] = getDNSHostEntries($config,$attrs['relativeDomainName'][0],true);
42       $this->Devices[$attrs['relativeDomainName'][0]]['OrigCn'] = $attrs['relativeDomainName'][0];
43     }
45     $ldap->cat($this->dn,array("objectClass"));
47     $this->disableDialog = true;
48     if(count($this->Devices)|| $ldap->count()){
49       $this->disableDialog = false;
50     }
51   }
53   function execute()
54   {
55     plugin::execute();
58     /* Check posts for operations ...  
59      */
60     $once = true;
61     foreach($_POST as $name => $value){
63       /* Add a new Record in given object  
64        */
65       
66       $tmp    = preg_replace("/^.*_(.*)_.*$/","\\1",$name);
67       $tmp2   = split("\|",$tmp);
69       /* Add new host entry
70        */
71       if((preg_match("/^UserRecord_?/",$name)) && ($once)){
72         $once = false;
73         $entry = getDNSHostEntries($this->config,"",true);     
74         $entry['exists']    = true;
75         $entry['zoneName']  = $this->zoneName; 
76         $entry['RECORDS'][] = array("type" => "aRecord" , "value"=>"");
77         $this->Devices[_("New entry")] = $entry;
78       }
80       if(count($tmp2) != 2) continue;
82       $Name     = base64_decode($tmp2[0]);
83       $RecordID = $tmp2[1];
85       /* Add new REcord
86        */
87       if((preg_match("/^AddRecord_/",$name)) && ($once)){
88         $once = false;
89         $this->Devices[$Name]['RECORDS'][] = $this->Devices[$Name]['RECORDS'][$RecordID];
90       }
92       /* Remove record from given dn
93        */
94       if((preg_match("/^RemoveRecord_/",$name)) && ($once)){
95         $once   = false;
96         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
97           unset($this->Devices[$Name]['RECORDS'][$RecordID]);
98         }
99       }
101     }
103     /* Fill templating stuff */
104     $smarty= get_smarty();
105     $display= "";
107     $table = "";
108     foreach($this->Devices as $key => $dev){
109       $table .= $this->generateRecordConfigurationRow($key);
110     }
112     $smarty->assign("disableDialog",$this->disableDialog);
113     $smarty->assign("table",$table);;
114     $display.= $smarty->fetch(get_template_path('servDNSeditZoneEntries.tpl', TRUE));
115     return($display);
116   }
119   function save_object()
120   {
121     /* Possible attributes posted 
122      */
123     foreach($_POST as $name => $value){
125       /* Extract informations out of post name 
126        */
127       $tmp    = preg_replace("/^.*_/","\\1",$name);
128       $tmp2   = split("\|",$tmp);      
129  
130       if(count($tmp2) != 2) continue;
132       $Name     = base64_decode($tmp2[0]);
133       $RecordID = $tmp2[1];
135       /* Check for value change 
136        */          
137       if(preg_match("/ValueSelection_/",$name)){
138         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
139           $this->Devices[$Name]['RECORDS'][$RecordID]['value'] = $value;
140         }
141       }
143       /* record type changed
144        */        
145       if(preg_match("/^RecordTypeSelection_/",$name)){
146         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
147           $this->Devices[$Name]['RECORDS'][$RecordID]['type'] = $value;
148         }  
149       }   
150     }
151     
152     /* check for renamed entries 
153      */ 
154     foreach($_POST as $name => $value){
156       /* Extract informations out of post name 
157        */
158       $tmp    = preg_replace("/^.*_/","\\1",$name);
159       $tmp2   = split("\|",$tmp);      
160  
161       if(count($tmp2) != 2) continue;
163       $Name     = base64_decode($tmp2[0]);
164       $RecordID = $tmp2[1];
166       /* Host renamed
167        */
168       if(preg_match("/RenameHost_/",$name)){
169         if((isset($this->Devices[$Name])) && ($Name != $value)){
170     
171           if(isset($this->Devices[$value])){
172             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));
173           }else{
174             $this->Devices[$value] = $this->Devices[$Name];
175             unset($this->Devices[$Name]);
176           }
177         }
178       }
179     }
180   }
183   /*  check something 
184    */
185   function check()
186   {
187     /* Call common method to give check the hook */
188     $message= plugin::check();
189     
190     $ldap = $this->config->get_ldap_link();
191     $ldap->cd($this->config->current['BASE']);
193     $names = array();
195     foreach($this->Devices as $DevName => $device){
197       /* skip checking empty attributes */
198       if(count($this->Devices[$DevName]['RECORDS']) == 0){
199         return;
200       }
202       /* Checking entry name
203        */
204       if((!is_uid($DevName)) | (empty($DevName))){
205         $message[] = sprintf(_("Entry name '%s' contains invalid characters."), $DevName);
206       }      
208       /* Renaming check for existing devices 
209        */
210       if(isset($device['OrigCn'])  && ($DevName != $device['OrigCn'] )){
211         $ldap->cd($this->dn);
212         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
213         if($ldap->count()){
214           $message[] = sprintf(_("Can not rename '%s' to '%s',the destination name already exists."),$device['OrigCn'],$DevName);
215         }
216       }elseif(!isset($device['OrigCn'])){
217         $ldap->cd($this->dn);
218         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
219         if($ldap->count()){
220           $message[] = sprintf(_("Can not create '%s',the destination name already exists."),$DevName);
221         }
222       }
224       /* Check names 
225        */
226       if(!isset($names[$DevName])){
227         $names[$DevName] = "";
228       }else{
229         $message[] = sprintf(_("The name '%s' is used more than once."),$DevName);
230       }
232       /* Names should be written in lowercase
233        */
236       if(strtolower($DevName) != $DevName){
237         $message[] = sprintf(_("The host name '%s' should be written in lowercase."), $DevName);
238       }
240       /* Check records
241        */                 
242       $singleEntries = array("cNAMERecord","pTRRecord");
244       $tmp  = array();
245       $tmp2 = array();
246       foreach($device['RECORDS'] as $Num => $Rec){
248         /* Check for multiple use of unique record types
249          */
250         if(in_array($Rec['type'],$singleEntries)){
251           if(!isset($tmp[$Rec['type']])){
252             $tmp[$Rec['type']] = "";
253           }else{
254             $message[] = sprintf(_("The record type '%s' is a unique type and can't be defined twice."),$type);
255           }
256         }
258         /* Check for empty / duplicate entries in record array 
259          */
260         if(empty($Rec['value'])){
261           $message[] = sprintf(_("There is an empty '%s' for host '%s'."),$Rec['type'],$DevName);
262         }
264         /* Check for duplicate record entries 
265          */
266         if(!isset($tmp[$Rec['type']][$Rec['value']])){
267           $tmp[$Rec['type']][$Rec['value']] = "";
268         }else{
269           $message[] = sprintf(_("There is a duplicate entry in '%s' for '%s'."),$Rec['type'],$DevName); 
270         }
271       }
272     }
273     return ($message);
274   }
276   function save()
277   {
278     if($this->disableDialog) return;
280     $todo = array(); 
283     /* Create todolist
284      */
285     foreach($this->Devices as $name => $dev){
286       if(isset($dev['OrigCn'])){
287         if(count($dev['RECORDS'])){
288           $todo[] = getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
289         }else{
290           $dev['exists'] = false;
291           $todo[] = getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
292         }
293       }else{
294         if(count($dev['RECORDS'])){
295           $todo[] = getDNSHostEntriesDiff($this->config,"",$dev,$name);
296         }else{
297           $dev['exists'] = false;
298           $todo[] = getDNSHostEntriesDiff($this->config,"",$dev,$name);
299         }
300       }
301     }
303     $tmp = array();
304     $tmp['del']   = array();
305     $tmp['add']   = array();
306     $tmp['move']  = array();
307     foreach($todo as $to){
308       foreach($to as $type => $entries){
309         $tmp[$type] = array_merge($tmp[$type],$entries);
310       }
311     }
313     /* Get ldap link
314      */
315     $ldap = $this->config->get_ldap_link();
316     $ldap->cd ($this->config->current['BASE']);
318     /* move follwoing entries
319      */
320     foreach($tmp['move'] as $src => $dst){
321       $this->recursive_move($src,$dst);
322     }
324     /* Delete dns */
325     foreach($tmp['del'] as $dn => $del){
326       $ldap->cd($dn);
327       $ldap->rmdir_recursive($dn);
328     }
330     /* Add || Update new DNS entries
331      */
332     foreach($tmp['add'] as $dn => $attrs){
333       $ldap->cd($dn);
334       $ldap->cat($dn, array('dn'));
335       if(count($ldap->fetch())){
336         $ldap->cd($dn);
337         $ldap->modify ($attrs);
338       }else{
339         $ldap->cd($dn);
340         $ldap->add($attrs);
341       }
342     }
343   }
346   /* Create html table out of given entry 
347    */
348   function generateRecordConfigurationRow($objKey){
350     /* Get some basic informations 
351      */
352     $obj        = $this->Devices[$objKey];
353     $objectName = $objKey;
355     /* Abort if emtpy
356      */
357     if(count($obj['RECORDS']) == 0) return "";
359     /* Set title 
360      */
361     $str= "<br>";
363     $hostNameOnce = true;
365     /* Walk through all defined records 
366      */
367     $str.= "<table cellspacing='0' cellpadding='0'>";
368     foreach($obj['RECORDS'] as $id => $record){
370       /* Create unique post name
371        */
372       $name = base64_encode($objKey)."|".$id;
374       $str .= "<tr><td style='width:170px;'>\n";
376       /* Only first host entry name should be editable
377        */
378       if($hostNameOnce){
379         $hostNameOnce = false;  
380         $str .="<input type='text' name='RenameHost_".$name."' value='".$objectName."'>\n";
381       }
383       /* Create rest. Selectbox, icons ...
384        */
385       $str .="
386         </td>
387         <td style='width:90px;'>
388           ".$this->createRecordTypeSelection($record['type'],$name)."
389         </td>
390         <td>
391           <input type='text'  value='".$record['value']."' name='ValueSelection_".$name."' style='width:250px;'>
392         </td>
393         <td style='width:50px;text-align:right;'>
394           <input type='image' name='AddRecord_".$name."'   src='images/list_new.png' alt='"._("Add")."' title='"._("Add")."'>
395           <input type='image' name='RemoveRecord_".$name."' src='images/edittrash.png'      alt='"._("Remove")."' title='"._("Remove")."'>
396         </td>
397       </tr>";
398     }
399     $str .="</table>";
400     return($str); 
401   }
404   /* Create selectbox with all available option types 
405    */
406   function createRecordTypeSelection($id,$refID){
408     $str = "\n<select name='RecordTypeSelection_".$refID."'>";
409     foreach($this->RecordTypes as $type => $atr) {
410       if($id == $type){
411         $str .="\n<option value='".$type."' selected >".strtoupper(preg_replace("/record/i","",$type))."</option>";
412       }else{
413         $str .="\n<option value='".$type."'>".strtoupper(preg_replace("/record/i","",$type))."</option>";
414       }
415     }
416     $str.= "\n</select>";
417     return($str);
418   }
421   function remove_from_parent()
422   {
423   }
427 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
428 ?>