Code

Added a check to force a zoneName reverseName to be given
[gosa.git] / plugins / admin / systems / class_servDNSeditZone.inc
1 <?php
3 class servdnseditZone 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("zoneName","ReverseZone","dNSClass",
13       "sOAprimary","sOAmail","sOAserial","sOArefresh","sOAretry","sOAexpire","sOAttl"); 
14   var $objectclasses  = array("whatever");
16   var $RecordTypes              = array();
18   var $ReverseZone              = "";
19   var $zoneName                 = "";
20   var $dNSClass                 = "IN";
22   var $sOAprimary               = "";
23   var $sOAmail                  = "";
24   var $sOAserial                = "";
25   var $sOArefresh               = "3600";
26   var $sOAretry                 = "1800";
27   var $sOAexpire                = "720000";
28   var $sOAttl                   = "6400";
30   var $Records                  = array();
31   var $mXRecords                = array();
33   var $OldZoneName              = ""; // To detect changes made with this edit
34   var $OldReverseZone           = "";
36   var $InitialReverseZone       = "";
37   var $InitialzoneName          = "";
39   var $dialog                   = false;
41   var $isNew                    = true;
43   var $ZoneObject               = array();
45   function servdnseditZone ($config, $dn= NULL,$attrs = array())
46   {
47     plugin::plugin ($config, $dn);
49     /* All types with required attrs */
50     $this->RecordTypes = getDnsRecordTypes(true); 
52     if(!count($attrs)){
53       $this->OldZoneName        = "";
54       $this->OldReverseZone     = "";
55       $this->isNew              = true;
56       $this->sOAserial          = date("Ymd")."1";
57       
58       $this->InitialzoneName    = "";//$attrs['InitialzoneName'];
59       $this->InitialReverseZone = "";//$attrs['InitialReverseZone'];
60     }else{
61       $this->ZoneObject         = $attrs;
63       $this->OldZoneName        = $attrs['zoneName'];
64       $this->OldReverseZone     = $attrs['ReverseZone'];
66       $this->InitialzoneName    = $attrs['InitialzoneName'];
67       $this->InitialReverseZone = $attrs['InitialReverseZone'];
69       $this->isNew                  = false;
71       foreach($this->attributes as $value){
72         $this->$value = $attrs[$value];
73       }
74       if(isset($attrs['RECORDS'])){
75         $this->Records = $attrs['RECORDS']; 
77         $tmp2 = array();
78         $usedPrio = array();
79         foreach($this->Records as $key => $rec){
80           if($rec['type'] == "mXRecord"){
81             $tmp = split(" ",$rec['value']);
82             $rec['value'] = $tmp[1];
83             $tmp2[$tmp[0]] = $rec;
84             unset($this->Records[$key]);
85           }
86         }
87         if(count($tmp2) != 0){
88           reset($tmp2);
89           ksort($tmp2);
90         }
91         $this->mXRecords = $tmp2;
92       }else{
93         $this->mXRecords  = array();
94         $this->Records    = array();
95       }
97       $str = date("Ymd");
98       if(preg_match("/^".$str."/",$this->sOAserial)){
99         $this->sOAserial = $this->sOAserial + 1;
100       }else{
101         $this->sOAserial = date("Ymd")."01";
102       }
103     }
104   }
106   /* TRansports the geiven Arraykey one position up*/
107   function ArrayUp($atr,$attrs)
108   {
109     $ret = $attrs;
110     $pos = $atr ;
111     $cn = count($attrs);
112     if(!(($pos == -1)||($pos == 1)||($pos >$cn))){
113       $before = array_slice($attrs,0,($pos-2));
114       $mitte  = array_reverse(array_slice($attrs,($pos-2),2));
115       $unten  = array_slice($attrs,$pos);
116       $ret = array();
117       $ret = $this->combineArrays($before,$mitte,$unten);
118     }
119     return($ret);
120   }
123   /* TRansports the geiven Arraykey one position up*/
124   function ArrayDown($atr,$attrs)
125   {
126     $ret = $attrs;
127     $pos = $atr ;
128     $cn = count($attrs);
129     if(!(($pos == -1)||($pos == $cn))){
130       $before = array_slice($attrs,0,($pos-1));
131       $mitte  = array_reverse(array_slice($attrs,($pos-1),2));
132       $unten  = array_slice($attrs,($pos+1));
133       $ret = array();
134       $ret = $this->combineArrays($before,$mitte,$unten);
135     }
136     return($ret);
137   }
139   /* Combine new array */
140   function combineArrays($ar0,$ar1,$ar2)
141   {
142     $ret = array();
143     if(is_array($ar0))
144     foreach($ar0 as $ar => $a){
145         $ret[]=$a;
146     }
147     if(is_array($ar1))
148     foreach($ar1 as $ar => $a){
149         $ret[]=$a;
150     }
151     if(is_array($ar2))
152     foreach($ar2 as $ar => $a){
153         $ret[]=$a;
154     }
155     return($ret);
156   }
157   
158   function getpos($atr,$attrs)
159   {
160     $i = 0;
161     foreach($attrs as $attr => $name)    {
162       $i++;
163       if($attr == $atr){
164         return($i);
165       }
166     }
167     return(-1);
168   }
171   function execute()
172   {
173     /* Call parent execute */
174     plugin::execute();
177     /* Fill templating stuff */
178     $smarty= get_smarty();
179     $display= "";
181     /* Open Zone Entry Edit Dialog
182      */
183     if(!count($this->ZoneObject)){
184       $smarty->assign("AllowZoneEdit" , false);
185     }else{
186       $smarty->assign("AllowZoneEdit" , true);
187       if(isset($_POST['EditZoneEntries'])){
188         $this->dialog= new servDNSeditZoneEntries($this->config,$this->dn,$this->ZoneObject);
189       }
190     }
192     /* Save Zone Entry Edit Dialog
193      */
194     if(isset($_POST['SaveZoneEntryChanges'])){
195       $this->dialog->save_object();
196       if(count($this->dialog->check())){
197         $msgs = $this->dialog->check();
198         foreach($msgs as $msg){
199           print_red($msg);
200         }
201       }else{
202         $this->dialog->save();
203         $this->dialog = false;
204       }
205     }
207     /* Cancel Zone Entrie Edit Dialog
208     */
209     if(isset($_POST['CancelZoneEntryChanges'])){
210       $this->dialog = false;
211     }
213     /* Display any type of open dialogs 
214      */
215     if($this->dialog){
216       $this->dialog->save_object();
217       return($this->dialog->execute());
218     }
220     $once =true;
221     foreach($_POST as $name => $value){
222       if((preg_match("/^MXup_/",$name)) && ($once)){
223         $once = false;
225         $id = preg_replace("/^MXup_/","",$name);
226         $id = preg_replace("/_.*$/","",$id);
227         $id = base64_decode($id);
228     
229         $this->mXRecords = $this->ArrayUp(($id+1),$this->mXRecords);
230       }
231       if((preg_match("/^MXdown_/",$name)) && ($once)){
232         $once = false;
233         
234         $id = preg_replace("/^MXdown_/","",$name);
235         $id = preg_replace("/_.*$/","",$id);
236         $id = base64_decode($id);
237   
238         $this->mXRecords = $this->ArrayDown(($id+1),$this->mXRecords);
239       }
240       if((preg_match("/^MXdel_/",$name)) && ($once)){
241         $once = false;
242         
243         $id = preg_replace("/^MXdel_/","",$name);
244         $id = preg_replace("/_.*$/","",$id);
245         $id = base64_decode($id);
246         
247         unset($this->mXRecords[$id]);
249         $tmp  =array();
250         foreach($this->mXRecords as $entry){
251           $tmp[] = $entry;
252         }
253  
254         $this->mXRecords = $tmp; 
255       }
256     }
258     if((isset($_POST['AddMXRecord'])) && (!empty($_POST['StrMXRecord']))){
259       $this->mXRecords[] = array("type"=>"mXRecord","value"=>trim($_POST['StrMXRecord']));      
260     }
262     /* Handle Post events */
263     $once = true;
264     foreach($_POST as $name => $value){
266       /* Delete record if requested */
267       if((preg_match("/RemoveRecord_/",$name))&&($once)){
268         $once = false;
269         $id= preg_replace("/RemoveRecord_/","",$name);
270         unset($this->Records[$id]);
271       }
272     }
274     /* Add new Zonerecord */
275     if(isset($_POST['AddNewRecord'])){
276       $this->Records[] = array("type"=>"aRecord","value"=>"");
277     }
279     /* Fill in values */
280     foreach($this->attributes as $name){
281       $smarty->assign($name,$this->$name);
282     }
285     $div = new DivSelectBox("MxRecords");
286     $div->setHeight(120);
287     $recs = $this->mXRecords;
289     $oneup    = "<input name='MXup_%s'    type='image' src='images/sort_up.png'    title='"._("Up")."'      class='center'>&nbsp;"; 
290     $onedown  = "<input name='MXdown_%s'  type='image' src='images/sort_down.png'  title='"._("Down")."'    class='center'>&nbsp;"; 
291     $onedel   = "<img src='images/empty.png' width='20' class='center'>
292                  <input name='MXdel_%s'   type='image' src='images/edittrash.png'  title='"._("Delete")."'  class='center'>"; 
294     foreach($recs as $key => $rec){
295       $div ->AddEntry(array(
296             array("string"=>$rec['value']),
297 /*            array("string"=>$key,
298                   "attach"=>"style='width:20px;'"),*/
299             array("string"=>str_replace("%s",base64_encode($key),$oneup.$onedown.$onedel),
300                   "attach"=>"style='width:70px;border-right:0px;'")
301             ));
302     }
304     /* Assign records list */
306       $smarty->assign("NotNew", false);
308     $smarty->assign("Mxrecords",  $div->DrawList());
309     $smarty->assign("records"  ,  $this->generateRecordsList());
311     /* Display tempalte */
312     $display.= $smarty->fetch(get_template_path('servdnseditzone.tpl', TRUE));
313     return($display);
314   }
316   function remove_from_parent()
317   {
318   }
320   /* Save data to object */
321   function save_object()
322   {
323     //plugin::save_object();
324     foreach($this->attributes as $attr){
325       if(isset($_POST[$attr])){
326         $this->$attr = $_POST[$attr];
327       }
328     }
330     foreach($this->Records as $id => $value){  
331       if(isset($_POST['RecordTypeSelectedFor_'.$id])){
332         $this->Records[$id]['type'] = $_POST['RecordTypeSelectedFor_'.$id];
333       }
334       if(isset($_POST['RecordValue_'.$id])){
335         $this->Records[$id]['value'] = $_POST['RecordValue_'.$id];
336       }
337     }
338   }
341   /* Check supplied data */
342   function check()
343   {
344     /* Call common method to give check the hook */
345     $message= plugin::check();
346         
347     /* Check if zoneName is already in use */
348     $usedZones = $this->getUsedZoneNames();
349     if(($this->isNew == true)||($this->zoneName  != $this->InitialzoneName)||($this->ReverseZone != $this->InitialReverseZone)){
350       if((isset($usedZones[$this->zoneName]))&&($this->zoneName  != $this->InitialzoneName)){
351         $message[] =_("This zoneName is already in use");
352       }
353       if((in_array($this->ReverseZone,$usedZones))&&($this->ReverseZone != $this->InitialReverseZone)){
354         $message[] =_("This reverse zone is already in use");
355       }
356     }
358     if(empty($this->zoneName)){
359       $message[] =sprintf(_("Please choose a valid zone name."));
360     }
362     if(empty($this->ReverseZone)){
363       $message[] =sprintf(_("Please choose a valid reverse zone name."));
364     }
366     if(!preg_match("/\.$/",$this->sOAprimary)){
367       $message[] = _("Primary dns server must end with '.' to be a valid entry.");
368     }
370     if(!preg_match("/\.$/",$this->sOAmail)){
371       $message[] = _("Your specified mail address must end with '.' to be a valid record.");
372     }
374     if(preg_match("/@/",$this->sOAmail)){
375       $message[] = _("Your mail address contains '@' replace this with '.' to enable GOsa to create a valid SOA record.");
376     }
378     if(preg_match("/@/",$this->sOAmail)){
379       $message[] = _("Your mail address contains '@' replace this with '.' to enable GOsa to create a valid SOA record.");
380     }
382     if($this->zoneName != strtolower($this->zoneName)){
383       $message[] = _("Only lowercase strings are allowed as zone name.");
384     }
386     if(!is_numeric($this->sOAserial)){
387       $message[] = _("Please specify a numeric value for serial number.");
388     }
390     if(!is_numeric($this->sOArefresh)){
391       $message[] = _("Please specify a numeric value for refresh.");
392     }
394     if(!is_numeric($this->sOAttl)){
395       $message[] = _("Please specify a numeric value for ttl.");
396     }
398     if(!is_numeric($this->sOAexpire)){
399       $message[] = _("Please specify a numeric value for expire.");
400     }
402     if(!is_numeric($this->sOAretry)){
403       $message[] = _("Please specify a numeric value for retry.");
404     }
406     foreach($this->Records as $name => $values){
407       /* only lower-case is allowed in record entries ... */
408       if($values['value'] != strtolower($values['value'])){
409         $message[] = sprintf(_("Only lowercase is allowed, please check your '%ss'."),$values['type']);
410       }
411     }
412     return ($message);
413   }
415   /* This funtion returns all used Zonenames */
416   function getUsedZoneNames()
417   {
418     $ret = array();
419     $ldap = $this->config->get_ldap_link();
420     $ldap->cd($this->config->current['BASE']);
421     $ldap->search("(&(objectClass=dNSZone)(relativeDomainName=@)(zoneName=*))",array("zoneName","tXTRecord"));
422     while($attr = $ldap->fetch()){
423       if(preg_match("/in-addr\.arpa/",$attr['zoneName'][0])){
424         if(isset($attr['tXTRecord'][0])){
425           $zn = preg_replace("/zoneName\=/","",$attr['tXTRecord'][0]);
426           $ret[$zn] =FlipIp(preg_replace("/\.in-addr\.arpa/","",$attr['zoneName'][0]));
427         }
428       }else{
429         $ret[$attr['zoneName'][0]]="";
430       }
431     }
432     return($ret);
433   }
435   /* Save to LDAP */
436   function save()
437   {
438     $ret =array();
439     foreach($this->attributes as $name){
440       $ret[$name] = $this->$name;
441     }
443     /* Create mx records 
444      */
445     foreach($this->mXRecords as $key => $rec){
446       $rec['value']= $key." ".$rec['value'];
447       $this->Records [] = $rec;
448     }
450     $ret['RECORDS'] = $this->Records; 
452     $ret['InitialReverseZone']=  $this->InitialReverseZone;
453     $ret['InitialzoneName']   =  $this->InitialzoneName;
455     return($ret);
456   }
458   
459   /* This function generate a table row for each used record.
460      This table row displays the recordtype in a select box
461       and the specified value for the record, and a remove button.
462      The last element of the table also got an 'add' button.
463    */
464   function generateRecordsList($changeStateForRecords="")
465   {
466     $changeStateForRecords = "";
468     $str = "<table summary=''>";
469     foreach($this->Records as $key => $entry){
471       if($entry['type'] == "mXRecord") continue;
472       
473       $changeStateForRecords.= "changeState('RecordTypeSelectedFor_".$key."');\n";
474       $changeStateForRecords.= "changeState('RecordValue_".$key."');\n";
475       $changeStateForRecords.= "changeState('RemoveRecord_".$key."');\n";
477       $str.=" <tr>".
478         "   <td>".$this->generateRecordListBox($entry['type'],"RecordTypeSelectedFor_".$key)."</td>".
479         "   <td><input type='text' value='".$entry['value']."' name='RecordValue_".$key."' id='RecordValue_".$key."'></td>".
480         "   <td><input type='submit' name='RemoveRecord_".$key."' value='"._("Delete")."' id='RemoveRecord_".$key."'></td>".
481         "</tr>";
482     }
484     $str.= "  <tr>".
485       "    <td colspan=2></td><td>".
486       "      <input type='submit' value='"._("Add")."' name='AddNewRecord'>".
487       "    </td>".
488       "  </tr>".
489       "</table>";
490     return($str);
491   }
493   /* This function generates a select box out of $this->RecordTypes options.
494      The Parameter $selected is used to predefine an attribute.
495      $name is used to specify a post name
496    */
497   function generateRecordListBox($selected,$name)
498   {
499     $str = "<select name='".$name."' id='".$name."'>";
500     foreach($this->RecordTypes as $type => $value){
502       if(preg_match("/^mXRecord$/i",$value)) continue;
504       $use = "";
505       if($type == $selected){
506         $use = " selected ";
507       }
508       $str.="\n <option value='".$type."' ".$use.">".strtoupper(preg_replace("/record/i","",$type))."</option>";
509     }
510     $str.="</select>";
511     return($str);
512   }
515 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
516 ?>