Source for file GuiUpdateDns.php

Documentation is available at GuiUpdateDns.php

  1. <?php
  2. /**
  3.  * GuiUpdateDns.php
  4.  *
  5.  * Long description for file:
  6.  * Using ip.address and systems.name from the FreeNAC 'ip' DB, generate
  7.  * a list of dynamic DNS updates.
  8.  * The DNS update commands are written to $tmp_file, once the file has been
  9.  * written, the dns_update flag is reset for each field.
  10.  * TODO : aliases/CNAMES, then HINFO LOC SVR (separate table)
  11.  *
  12.  * Inputs: ip.address, systems.name
  13.  *   $conf->: ddns_server,  dns_domain, ddns_ttl
  14.  * Options:
  15.  *   $ddns_level: 0 = all hosts, 1 = hosts with dns_update bit 1 is set
  16.  *  Status field
  17.  *    0 = free
  18.  *    1 = used: updated by Dyn dns [THIS is the only value we check]
  19.  *    -1 =  special address (network address, broadcast)
  20.  *    2 =  fixed
  21.  *    3 = reserved
  22.  *
  23.  * PHP version 5
  24.  *
  25.  * LICENSE: This program is free software; you can redistribute it and/or
  26.  * modify it under the terms of the GNU General Public License as published
  27.  * by the Free Software Foundation.
  28.  *
  29.  * @package            FreeNAC
  30.  * @author            Sean Boran/Thomas Dagonnier (FreeNAC Core Team)
  31.  * @copyright            2008 FreeNAC
  32.  * @license            http://www.gnu.org/copyleft/gpl.html   GNU Public License Version 2
  33.  * @version            SVN: $Id$
  34.  * @link            http://www.freenac.net
  35.  *
  36.  */
  37.  
  38. class GuiUpdateDns extends WebCommon
  39. {
  40.   private $id$action;      // See also WebCommon and Common
  41.  
  42.   function __construct($title="Updating DNS"$debug_level=1)
  43.   {
  44.     parent::__construct(false);     // See also WebCommon and Common
  45.     $this->logger->setDebugLevel($debug_level);
  46.     $this->debug("__construct debug=$debug_level"2);
  47.  
  48.     $this->module='GuiUpdateDns';              // identify module, in Webcommon
  49.     $this->table='ip';               // identify SQL table, in Webcommon
  50.     echo $this->print_header1();
  51.     echo "<hr><p class='text18'>$title</p>";
  52.   }
  53.  
  54.   protected function sanitize_name($name{
  55.     // make sure there are only DNS-ok characters
  56.     // currently ugly/basic - need to be improved
  57.     $name ltrim(rtrim($name,' '),' ');
  58.     $name str_replace(' ''-'$name);
  59.     if ($position=strpos($name".")) // strip away a domain name, if there is one
  60.       $name substr($name0$position);
  61.     }
  62.     return($name);
  63.   }
  64.  
  65.  
  66.   public function ViewDNS()
  67.   {
  68.     $cmd="nslookup -type=axfr {$this->conf->dns_domain} {$this->conf->ddns_server}";
  69.     $res=syscall($cmd);
  70.     echo "<br>$cmd<pre class='logtext'>$res</pre>";
  71.     echo "<hr><p>Go back to the <a href='{$this->calling_href}'>previous page</a></p>";
  72.   }
  73.  
  74.  
  75.   public function UpdateDnsAll()
  76.   {
  77.     $this->UpdateDns(TRUE);
  78.   }
  79.  
  80.  
  81.   protected function  call_process($cmd, $input)
  82.   {
  83.       // send the file to nsupdate
  84. /*    $fp = popen($nsupdate,'w');
  85.       if( ! $fp ){
  86.         print "<h3>Error while sending to: $nsupdate</h3>\n";
  87.         return false;
  88.       }
  89.       fwrite($fp,$dns_update);
  90.       pclose($fp);
  91. */
  92.       $desarray( 0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
  93.                    1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
  94.                    2 => array("pipe", "w")   // stderr
  95.       );
  96.       $fp = proc_open($cmd, $des, $pipes);
  97.       if (is_resource($fp) ) {
  98.         fwrite($pipes[0], $input);    // send dns updates
  99.         fclose($pipes[0]);
  100.  
  101.         $retstdoutstream_get_contents($pipes[1]);  // read the answer
  102.         #while (!feof($pipes[1]))   // read the answer
  103.         #  $ret.=fgets($pipes[1], 1024);
  104.         $retstderrstream_get_contents($pipes[2]);  // read the answer
  105.         #while (!feof($pipes[2]))   // read the answer
  106.         #  $ret.=fgets($pipes[2], 1024);
  107.         fclose($pipes[1]); fclose($pipes[2]);
  108.         $ret2=proc_close($fp);
  109.       }
  110.       #echo "<br>The stdout answer is:<pre class='logtext'>$retstdout</pre>";
  111.       #echo "<br>Process answer =$ret2 (0 is success)";
  112.       $this->debug("The stdout answer is: $retstdout", 3);
  113.       $this->debug("The process answer is: $ret2", 3);
  114.       echo "<br>The DNS server replied (look for 'status: NOERROR'):<pre class='logtext'>$retstderr</pre>";
  115.   }
  116.  
  117.   public function UpdateDns($ddns_update_all=FALSE)
  118.   {
  119.     // ddns_update_all: True= all hosts, false= hosts with lastchange>lastupdate
  120.     // settings TBD: query from $conf later
  121.     #$nsupdate="nsupdate -v -t 10 ";    // -d = debug, 10 sec timeout, use tcp
  122.     $nsupdate="nsupdate -d -v -t 10 ";    // -d = debug, 10 sec timeout, use tcp
  123.     if ($_SESSION['nac_rights'] < 2)    // TBD: change to 99 for production
  124.       throw new InsufficientRightsException('UpdateDns() ' .$_SESSION['nac_rights']);
  125.     $conn=$this->getConnection();     //  make sure we have a DB connection
  126.  
  127.     /** A Records **/
  128.     $query "SELECT ip.id as id, INET_NTOA(ip.address) as ip, systems.name as name FROM ip LEFT JOIN systems ON ip.system = systems.id WHERE ip.status=1 AND ip.system != 0 ";
  129.       if ($ddns_update_all===FALSE{
  130.            $query.=" AND (ip.lastupdate < ip.lastchange)";
  131.       }
  132.       $this->debug($query3);
  133.       $res $conn->query($query);
  134.       if ($res === FALSE)
  135.         throw new DatabaseErrorException($conn->error);
  136.  
  137.  
  138.     $dns_ina='';      // collect the update commands
  139.     $host_count=0;
  140.     while (($host $res->fetch_assoc()) !== NULL{
  141.  
  142.          if (($host['name'] == 'unknown') || ($host['ip'] == '') || ($host['name'] == '')) { 
  143.             echo "Skipping invalid host={$host['name']}, ip={$host['ip']} <br>";
  144.             next;
  145.          }
  146.          $host_count++;
  147.          echo "<p class='text15'>Analysing host={$host['name']}, ip={$host['ip']}";
  148.  
  149.      $dns_name = $this->sanitize_name($host['name']."." .$this->conf->dns_domain .".";
  150.         #$dns_ip = $host['ip'];
  151.             $dns_ina .= 'update delete '.$dns_name."\t A\r\n";
  152.         $dns_ina .= 'update add ' .$dns_name ."\t" .$this->conf->ddns_ttl 
  153.               .' A ' .$host['ip'."\r\n";
  154.  
  155.          $dns_ptr='';      // reverse PTR record for this IP
  156.          $listexplode("."$host['ip']);    // CReate reverse PTR records
  157.          #$dns_ptr.= "zone " .$list[2] ."." .$list[1] ."." .$list[0] .".in-addr.arpa \r\n";
  158.          $ptr$list[2."." .$list[1."." .$list[0.".in-addr.arpa";
  159.          $dns_ptr.= "server {$this->conf->ddns_server}\r\n";
  160.          $dns_ptr.= "zone $ptr\r\n";
  161.          $dns_ptr.= "update delete {$list[3]}.$ptr PTR \r\n";
  162.          $dns_ptr.= "update add {$list[3]}.$ptr {$this->conf->ddns_ttl} PTR $dns_name\r\n";
  163.          $dns_ptr.= "answer\r\nsend \r\n";
  164.          echo "<br class='text15'>Create reverse PTR records:<pre class='logtext'>$dns_ptr</pre>";
  165.          $this->call_process($nsupdate$dns_ptr);
  166.  
  167.          // clear update flag: TBD: we don't really know yet if all updates will work..
  168.          $upd_clear "UPDATE ip SET lastupdate=NOW() WHERE id=".$host['id'];
  169.             $this->debug($query3);
  170.             $res2 $conn->query($upd_clear);
  171.             if ($res2 === FALSE)
  172.               throw new DatabaseErrorException($conn->error);
  173.     };
  174.  
  175.     if ($host_count==0) {
  176.       echo "<br>There are no new changes, no DNS updates pending.";
  177.       
  178.     } else {
  179.       $dns_update = "server {$this->conf->ddns_server}\r\n";
  180.       //$dns_update .= "zone $dns_domain\r\n"; Zone must be in name
  181.       $dns_update .= $dns_ina;
  182.         // request verbose answer, i.e. NOERROR below:
  183.         # Outgoing update query:
  184.         # ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id:  29828
  185.         # ;; flags: qr ra ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
  186.         $dns_update .= "answer\n";    
  187.       $dns_update .= "send\n";
  188.       echo "<hr><p class='text15'>Updating the forward records, send request [$nsupdate]:<pre class='logtext'>$dns_update</pre>";
  189.  
  190.  
  191.       $this->call_process($nsupdate$dns_update);
  192.     }
  193.  
  194.     echo "<hr><p>Go back to the <a href='{$this->calling_href}'>previous page</a></p>";
  195.   }
  196.  
  197. }   // class
  198.  
  199. /////////// main() should never get here .. ///////////////////////////////////////
  200. if (isset($_POST['action']) && $_POST['action']=='Edit') {
  201.   $logger=Logger::getInstance();
  202.   $logger->debug("Edit__:action:"$_POST['action']1);
  203. }
  204.  
  205. if ( isset($_POST['submit']) ) {             // form submit, check fields
  206. ## Initialise (standard header for all modules)
  207.   dir(dirname(__FILE__)); set_include_path("./:../");
  208.   require_once('webfuncs.inc');
  209.   $logger=Logger::getInstance();
  210.   $logger->setDebugLevel(1);
  211.   $logger->debug("Edit__ main -submit");
  212.   #echo handle_submit();
  213.  
  214. } else {
  215.   # Do nothing, we've been included.
  216. }
  217.  
  218.  

Documentation generated on Mon, 17 Nov 2008 01:10:37 +0100 by phpDocumentor 1.4.0