763f0e7fa24164cbdfc9691941e073ebd7a4f26c
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"=>"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 var $orig_dn ="";
33 var $IPisMust = false;
34 var $MACisMust= false;
36 function termDNS ($config, $dn,$objectClasses,$IPisMust = false)
37 {
38 /* We need to know which objectClasses are used, to store the ip/mac*/
39 $this->objectclasses= $objectClasses;
40 plugin::plugin ($config, $dn);
42 $this->orig_dn= $dn;
44 $this->IPisMust = $IPisMust;
46 /* All types with required attrs */
47 $this->RecordTypes['aRecord'] = "aRecord"; // ok
48 $this->RecordTypes['mDRecord'] = "mDRecord"; // ok
49 $this->RecordTypes['mXRecord'] = "mXRecord"; // ok
50 $this->RecordTypes['nSRecord'] = "nSRecord"; // ok
51 $this->RecordTypes['pTRRecord'] = "relativeDomainName";// ok
52 $this->RecordTypes['hInfoRecord'] = "hInfoRecord"; // ok
53 $this->RecordTypes['mInfoRecord'] = "mInfoRecord"; // ok
54 $this->RecordTypes['cNAMERecord'] = "relativeDomainName";// ok
55 $this->RecordTypes['tXTRecord'] = "tXTRecord"; // ok
56 $this->RecordTypes['aFSDBRecord'] = "aFSDBRecord"; // ok
57 $this->RecordTypes['SigRecord'] = "SigRecord"; // ok
58 $this->RecordTypes['KeyRecord'] = "KeyRecord"; // ok
59 $this->RecordTypes['aAAARecord'] = "aAAARecord"; // ok
60 $this->RecordTypes['LocRecord'] = "LocRecord"; // ok
61 $this->RecordTypes['nXTRecord'] = "nXTRecord"; // ok
62 $this->RecordTypes['sRVRecord'] = "sRVRecord"; // ok
63 $this->RecordTypes['nAPTRRecord'] = "nAPTRRecord"; // ok
64 $this->RecordTypes['kXRecord'] = "kXRecord"; // ok
65 $this->RecordTypes['certRecord'] = "certRecord"; // ok
66 $this->RecordTypes['a6Record'] = "a6Record"; // ok
67 $this->RecordTypes['dSRecord'] = "dSRecord"; // ok
68 $this->RecordTypes['sSHFPRecord'] = "sSHFPRecord"; // ok
69 $this->RecordTypes['rRSIGRecord'] = "rRSIGRecord"; // ok
70 $this->RecordTypes['nSECRecord'] = "nSECRecord"; // ok
72 echo $this->cn;
73 /* Get all available zones */
74 if(empty($this->cn)&&(isset($this->attrs['cn'][0]))){
75 $this->cn = $this->attrs['cn'][0];
76 }
77 $this->Zones = $this->get_Zones();
78 $types = array();
80 /* Get all records */
81 $ldap = $this->config->get_ldap_link();
82 $ldap->cd($this->dn);
83 $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("*"));
85 while($attrs = $ldap->fetch()){
86 /* If relative domainname == cn
87 * Try to read dnsclass / TTl / zone
88 */
89 if($attrs['relativeDomainName'][0] == $this->cn){
90 /* Get class */
91 if(isset($attrs['dNSClass'][0])){
92 $this->dNSClass = $attrs['dNSClass'][0];
93 }
94 /* Get Zone*/
95 if(isset($attrs['zoneName'][0])){
96 $this->zoneName = $attrs['zoneName'][0];
97 }
98 /* Get ttl */
99 if(isset($attrs['dNSTTL'][0])){
100 $this->dNSTTL = $attrs['dNSTTL'][0];
101 }
102 }
104 /* Create list with all used records */
105 foreach($this->RecordTypes as $name => $value){
107 /* If there is a record attribute */
108 if(isset($attrs[$name])){
111 /* get all entries */
112 for($i = 0 ; $i < $attrs[$value]['count']; $i ++){
113 if(($value == "aRecord")&&($this->ipHostNumber==$attrs[$value][$i])){
114 continue;
115 }
116 $types[] =array("type"=>$name,"inittype"=>$name,"value"=>$attrs[$value][$i],"status"=>"edited","dn"=>$attrs['dn']);
117 }
118 }
119 }
120 }
122 /* If there is at least one entry in this -> types, we have DNS enabled */
123 $this->types = $types;
124 if(count($this->types) == 0){
125 $this->DNS_is_account = false;
126 }else{
127 $this->DNS_is_account = true;
128 }
130 /* Store initally account settings */
131 $this->DNSinitially_was_account = $this->DNS_is_account;
132 }
134 function execute()
135 {
136 /* Call parent execute */
137 $smarty= get_smarty();
138 $display= "";
140 /* Add new empty array with status new, to our record list */
141 if(isset($_POST['AddNewRecord'])){
142 $this->types[] =array("type"=>"aRecord","value"=>"","status"=>"new");
143 }
145 /* Handle all posts */
146 $only_once =true;
147 foreach($_POST as $name => $value){
149 /* Check if we have to delete a record entry */
150 if((preg_match("/RemoveRecord_/",$name))&&($only_once)) {
152 /* Avoid performing this once again */
153 $only_once = false;
155 /* Extract id for specified entry */
156 $id = preg_replace("/RemoveRecord_/","",$name);
157 $id = preg_replace("/_.*$/","",$id);
159 /* Delete this record, mark edited entries to be able to delete them */
160 if(isset($this->types[$id])){
161 if($this->types[$id]['status'] == "edited"){
162 $this->types[$id]['status'] = "deleted";
163 }else{
164 unset($this->types[$id]);
165 }
166 }
167 }
168 }
170 /* Assign smarty all non DNs attributes */
171 foreach($this->attributes as $attr){
172 $smarty->assign($attr,$this->$attr);
173 }
175 /* Assign smarty all DNS attributes */
176 foreach($this->DNSattributes as $attr){
177 $smarty->assign($attr,$this->$attr);
178 }
180 /* Assign all needed vars */
181 $smarty->assign("DNSAccount",$this->DNS_is_account);
182 $smarty->assign("Zones",$this->Zones);
183 $smarty->assign("ZoneKeys",($this->Zones));
184 $smarty->assign("IPisMust",(($this->IPisMust)||($this->DNS_is_account)));
185 $changeStateForRecords ="";
186 $smarty->assign("records",$this->generateRecordsList(&$changeStateForRecords));
187 $smarty->assign("changeStateForRecords",$changeStateForRecords);
188 // $smarty->assign("dNSClasses",array("IN"=>"IN"));
189 $smarty->assign("staticAddress","<font class=\"must\">*</font>");
190 $display.= $smarty->fetch(get_template_path('network.tpl', TRUE));
191 return($display);
192 }
194 function remove_from_parent()
195 {
196 $ldap = $this->config->get_ldap_link();
197 $ldap->cd($this->orig_dn);
198 $ldap->search("(&(objectClass=dNSZone)(zoneName=*)(!(relativeDomainName=@)))",array("relativeDomainName","zoneName"));
199 while($attr = $ldap->fetch()){
200 $ldap->cd($attr['dn']);
201 $ldap->rmDir($attr['dn']);
202 }
203 }
205 /* Save data to object */
206 function save_object()
207 {
208 /* Save all posted vars */
209 plugin::save_object();
211 /* Ge all non dns attributes (IP/MAC)*/
212 foreach($this->attributes as $attr){
213 if(isset($_POST[$attr])){
214 $this->$attr = $_POST[$attr];
215 }
216 }
218 /* Get dns attributes */
219 if(isset($_POST['network_tpl_posted'])){
221 /* Check for posted record changes */
222 foreach($this->types as $key => $value){
224 /* Check if type has changed */
225 if(isset($_POST['RecordTypeSelectedFor_'.$key])){
226 $this->types[$key]['type'] = $_POST['RecordTypeSelectedFor_'.$key];
227 }
228 /* Check if value has changed */
229 if(isset($_POST['RecordValue_'.$key])){
230 $this->types[$key]['value'] = $_POST['RecordValue_'.$key];
231 }
232 }
234 /* Get all basic DNS attributes (TTL, Clas ..)*/
235 foreach($this->DNSattributes as $attr){
236 if(isset($_POST[$attr])){
237 $this->$attr = $_POST[$attr];
238 }
239 }
241 /* Enable diable DNS */
242 if(isset($_POST['enableDNS'])){
243 $this->DNS_is_account = true;
244 }else{
245 $this->DNS_is_account = false;
246 }
247 }
248 }
251 /* Check supplied data */
252 function check()
253 {
254 $message= array();
257 if(($this->IPisMust)||($this->DNS_is_account)){
258 /* Check if ip is empty */
259 if ($this->ipHostNumber == "" && chkacl ($this->acl, "ipHostNumber") == ""){
260 $message[]= _("The required field 'IP-address' is not set.");
261 }
263 /* check if given ip is valid ip*/
264 $num="(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
265 if (!preg_match("/^$num\\.$num\\.$num\\.$num$/", $this->ipHostNumber)){
266 $message[]= _("Wrong IP format in field IP-address.");
267 }
268 }
270 /* Check if mac is empty */
271 if ($this->macAddress == "" && chkacl ($this->acl, "macAddress") == ""){
272 $message[]= _("The required field 'MAC-address' is not set.");
273 }
275 /* Check if given mac is valid mac */
276 $tr = count(split(":",$this->macAddress));
277 if($tr!=6){
278 $message[]=(_("The given macaddress is invalid. There must be 6 1byte segments seperated by ':'."));
279 }
281 /* only perfrom this checks if this is a valid DNS account */
282 if($this->DNS_is_account){
283 foreach($this->types as $name => $values){
285 /* Check if there is an aRecord defined which uses the same IP as used in IPhostAddress */
286 if(($values['type'] == "aRecord")&&($values['value'] == $this->ipHostNumber)&&($values['status']!="deleted")){
287 $message[]=sprintf(_("The device IP '%s' is added as 'A Record', this will be done automatically, please remove the record."),
288 $this->ipHostNumber);
289 }
291 /* only lower-case is allowed in record entries ... */
292 if($values['value'] != strtolower($values['value'])){
293 $message[] = sprintf(_("Only lowercase is allowed, please check your '%ss'."),$values['type']);
294 }
295 }
296 }
298 return ($message);
299 }
302 /* Save to LDAP */
303 function save($dn)
304 {
305 $ldap= $this->config->get_ldap_link();
307 /*******************/
308 /* IP-MAC HANDLING */
309 /*******************/
311 /* $dn was posted as parameter */
312 $this->dn = $dn;
314 /* Save DNS setting & ip/Mac*/
315 plugin::save();
317 /* Write back to ldap */
318 $ldap->cd($this->dn);
319 $this->cleanup();
320 $ldap->modify ($this->attrs);
323 /****************/
324 /* DNS HANDLING */
325 /****************/
327 /* If isn't DNS account but initially was DNS account
328 remove all DNS entries
329 */
330 if(!$this->DNS_is_account){
331 if($this->DNSinitially_was_account){
332 $tmp = array();
333 foreach($this->types as $type){
334 $dn = $type['dn'];
335 if(!isset($tmp[$dn])) {
336 $ldap->cd($dn);
337 $ldap->rmDir($dn);
338 }
339 $tmp[$dn]=$dn;
340 }
341 }
342 }else{
344 /* DNS is enabled, check what we have to do */
345 $delete = array();
347 /* Generate a list of new ldap entries,
348 & $delete contains all dns which should be deleted
349 */
350 $entries = $this->generate_LDAP_entries(&$delete);
352 /* Delete dns */
353 foreach($delete as $dn => $del){
354 $ldap->cd($dn);
355 $ldap->rmDir($dn);
356 }
358 /* Add || Update new DNS entries */
359 foreach($entries as $dn => $attrs){
360 $ldap->cd($dn);
361 $ldap->cat($dn);
363 if(count($ldap->fetch())){
364 $ldap->cd($dn);
365 // $this->cleanup();
366 $ldap->modify ($attrs);
368 }else{
369 $ldap->cd($dn);
370 $ldap->add($attrs);
371 }
372 }
373 }
374 if($ldap->get_error() != "Success"){
375 show_ldap_error($ldap->get_error());
376 }
378 }
380 /* Create html table with all used record types
381 */
382 function generateRecordsList($changeStateForRecords)
383 {
384 $changeStateForRecords = "";
386 if(!$this->DNS_is_account) {
387 $str = "<input type='submit' value='"._("Add")."' name='AddNewRecord' id='AddNewRecord' disabled>";
388 return $str;
389 }
391 $str = "<table summary='' width='100%'>";
392 foreach($this->types as $key => $entry){
393 if($entry['status'] == "deleted") continue;
395 $changeStateForRecords.= "changeState('RecordTypeSelectedFor_".$key."');\n";
396 $changeStateForRecords.= "changeState('RecordValue_".$key."');\n";
397 $changeStateForRecords.= "changeState('RemoveRecord_".$key."');\n";
399 $str.=" <tr>".
400 " <td>".$this->generateRecordListBox($entry['type'],"RecordTypeSelectedFor_".$key)."</td>".
401 " <td><input type='text' value='".$entry['value']."' name='RecordValue_".$key."' id='RecordValue_".$key."'></td>".
402 " <td><input type='submit' name='RemoveRecord_".$key."' value='"._("Delete")."' id='RemoveRecord_".$key."'></td>".
403 "</tr>";
404 }
406 $str.= " <tr>".
407 " <td colspan=2 width='50%'></td><td>".
408 " <input type='submit' value='"._("Add")."' name='AddNewRecord'>".
409 " </td>".
410 " </tr>".
411 "</table>";
412 return($str);
413 }
415 /* Create a html select box which allows us to select different types of records */
416 function generateRecordListBox($selected,$name)
417 {
418 $str = "<select name='".$name."' id='".$name."'>";
419 foreach($this->RecordTypes as $type => $value){
420 $use = "";
421 if($type == $selected){
422 $use = " selected ";
423 }
424 $str.="\n <option value='".$type."' ".$use.">".$type."</option>";
425 }
426 $str.="</select>";
427 return($str);
428 }
430 /* return all Zone names */
431 function get_Zones()
432 {
433 $ret = array();
434 $ldap = $this->config->get_ldap_link();
435 $ldap-> cd ($this->config->current['BASE']);
436 $ldap->search("(&(objectClass=dNSZone)(sOARecord=*))",array("*"));
438 while($at = $ldap->fetch()){
439 if(preg_match("/\.in\-addr\.arpa/",$at['zoneName'][0])){
440 $ret[$at['relativeDomainName'][0]]['addr']= $at['zoneName'][0];
441 }else{
442 $ret[$at['relativeDomainName'][0]]['name']= $at['zoneName'][0];
443 }
444 }
446 $tmp =array();
447 foreach($ret as $name => $entry){
448 if((isset($entry['addr']))&&(isset($entry['name']))){
449 $tmp[$entry['addr']]=$entry['name'];
450 }
451 }
452 $ret = $tmp;
453 return($ret);
454 }
456 /* this is used to generate ldap friendly output of our
457 dns configuration
458 */
459 function generate_LDAP_entries($delete)
460 {
461 $entries = array();
462 $delete = array();
464 /* Generate Main Entry */
465 $dn = "relativeDomainName=".$this->cn.",".$this->dn;
466 $entries[$dn]['dNSClass'] = $this->dNSClass;
467 $entries[$dn]['zoneName'] = $this->zoneName;
468 $entries[$dn]['dNSTTL'] = $this->dNSTTL;
469 $entries[$dn]['relativeDomainName'] = $this->cn;
471 /* Generate cNAMERecord */
472 $aRecords = array();
473 foreach($this->types as $type){
474 if($type['type'] == "cNAMERecord"){
476 $Cdn = "relativeDomainName=".$type['value'].",".$this->dn;
477 if($type['status']=="deleted"){
478 $delete [$type['dn']] = $Cdn;
479 }else{
480 $entries[$Cdn] = $entries[$dn];
481 $entries[$Cdn]['relativeDomainName'] = $type['value'];
482 $entries[$Cdn]['cNAMERecord'] = $this->cn.".".$this->zoneName;
483 }
484 }
485 }
487 /* Generate tXTRecord */
488 $aRecords = array();
489 foreach($this->types as $type){
490 if(($type['type'] == "tXTRecord")&&($type['status']!="deleted")){
491 $entries[$dn]['tXTRecord'][] = $type['value'];
492 }
493 }
495 /* Generate mDRecord */
496 $aRecords = array();
497 foreach($this->types as $type){
498 if(($type['type'] == "mDRecord")&&($type['status']!="deleted")){
499 $entries[$dn]['mDRecord'][] = $type['value'];
500 }
501 }
503 /* Generate mXRecord */
504 $aRecords = array();
505 foreach($this->types as $type){
506 if(($type['type'] == "mXRecord")&&($type['status']!="deleted")){
507 $entries[$dn]['mXRecord'][] = $type['value'];
508 }
509 }
511 /* Generate hInfoRecord */
512 $aRecords = array();
513 foreach($this->types as $type){
514 if(($type['type'] == "hInfoRecord")&&($type['status']!="deleted")){
515 $entries[$dn]['hInfoRecord'][] = $type['value'];
516 }
517 }
519 /* Generate mInfoRecord */
520 $aRecords = array();
521 foreach($this->types as $type){
522 if(($type['type'] == "mInfoRecord")&&($type['status']!="deleted")){
523 $entries[$dn]['mInfoRecord'][] = $type['value'];
524 }
525 }
527 /* Generate aFSDBRecord */
528 $aRecords = array();
529 foreach($this->types as $type){
530 if(($type['type'] == "aFSDBRecord")&&($type['status']!="deleted")){
531 $entries[$dn]['aFSDBRecord'][] = $type['value'];
532 }
533 }
535 /* Generate some attrs */
536 $arr = array("SigRecord","KeyRecord","aAAARecord","nSRecord",
537 "LocRecord","nXTRecord","sRVRecord","nAPTRRecord","kXRecord","certRecord","a6Record","dSRecord","sSHFPRecord","rRSIGRecord","nSECRecord");
538 $aRecords = array();
539 foreach($arr as $ar){
540 foreach($this->types as $type){
541 if(($type['type'] == $ar)&&($type['status']!="deleted")){
542 $entries[$dn][$ar][] = $type['value'];
543 }
544 }
545 }
548 /* Generate A Records (IP Address relation) */
549 $aRecords = array();
550 foreach($this->types as $type){
551 if(($type['type'] == "aRecord")&&($type['status']!="deleted")){
552 $aRecords[] = $type['value'];
553 }
554 }
555 if(count($aRecords)){
557 /* Add ipHostNumber as default aRecord */
558 $aRecords[] = $this->ipHostNumber;
560 $dn = "relativeDomainName=".$this->cn.",".$this->dn;
561 foreach($aRecords as $rec){
562 $entries[$dn]['aRecord'][] = $rec;
563 }
564 }
566 /* Generate pTRRecord Records */
567 foreach($this->types as $type){
568 if($type['type'] == "pTRRecord"){
569 $PTRdn= "relativeDomainName=".$type['value'].",".$this->dn;
570 if($type['status']=="deleted"){
571 $delete [$type['dn']] = $PTRdn;
572 }else{
573 $zones = array_flip($this->Zones);
574 $zone = $zones[$this->zoneName];
575 $entries[$PTRdn]['relativeDomainName'] = $type['value'];
576 $entries[$PTRdn]['pTRRecord'] = $this->cn.".".$this->zoneName;
577 $entries[$PTRdn]['zoneName'] = $zone;
578 }
579 }
580 }
582 /* add ObjectClasses */
583 foreach($entries as $key => $entry ){
584 $entries[$key]['objectClass']=array("top","dNSZone");
585 $entries[$key] = array_reverse($entries[$key]);
586 }
588 /* Check if record type has changed, and if we need to delete this record attribute from ldap entry */
589 foreach($this->types as $type){
590 if(isset($type['inittype'])){
591 if(!isset($entries[$dn][$type['inittype']])){
592 $entries[$dn][$type['inittype']] = array();
593 }
594 }
595 }
597 return($entries);
598 }
599 }
601 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
602 ?>