Code

dfcba384343ad56e0b16f92c635ffbb55deff677
[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();
28     /* Remove nSRecord from listed types */
29     if(isset($this->RecordTypes['nSRecord'])){
30       unset($this->RecordTypes['nSRecord']);
31     }
32     /* Remove nSRecord from listed types */
33     if(isset($this->RecordTypes['pTRRecord'])){
34       unset($this->RecordTypes['pTRRecord']);
35     }
37     $this->dn           = "zoneName=".getNameFromMix($zoneObject['InitialzoneName']).",".$dn; 
38     $this->zoneName     = $zoneObject['InitialzoneName'];
39     $this->reverseName  = $zoneObject['InitialReverseZone'];
41     /* Get ldap connection 
42      */
43     $ldap = $this->config->get_ldap_link();
44     $ldap->cd($this->config->current['BASE']);
46     /* Get zone content
47      */
48     $ldap->ls("(&(objectClass=dNSZone)(!(relativeDomainName=@)))",$this->dn,array("relativeDomainName"));
49     
50     while($attrs = $ldap->fetch()){
51       $this->Devices[$attrs['relativeDomainName'][0]] = getDNSHostEntries($config,$attrs['relativeDomainName'][0],true);
52       $this->Devices[$attrs['relativeDomainName'][0]]['OrigCn'] = $attrs['relativeDomainName'][0];
53     }
55     $ldap->cat($this->dn,array("objectClass"));
57     $this->disableDialog = true;
58     if(count($this->Devices)|| $ldap->count()){
59       $this->disableDialog = false;
60     }
61   }
63   function execute()
64   {
65     plugin::execute();
67     /* Fill templating stuff */
68     $smarty= get_smarty();
69     $display= "";
71     $table = "";
72     foreach($this->Devices as $key => $dev){
73       $table .= $this->generateRecordConfigurationRow($key);
74     }
76     $smarty->assign("disableDialog",$this->disableDialog);
77     $smarty->assign("table",$table);;
78     $display.= $smarty->fetch(get_template_path('servDNSeditZoneEntries.tpl', TRUE));
79     return($display);
80   }
83   function save_object()
84   {
85     /* Check posts for operations ...  
86      */
87     $once = true;
88     $ptr_updates = array();
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']  = $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         }
128         /* Check if there is at least one visible record. Else remove complete entry */
129         $visible = false;
130         foreach($this->Devices[$Name]['RECORDS'] as $rec){
131           if(in_array($rec['type'],$this->RecordTypes)){
132             $visible = true;  
133             break;
134           }
135         }
136         if(!$visible && isset($this->Devices[$Name]['RECORDS'])){
137           $this->Devices[$Name]['RECORDS'] = array();
138         }
139       }
140     }
142     /* Possible attributes posted 
143      */
144     foreach($_POST as $name => $value){
146       /* Extract informations out of post name 
147        */
148       $tmp    = preg_replace("/^.*_/","\\1",$name);
149       $tmp2   = split("\|",$tmp);      
150  
151       if(count($tmp2) != 2) continue;
153       $Name     = base64_decode($tmp2[0]);
154       $RecordID = $tmp2[1];
156       /* Check for value change 
157        */          
158       if(preg_match("/ValueSelection_/",$name)){
159         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
160          
161           /* Update value */ 
162           $old = $this->Devices[$Name]['RECORDS'][$RecordID]['value'];
163           $this->Devices[$Name]['RECORDS'][$RecordID]['value'] = $value;
165           /* Handle pTRRecord */
166           if(!isset($ptr_updates[$Name]) && $this->Devices[$Name]['RECORDS'][$RecordID]['type'] == "aRecord"){
167     
168             $found = false;
169             $ip = $value;
170             $match = preg_replace("/^[^\/]*+\//","",$this->reverseName);
171             $ip = preg_replace("/^".normalizePreg($match)."/","",$ip);
172             $ip = preg_replace("/^\./","",$ip);
174             foreach($this->Devices[$Name]['RECORDS'] as $key => $dev){
175               if($dev['type'] == "pTRRecord"){
176                 $ptr_updates[$Name] = $Name;
177                 $this->Devices[$Name]['RECORDS'][$key]['value'] = $ip;
178                 $found = true;
179                 break;
180               }
181             }
182             if(!$found){
183               $dev = array('type'=> 'pTRRecord', 'value' => $ip);
184               $this->Devices[$Name]['RECORDS'][] = $dev;
185             }
186           }
187         }
188       }
190       /* record type changed
191        */        
192       if(preg_match("/^RecordTypeSelection_/",$name)){
193         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
194           $this->Devices[$Name]['RECORDS'][$RecordID]['type'] = $value;
195         }  
196       }   
197     }
198     
199     /* check for renamed entries 
200      */ 
201     foreach($_POST as $name => $value){
203       /* Extract informations out of post name 
204        */
205       $tmp    = preg_replace("/^.*_/","\\1",$name);
206       $tmp2   = split("\|",$tmp);      
207  
208       if(count($tmp2) != 2) continue;
210       $Name     = base64_decode($tmp2[0]);
211       $RecordID = $tmp2[1];
213       /* Host renamed
214        */
215       if(preg_match("/RenameHost_/",$name)){
216         if((isset($this->Devices[$Name])) && ($Name != $value)){
217     
218           if(isset($this->Devices[$value])){
219             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));
220           }else{
221             $this->Devices[$value] = $this->Devices[$Name];
222             unset($this->Devices[$Name]);
223           }
224         }
225       }
226     }
227   }
230   /*  check something 
231    */
232   function check()
233   {
234     /* Call common method to give check the hook */
235     $message= plugin::check();
236     
237     $ldap = $this->config->get_ldap_link();
238     $ldap->cd($this->config->current['BASE']);
240     $names = array();
242     foreach($this->Devices as $DevName => $device){
244       /* skip checking empty attributes */
245       if(count($this->Devices[$DevName]['RECORDS']) == 0){
246         return;
247       }
249       /* Checking entry name
250        */
251       if(!preg_match("/^[a-z0-9_\.-]+$/i", $DevName) || (empty($DevName))){
252         $message[] = sprintf(_("Entry name '%s' contains invalid characters."), $DevName);
253       }      
255       /* Renaming check for existing devices 
256        */
257       if(isset($device['OrigCn'])  && ($DevName != $device['OrigCn'] )){
258         $ldap->cd($this->dn);
259         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
260         if($ldap->count()){
261           $message[] = sprintf(_("Can not rename '%s' to '%s',the destination name already exists."),$device['OrigCn'],$DevName);
262         }
263       }elseif(!isset($device['OrigCn'])){
264         $ldap->cd($this->dn);
265         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
266         if($ldap->count()){
267           $message[] = sprintf(_("Can not create '%s',the destination name already exists."),$DevName);
268         }
269       }
271       /* Check names 
272        */
273       if(!isset($names[$DevName])){
274         $names[$DevName] = "";
275       }else{
276         $message[] = sprintf(_("The name '%s' is used more than once."),$DevName);
277       }
279       /* Names should be written in lowercase
280        */
283       if(strtolower($DevName) != $DevName){
284         $message[] = sprintf(_("The host name '%s' should be written in lowercase."), $DevName);
285       }
287       /* Check records
288        */                 
289       $singleEntries = array("pTRRecord");
291       $tmp  = array();
292       $tmp2 = array();
293       foreach($device['RECORDS'] as $Num => $Rec){
295         /* Check for multiple use of unique record types
296          */
297         if(in_array($Rec['type'],$singleEntries)){
298           if(!isset($tmp[$Rec['type']])){
299             $tmp[$Rec['type']] = "";
300           }else{
301             $message[] = sprintf(_("The record type '%s' is a unique type and can't be defined twice."),$Rec['type']);
302           }
303         }
305         /* Check for empty / duplicate entries in record array 
306          */
307         if(empty($Rec['value'])){
308           $message[] = sprintf(_("There is an empty '%s' for host '%s'."),$Rec['type'],$DevName);
309         }
311         /* Check for duplicate record entries 
312          */
313         if(!isset($tmp[$Rec['type']][$Rec['value']])){
314           $tmp[$Rec['type']][$Rec['value']] = "";
315         }else{
316           $message[] = sprintf(_("There is a duplicate entry in '%s' for '%s'."),$Rec['type'],$DevName); 
317         }
318       }
319     }
320     return ($message);
321   }
323   function save()
324   {
325     if($this->disableDialog) return;
327     $todo = array(); 
330     /* Create todolist
331      */
332     foreach($this->Devices as $name => $dev){
333       if(isset($dev['OrigCn'])){
334         if(count($dev['RECORDS'])){
335           $todo[] = getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
336         }else{
337           $dev['exists'] = false;
338           $todo[] = getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
339         }
340       }else{
341         if(count($dev['RECORDS'])){
342           $todo[] = getDNSHostEntriesDiff($this->config,"",$dev,$name);
343         }else{
344           $dev['exists'] = false;
345           $todo[] = getDNSHostEntriesDiff($this->config,"",$dev,$name);
346         }
347       }
348     }
350     $tmp = array();
351     $tmp['del']   = array();
352     $tmp['add']   = array();
353     $tmp['move']  = array();
354     foreach($todo as $to){
355       foreach($to as $type => $entries){
356         $tmp[$type] = array_merge($tmp[$type],$entries);
357       }
358     }
360     /* Get ldap link
361      */
362     $ldap = $this->config->get_ldap_link();
363     $ldap->cd ($this->config->current['BASE']);
365     /* move follwoing entries
366      */
367     foreach($tmp['move'] as $src => $dst){
368       $this->recursive_move($src,$dst);
369     }
371     /* Delete dns */
372     foreach($tmp['del'] as $dn => $del){
373       $ldap->cd($dn);
374       $ldap->rmdir_recursive($dn);
375     }
377     /* Add || Update new DNS entries
378      */
379     foreach($tmp['add'] as $dn => $attrs){
380       $ldap->cd($dn);
381       $ldap->cat($dn, array('dn'));
382       if(count($ldap->fetch())){
383         $ldap->cd($dn);
384         $ldap->modify ($attrs);
385       }else{
386         $ldap->cd($dn);
387         $ldap->add($attrs);
388       }
389     }
390   }
393   /* Create html table out of given entry 
394    */
395   function generateRecordConfigurationRow($objKey){
397     /* Get some basic informations 
398      */
399     $obj        = $this->Devices[$objKey];
400     $objectName = $objKey;
402     /* Abort if emtpy
403      */
404     if(count($obj['RECORDS']) == 0) return "";
406     /* Set title 
407      */
408     $str= "<br>";
410     $hostNameOnce = true;
412     /* Walk through all defined records 
413      */
414     $str.= "<table cellspacing='0' cellpadding='0'>";
415     foreach($obj['RECORDS'] as $id => $record){
417       /* Skip not selectable entries */
418       if(!isset($this->RecordTypes [$record['type']])) {
419         continue;
420       }
422       /* Create unique post name
423        */
424       $name = base64_encode($objKey)."|".$id;
426       $str .= "<tr><td style='width:170px;'>\n";
428       /* Only first host entry name should be editable
429        */
430       if($hostNameOnce){
431         $hostNameOnce = false;  
432         $str .="<input type='text' name='RenameHost_".$name."' value='".$objectName."'>\n";
433       }
435       /* Create rest. Selectbox, icons ...
436        */
437       $str .="
438         </td>
439         <td style='width:90px;'>
440           ".$this->createRecordTypeSelection($record['type'],$name)."
441         </td>
442         <td>
443           <input type='text'  value='".$record['value']."' name='ValueSelection_".$name."' style='width:250px;'>
444         </td>
445         <td style='width:75px;text-align:right;'>
446           <input type='image' name='AddRecord_".$name."'   src='images/list_new.png' alt='"._("Add")."' title='"._("Add")."'>
447           <input type='image' name='RemoveRecord_".$name."' src='images/edittrash.png'      alt='"._("Remove")."' title='"._("Remove")."'>
448         ";
450 #        if($record['type'] == "aRecord"){
451 #          $str .="<input type='image' name='AddPtr_".$name."' src='images/network.png' 
452 #                    alt='"._("Add PTR")."' title='"._("Add PTR record")."'>";
453 #        }else{
454 #          $str .= "<img src='images/empty.png' alt=''>";
455 #        }
457       $str.=
458         "</td>
459       </tr>";
460     }
461     $str .="</table>";
462     return($str); 
463   }
466   /* Create selectbox with all available option types 
467    */
468   function createRecordTypeSelection($id,$refID){
470     $str = "\n<select name='RecordTypeSelection_".$refID."'>";
471     foreach($this->RecordTypes as $type => $atr) {
472       if($id == $type){
473         $str .="\n<option value='".$type."' selected >".strtoupper(preg_replace("/record/i","",$type))."</option>";
474       }else{
475         $str .="\n<option value='".$type."'>".strtoupper(preg_replace("/record/i","",$type))."</option>";
476       }
477     }
478     $str.= "\n</select>";
479     return($str);
480   }
483   function remove_from_parent()
484   {
485   }
489 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
490 ?>