1 <?php
3 class termDNS 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 $DNSattributes = array("dNSClass","zoneName","dNSTTL");
13 var $attributes= array("ipHostNumber","macAddress");
14 var $objectclasses= array("whatever");
16 var $ipHostNumber =""; // IP address
17 var $macAddress =""; // Mac address
18 var $cn =""; // CN of currently edited device
20 var $Zones = array(); // All Available Zones like array("3.2.1.in-addr.arpa"=>"MyServer.de")
21 var $RecordTypes= array(); // Possible record types
23 var $dNSClass = "IN"; // dNSClass name
24 var $zoneName = ""; // Used ZoneName
25 var $dNSTTL = 7200; // TTL settings for the created entries
27 /* Used records */
28 var $types = array();
29 var $DNSinitially_was_account = false;
31 function termDNS ($config, $dn,$objectClasses)
32 {
33 /* We need to know which objectClasses are used, to store the ip/mac*/
34 $this->objectclasses= $objectClasses;
35 plugin::plugin ($config, $dn);
37 /* All types with required attrs */
38 $this->RecordTypes['aRecord'] = "aRecord"; // ok
39 $this->RecordTypes['mDRecord'] = "mDRecord"; // ok
40 $this->RecordTypes['mXRecord'] = "mXRecord"; // ok
41 $this->RecordTypes['nSRecord'] = "nSRecord"; // ok
42 $this->RecordTypes['pTRRecord'] = "relativeDomainName";// ok
43 $this->RecordTypes['hInfoRecord'] = "hInfoRecord"; // ok
44 $this->RecordTypes['mInfoRecord'] = "mInfoRecord"; // ok
45 $this->RecordTypes['cNAMERecord'] = "relativeDomainName";// ok
46 $this->RecordTypes['tXTRecord'] = "tXTRecord"; // ok
47 $this->RecordTypes['aFSDBRecord'] = "aFSDBRecord"; // ok
48 $this->RecordTypes['SigRecord'] = "SigRecord"; // ok
49 $this->RecordTypes['KeyRecord'] = "KeyRecord"; // ok
50 $this->RecordTypes['aAAARecord'] = "aAAARecord"; // ok
51 $this->RecordTypes['LocRecord'] = "LocRecord"; // ok
52 $this->RecordTypes['nXTRecord'] = "nXTRecord"; // ok
53 $this->RecordTypes['sRVRecord'] = "sRVRecord"; // ok
54 $this->RecordTypes['nAPTRRecord'] = "nAPTRRecord"; // ok
55 $this->RecordTypes['kXRecord'] = "kXRecord"; // ok
56 $this->RecordTypes['certRecord'] = "certRecord"; // ok
57 $this->RecordTypes['a6Record'] = "a6Record"; // ok
58 $this->RecordTypes['dSRecord'] = "dSRecord"; // ok
59 $this->RecordTypes['sSHFPRecord'] = "sSHFPRecord"; // ok
60 $this->RecordTypes['rRSIGRecord'] = "rRSIGRecord"; // ok
61 $this->RecordTypes['nSECRecord'] = "nSECRecord"; // ok
63 /* Get all available zones */
64 $this->cn = $this->attrs['cn'][0];
65 $this->Zones = $this->get_Zones();
66 $types = array();
68 /* Get all records */
69 $ldap = $this->config->get_ldap_link();
70 $ldap->cd($this->dn);
71 $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("*"));
73 while($attrs = $ldap->fetch()){
74 /* If relative domainname == cn
75 * Try to read dnsclass / TTl / zone
76 */
77 if($attrs['relativeDomainName'][0] == $this->cn){
78 /* Get class */
79 if(isset($attrs['dNSClass'][0])){
80 $this->dNSClass = $attrs['dNSClass'][0];
81 }
82 /* Get Zone*/
83 if(isset($attrs['zoneName'][0])){
84 $this->zoneName = $attrs['zoneName'][0];
85 }
86 /* Get ttl */
87 if(isset($attrs['dNSTTL'][0])){
88 $this->dNSTTL = $attrs['dNSTTL'][0];
89 }
90 }
92 /* Create list with all used records */
93 foreach($this->RecordTypes as $name => $value){
95 /* If there is a record attribute */
96 if(isset($attrs[$name])){
98 /* get all entries */
99 for($i = 0 ; $i < $attrs[$value]['count']; $i ++){
100 $types[] =array("type"=>$name,"inittype"=>$name,"value"=>$attrs[$value][$i],"status"=>"edited","dn"=>$attrs['dn']);
101 }
102 }
103 }
104 }
106 /* If there is at least one entry in this -> types, we have DNS enabled */
107 $this->types = $types;
108 if(count($this->types) == 0){
109 $this->DNS_is_account = false;
110 }else{
111 $this->DNS_is_account = true;
112 }
114 /* Store initally account settings */
115 $this->DNSinitially_was_account = $this->DNS_is_account;
116 }
118 function execute()
119 {
120 /* Call parent execute */
121 $smarty= get_smarty();
122 $display= "";
124 /* Add new empty array with status new, to our record list */
125 if(isset($_POST['AddNewRecord'])){
126 $this->types[] =array("type"=>"aRecord","value"=>"","status"=>"new");
127 }
129 /* Handle all posts */
130 $only_once =true;
131 foreach($_POST as $name => $value){
133 /* Check if we have to delete a record entry */
134 if((preg_match("/RemoveRecord_/",$name))&&($only_once)) {
136 /* Avoid performing this once again */
137 $only_once = false;
139 /* Extract id for specified entry */
140 $id = preg_replace("/RemoveRecord_/","",$name);
141 $id = preg_replace("/_.*$/","",$id);
143 /* Delete this record, mark edited entries to be able to delete them */
144 if(isset($this->types[$id])){
145 if($this->types[$id]['status'] == "edited"){
146 $this->types[$id]['status'] = "deleted";
147 }else{
148 unset($this->types[$id]);
149 }
150 }
151 }
152 }
154 /* Assign smarty all non DNs attributes */
155 foreach($this->attributes as $attr){
156 $smarty->assign($attr,$this->$attr);
157 }
159 /* Assign smarty all DNS attributes */
160 foreach($this->DNSattributes as $attr){
161 $smarty->assign($attr,$this->$attr);
162 }
164 /* Assign all needed vars */
165 $smarty->assign("DNSAccount",$this->DNS_is_account);
166 $smarty->assign("Zones",$this->Zones);
167 $smarty->assign("ZoneKeys",($this->Zones));
168 $changeStateForRecords ="";
169 $smarty->assign("records",$this->generateRecordsList(&$changeStateForRecords));
170 $smarty->assign("changeStateForRecords",$changeStateForRecords);
171 $smarty->assign("dNSClasses",array("IN"=>"IN"));
172 $smarty->assign("staticAddress","<font class=\"must\">*</font>");
173 $display.= $smarty->fetch(get_template_path('network.tpl', TRUE));
174 return($display);
175 }
177 function remove_from_parent()
178 {
179 /* This cannot be removed... */
180 }
182 /* Save data to object */
183 function save_object()
184 {
185 /* Save all posted vars */
186 plugin::save_object();
188 /* Ge all non dns attributes (IP/MAC)*/
189 foreach($this->attributes as $attr){
190 if(isset($_POST[$attr])){
191 $this->$attr = $_POST[$attr];
192 }
193 }
195 /* Get dns attributes */
196 if(isset($_POST['network_tpl_posted'])){
198 /* Check for posted record changes */
199 foreach($this->types as $key => $value){
201 /* Check if type has changed */
202 if(isset($_POST['RecordTypeSelectedFor_'.$key])){
203 $this->types[$key]['type'] = $_POST['RecordTypeSelectedFor_'.$key];
204 }
205 /* Check if value has changed */
206 if(isset($_POST['RecordValue_'.$key])){
207 $this->types[$key]['value'] = $_POST['RecordValue_'.$key];
208 }
209 }
211 /* Get all basic DNS attributes (TTL, Clas ..)*/
212 foreach($this->DNSattributes as $attr){
213 if(isset($_POST[$attr])){
214 $this->$attr = $_POST[$attr];
215 }
216 }
218 /* Enable diable DNS */
219 if(isset($_POST['enableDNS'])){
220 $this->DNS_is_account = true;
221 }else{
222 $this->DNS_is_account = false;
223 }
224 }
225 }
228 /* Check supplied data */
229 function check()
230 {
231 $message= array();
232 return ($message);
233 }
236 /* Save to LDAP */
237 function save($dn)
238 {
239 $ldap= $this->config->get_ldap_link();
241 /*******************/
242 /* IP-MAC HANDLING */
243 /*******************/
245 /* $dn was posted as parameter */
246 $this->dn = $dn;
248 /* Save DNS setting & ip/Mac*/
249 plugin::save();
251 /* Write back to ldap */
252 $ldap->cd($this->dn);
253 $ldap->modify($this->attrs);
255 /****************/
256 /* DNS HANDLING */
257 /****************/
259 /* If isn't DNS account but initially was DNS account
260 remove all DNS entries
261 */
262 if(!$this->DNS_is_account){
263 if($this->DNSinitially_was_account){
264 $tmp = array();
265 foreach($this->types as $type){
266 $dn = $type['dn'];
267 if(!isset($tmp[$dn])) {
268 $ldap->cd($dn);
269 $ldap->rmDir($dn);
270 }
271 $tmp[$dn]=$dn;
272 }
273 }
274 }else{
276 /* DNS is enabled, check what we have to do */
277 $delete = array();
279 /* Generate a list of new ldap entries,
280 & $delete contains all dns which should be deleted
281 */
282 $entries = $this->generate_LDAP_entries(&$delete);
284 /* Delete dns */
285 foreach($delete as $dn => $del){
286 $ldap->cd($dn);
287 $ldap->rmDir($dn);
288 }
290 /* Add || Update new DNS entries */
291 foreach($entries as $dn => $attrs){
292 $ldap->cd($dn);
293 $ldap->cat($dn);
295 if(count($ldap->fetch())){
296 $ldap->cd($dn);
297 $ldap->modify($attrs);
298 }else{
299 $ldap->cd($dn);
300 $ldap->add($attrs);
301 }
302 }
303 }
304 if($ldap->get_error() != "Success"){
305 show_ldap_error($ldap->get_error());
306 }
308 }
311 function generateRecordsList($changeStateForRecords)
312 {
313 $changeStateForRecords = "";
315 if(!$this->DNS_is_account) {
316 $str = "<input type='submit' value='"._("Add")."' name='AddNewRecord' id='AddNewRecord' disabled>";
317 return $str;
318 }
320 $str = "<table summary=''>";
321 foreach($this->types as $key => $entry){
322 if($entry['status'] == "deleted") continue;
324 $changeStateForRecords.= "changeState('RecordTypeSelectedFor_".$key."');\n";
325 $changeStateForRecords.= "changeState('RecordValue_".$key."');\n";
326 $changeStateForRecords.= "changeState('RemoveRecord_".$key."');\n";
328 $str.=" <tr>".
329 " <td>".$this->generateRecordListBox($entry['type'],"RecordTypeSelectedFor_".$key)."</td>".
330 " <td><input type='text' value='".$entry['value']."' name='RecordValue_".$key."' id='RecordValue_".$key."'></td>".
331 " <td><input type='submit' name='RemoveRecord_".$key."' value='"._("Delete")."' id='RemoveRecord_".$key."'></td>".
332 "</tr>";
333 }
335 $str.= " <tr>".
336 " <td colspan=2></td><td>".
337 " <input type='submit' value='"._("Add")."' name='AddNewRecord'>".
338 " </td>".
339 " </tr>".
340 "</table>";
341 return($str);
342 }
344 function generateRecordListBox($selected,$name)
345 {
346 $str = "<select name='".$name."' id='".$name."'>";
347 foreach($this->RecordTypes as $type => $value){
348 $use = "";
349 if($type == $selected){
350 $use = " selected ";
351 }
352 $str.="\n <option value='".$type."' ".$use.">".$type."</option>";
353 }
354 $str.="</select>";
355 return($str);
356 }
358 function get_Zones()
359 {
360 $ret = array();
361 $ldap = $this->config->get_ldap_link();
362 $ldap-> cd ($this->config->current['BASE']);
363 $ldap->search("(&(objectClass=dNSZone)(sOARecord=*))",array("*"));
365 while($at = $ldap->fetch()){
366 if(preg_match("/\.in\-addr\.arpa/",$at['zoneName'][0])){
367 $ret[$at['relativeDomainName'][0]]['addr']= $at['zoneName'][0];
368 }else{
369 $ret[$at['relativeDomainName'][0]]['name']= $at['zoneName'][0];
370 }
371 }
373 $tmp =array();
374 foreach($ret as $name => $entry){
375 $tmp[$entry['addr']]=$entry['name'];
376 }
377 $ret = $tmp;
378 return($ret);
379 }
381 function generate_LDAP_entries($delete)
382 {
384 $entries = array();
386 $delete = array();
388 /* Generate Main Entry */
389 $dn = "relativeDomainName=".$this->cn.",".$this->dn;
390 $entries[$dn]['dNSClass'] = $this->dNSClass;
391 $entries[$dn]['zoneName'] = $this->zoneName;
392 $entries[$dn]['dNSTTL'] = $this->dNSTTL;
393 $entries[$dn]['relativeDomainName'] = $this->cn;
395 /* Generate cNAMERecord */
396 $aRecords = array();
397 foreach($this->types as $type){
398 if($type['type'] == "cNAMERecord"){
400 $Cdn = "relativeDomainName=".$type['value'].",".$this->dn;
401 if($type['status']=="deleted"){
402 $delete [$type['dn']] = $Cdn;
403 }else{
404 $entries[$Cdn] = $entries[$dn];
405 $entries[$Cdn]['relativeDomainName'] = $type['value'];
406 $entries[$Cdn]['cNAMERecord'] = $this->cn.".".$this->zoneName;
407 }
408 }
409 }
411 /* Generate tXTRecord */
412 $aRecords = array();
413 foreach($this->types as $type){
414 if(($type['type'] == "tXTRecord")&&($type['status']!="deleted")){
415 $entries[$dn]['tXTRecord'][] = $type['value'];
416 }
417 }
419 /* Generate mDRecord */
420 $aRecords = array();
421 foreach($this->types as $type){
422 if(($type['type'] == "mDRecord")&&($type['status']!="deleted")){
423 $entries[$dn]['mDRecord'][] = $type['value'];
424 }
425 }
427 /* Generate mXRecord */
428 $aRecords = array();
429 foreach($this->types as $type){
430 if(($type['type'] == "mXRecord")&&($type['status']!="deleted")){
431 $entries[$dn]['mXRecord'][] = $type['value'];
432 }
433 }
435 /* Generate hInfoRecord */
436 $aRecords = array();
437 foreach($this->types as $type){
438 if(($type['type'] == "hInfoRecord")&&($type['status']!="deleted")){
439 $entries[$dn]['hInfoRecord'][] = $type['value'];
440 }
441 }
443 /* Generate mInfoRecord */
444 $aRecords = array();
445 foreach($this->types as $type){
446 if(($type['type'] == "mInfoRecord")&&($type['status']!="deleted")){
447 $entries[$dn]['mInfoRecord'][] = $type['value'];
448 }
449 }
451 /* Generate aFSDBRecord */
452 $aRecords = array();
453 foreach($this->types as $type){
454 if(($type['type'] == "aFSDBRecord")&&($type['status']!="deleted")){
455 $entries[$dn]['aFSDBRecord'][] = $type['value'];
456 }
457 }
459 /* Generate some attrs */
460 $arr = array("SigRecord","KeyRecord","aAAARecord","nSRecord",
461 "LocRecord","nXTRecord","sRVRecord","nAPTRRecord","kXRecord","certRecord","a6Record","dSRecord","sSHFPRecord","rRSIGRecord","nSECRecord");
462 $aRecords = array();
463 foreach($arr as $ar){
464 foreach($this->types as $type){
465 if(($type['type'] == $ar)&&($type['status']!="deleted")){
466 $entries[$dn][$ar][] = $type['value'];
467 }
468 }
469 }
472 /* Generate A Records (IP Address relation) */
473 $aRecords = array();
474 foreach($this->types as $type){
475 if(($type['type'] == "aRecord")&&($type['status']!="deleted")){
476 $aRecords[] = $type['value'];
477 }
478 }
479 if(count($aRecords)){
480 $dn = "relativeDomainName=".$this->cn.",".$this->dn;
481 foreach($aRecords as $rec){
482 $entries[$dn]['aRecord'][] = $rec;
483 }
484 }
486 /* Generate pTRRecord Records */
487 foreach($this->types as $type){
488 if($type['type'] == "pTRRecord"){
489 $PTRdn= "relativeDomainName=".$type['value'].",".$this->dn;
490 if($type['status']=="deleted"){
491 $delete [$type['dn']] = $PTRdn;
492 }else{
493 $zones = array_flip($this->Zones);
494 $zone = $zones[$this->zoneName];
495 $entries[$PTRdn]['relativeDomainName'] = $type['value'];
496 $entries[$PTRdn]['pTRRecord'] = $this->cn.".".$this->zoneName;
497 $entries[$PTRdn]['zoneName'] = $zone;
498 }
499 }
500 }
502 foreach($entries as $key => $entry ){
503 $entries[$key]['objectClass']=array("top","dNSZone");
504 $entries[$key] = array_reverse($entries[$key]);
505 }
507 foreach($this->types as $type){
508 if(isset($type['inittype'])){
509 if(!isset($entries[$dn][$type['inittype']])){
510 $entries[$dn][$type['inittype']] = array();
511 }
512 }
513 }
515 return($entries);
516 }
517 }
519 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
520 ?>