Code

b87d22c1e3e7c6e460b599cc4f349c31e357dbc1
[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     }
39     /* Remove nSRecord from listed types */
40     if(isset($this->RecordTypes['pTRRecord'])){
41       unset($this->RecordTypes['pTRRecord']);
42     }
44     /* Get ldap connection 
45      */
46     $ldap = $this->config->get_ldap_link();
47     $ldap->cd($this->config->current['BASE']);
49     /* Get zone content
50      */
51     $ldap->ls("(&(objectClass=dNSZone)(!(relativeDomainName=@)))",$this->dn,array("relativeDomainName"));
52     
53     while($attrs = $ldap->fetch()){
54       $this->Devices[$attrs['relativeDomainName'][0]] = getDNSHostEntries($config,$attrs['relativeDomainName'][0],true);
55       $this->Devices[$attrs['relativeDomainName'][0]]['OrigCn'] = $attrs['relativeDomainName'][0];
56     }
58     $ldap->cat($this->dn,array("objectClass"));
60     $this->disableDialog = true;
61     if(count($this->Devices)|| $ldap->count()){
62       $this->disableDialog = false;
63     }
64   }
66   function execute()
67   {
68     plugin::execute();
70     /* Fill templating stuff */
71     $smarty= get_smarty();
72     $display= "";
74     $table = "";
75     foreach($this->Devices as $key => $dev){
76       $table .= $this->generateRecordConfigurationRow($key);
77     }
78     print_a($this->Devices);
80     $smarty->assign("disableDialog",$this->disableDialog);
81     $smarty->assign("table",$table);;
82     $display.= $smarty->fetch(get_template_path('servDNSeditZoneEntries.tpl', TRUE));
83     return($display);
84   }
87   function save_object()
88   {
89     /* Check posts for operations ...  
90      */
91     $once = true;
92     $ptr_updates = array();
93     foreach($_POST as $name => $value){
95       /* Add a new Record in given object  
96        */
97       
98       $tmp    = preg_replace("/^.*_(.*)_.*$/","\\1",$name);
99       $tmp2   = split("\|",$tmp);
101       /* Add new host entry
102        */
103       if((preg_match("/^UserRecord_?/",$name)) && ($once)){
104         $once = false;
105         $entry = getDNSHostEntries($this->config,"",true);     
106         $entry['exists']    = true;
107         $entry['zoneName']  = strtoupper($this->attrs['cn'][0])."/".$this->zoneName; 
108         $entry['RECORDS'][] = array("type" => "aRecord" , "value"=>"");
109         $this->Devices[_("New entry")] = $entry;
110       }
112       if(count($tmp2) != 2) continue;
114       $Name     = base64_decode($tmp2[0]);
115       $RecordID = $tmp2[1];
117       /* Add new REcord
118        */
119       if((preg_match("/^AddRecord_/",$name)) && ($once)){
120         $once = false;
121         $this->Devices[$Name]['RECORDS'][] = $this->Devices[$Name]['RECORDS'][$RecordID];
122       }
124       /* Remove record from given dn
125        */
126       if((preg_match("/^RemoveRecord_/",$name)) && ($once)){
127         $once   = false;
128         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
129           unset($this->Devices[$Name]['RECORDS'][$RecordID]);
130         }
132         /* Check if there is at least one visible record. Else remove complete entry */
133         $visible = false;
134         foreach($this->Devices[$Name]['RECORDS'] as $rec){
135           if(in_array($rec['type'],$this->RecordTypes)){
136             $visible = true;  
137             break;
138           }
139         }
140         if(!$visible && isset($this->Devices[$Name]['RECORDS'])){
141           $this->Devices[$Name]['RECORDS'] = array();
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          
165           /* Update value */ 
166           $old = $this->Devices[$Name]['RECORDS'][$RecordID]['value'];
167           $this->Devices[$Name]['RECORDS'][$RecordID]['value'] = $value;
169           /* Handle pTRRecord */
170           if(!isset($ptr_updates[$Name]) && $this->Devices[$Name]['RECORDS'][$RecordID]['type'] == "aRecord"){
171     
172             $found = false;
173             $ip = $value;
174             $match = preg_replace("/^[^\/]*+\//","",$this->reverseName);
175             $ip = preg_replace("/^".normalizePreg($match)."/","",$ip);
176             $ip = preg_replace("/^\./","",$ip);
178             foreach($this->Devices[$Name]['RECORDS'] as $key => $dev){
179               if($dev['type'] == "pTRRecord"){
180                 $ptr_updates[$Name] = $Name;
181                 $this->Devices[$Name]['RECORDS'][$key]['value'] = $ip;
182                 $found = true;
183                 break;
184               }
185             }
186             if(!$found){
187               $dev = array('type'=> 'pTRRecord', 'value' => $ip);
188               $this->Devices[$Name]['RECORDS'][] = $dev;
189             }
190           }
191         }
192       }
194       /* record type changed
195        */        
196       if(preg_match("/^RecordTypeSelection_/",$name)){
197         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
198           $this->Devices[$Name]['RECORDS'][$RecordID]['type'] = $value;
199         }  
200       }   
201     }
202     
203     /* check for renamed entries 
204      */ 
205     foreach($_POST as $name => $value){
207       /* Extract informations out of post name 
208        */
209       $tmp    = preg_replace("/^.*_/","\\1",$name);
210       $tmp2   = split("\|",$tmp);      
211  
212       if(count($tmp2) != 2) continue;
214       $Name     = base64_decode($tmp2[0]);
215       $RecordID = $tmp2[1];
217       /* Host renamed
218        */
219       if(preg_match("/RenameHost_/",$name)){
220         if((isset($this->Devices[$Name])) && ($Name != $value)){
221     
222           if(isset($this->Devices[$value])){
223             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));
224           }else{
225             $this->Devices[$value] = $this->Devices[$Name];
226             unset($this->Devices[$Name]);
227           }
228         }
229       }
230     }
231   }
234   /*  check something 
235    */
236   function check()
237   {
238     /* Call common method to give check the hook */
239     $message= plugin::check();
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[] = sprintf(_("Entry name '%s' contains invalid characters."), $DevName);
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(_("Can not rename '%s' to '%s',the destination name already exists."),$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(_("Can not create '%s',the destination name already exists."),$DevName);
269         }
270       }
272       /* Check names 
273        */
274       if(!isset($names[$DevName])){
275         $names[$DevName] = "";
276       }else{
277         $message[] = sprintf(_("The name '%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("cNAMERecord","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(_("The record type '%s' is a unique type and can't be defined twice."),$type);
301           }
302         }
304         /* Check for empty / duplicate entries in record array 
305          */
306         if(empty($Rec['value'])){
307           $message[] = sprintf(_("There is an empty '%s' for host '%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(_("There is a duplicate entry in '%s' for '%s'."),$Rec['type'],$DevName); 
316         }
317       }
318     }
319     return ($message);
320   }
322   function save()
323   {
324     if($this->disableDialog) return;
326     $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       if(is_object($this->parent->parent)){
376         $this->parent->parent->handle_post_events("remove",array("dn" => $dn));
377       }
378     }
380     /* Add || Update new DNS entries
381      */
382     foreach($tmp['add'] as $dn => $attrs){
383       $ldap->cd($dn);
384       $ldap->cat($dn, array('dn'));
385       if(count($ldap->fetch())){
386         $ldap->cd($dn);
387         $ldap->modify ($attrs);
388         if(is_object($this->parent->parent)){
389           $this->parent->parent->handle_post_events("modify",array("dn" => $dn));
390         }
391       }else{
392         $ldap->cd($dn);
393         $ldap->add($attrs);
394         if(is_object($this->parent->parent)){
395           $this->parent->parent->handle_post_events("create",array("dn" => $dn));
396         }
397       }
398     }
399   }
402   /* Create html table out of given entry 
403    */
404   function generateRecordConfigurationRow($objKey){
406     /* Get some basic informations 
407      */
408     $obj        = $this->Devices[$objKey];
409     $objectName = $objKey;
411     /* Abort if emtpy
412      */
413     if(count($obj['RECORDS']) == 0) return "";
415     /* Set title 
416      */
417     $str= "<br>";
419     $hostNameOnce = true;
421     /* Walk through all defined records 
422      */
423     $str.= "<table cellspacing='0' cellpadding='0'>";
424     foreach($obj['RECORDS'] as $id => $record){
426       /* Skip not selectable entries */
427       if(!isset($this->RecordTypes [$record['type']])) {
428         continue;
429       }
431       /* Create unique post name
432        */
433       $name = base64_encode($objKey)."|".$id;
435       $str .= "<tr><td style='width:170px;'>\n";
437       /* Only first host entry name should be editable
438        */
439       if($hostNameOnce){
440         $hostNameOnce = false;  
441         $str .="<input type='text' name='RenameHost_".$name."' value='".$objectName."'>\n";
442       }
444       /* Create rest. Selectbox, icons ...
445        */
446       $str .="
447         </td>
448         <td style='width:90px;'>
449           ".$this->createRecordTypeSelection($record['type'],$name)."
450         </td>
451         <td>
452           <input type='text'  value='".$record['value']."' name='ValueSelection_".$name."' style='width:250px;'>
453         </td>
454         <td style='width:75px;text-align:right;'>
455           <input type='image' name='AddRecord_".$name."'   src='images/list_new.png' alt='"._("Add")."' title='"._("Add")."'>
456           <input type='image' name='RemoveRecord_".$name."' src='images/edittrash.png'      alt='"._("Remove")."' title='"._("Remove")."'>
457         ";
459 #        if($record['type'] == "aRecord"){
460 #          $str .="<input type='image' name='AddPtr_".$name."' src='images/network.png' 
461 #                    alt='"._("Add PTR")."' title='"._("Add PTR record")."'>";
462 #        }else{
463 #          $str .= "<img src='images/empty.png' alt=''>";
464 #        }
466       $str.=
467         "</td>
468       </tr>";
469     }
470     $str .="</table>";
471     return($str); 
472   }
475   /* Create selectbox with all available option types 
476    */
477   function createRecordTypeSelection($id,$refID){
479     $str = "\n<select name='RecordTypeSelection_".$refID."'>";
480     foreach($this->RecordTypes as $type => $atr) {
481       if($id == $type){
482         $str .="\n<option value='".$type."' selected >".strtoupper(preg_replace("/record/i","",$type))."</option>";
483       }else{
484         $str .="\n<option value='".$type."'>".strtoupper(preg_replace("/record/i","",$type))."</option>";
485       }
486     }
487     $str.= "\n</select>";
488     return($str);
489   }
492   function remove_from_parent()
493   {
494   }
498 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
499 ?>