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"));
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 */
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);
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 }
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);
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)){
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();
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->config->current['BASE']);
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->config->current['BASE']);
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 }
425 }
427 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
428 ?>