From 40e6570114722f711735ff59f8d726f6e3e05624 Mon Sep 17 00:00:00 2001
From: wyrie <wyrie@ispconfig3>
Date: Mon, 18 Jan 2010 04:00:21 -0500
Subject: [PATCH] Bind DLZ plugin
---
server/plugins-available/bind_dlz_plugin.inc.php | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 347 insertions(+), 0 deletions(-)
diff --git a/server/plugins-available/bind_dlz_plugin.inc.php b/server/plugins-available/bind_dlz_plugin.inc.php
new file mode 100644
index 0000000..e1af955
--- /dev/null
+++ b/server/plugins-available/bind_dlz_plugin.inc.php
@@ -0,0 +1,347 @@
+<?php
+
+/*
+Copyright (c) 2009, Falko Timme, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+TABLE STRUCTURE of the "named" database:
+
+CREATE TABLE IF NOT EXISTS `records` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `zone` varchar(255) NOT NULL,
+ `ttl` int(11) NOT NULL default '86400',
+ `type` varchar(255) NOT NULL,
+ `host` varchar(255) NOT NULL default '@',
+ `mx_priority` int(11) default NULL,
+ `data` text,
+ `primary_ns` varchar(255) default NULL,
+ `resp_contact` varchar(255) default NULL,
+ `serial` bigint(20) default NULL,
+ `refresh` int(11) default NULL,
+ `retry` int(11) default NULL,
+ `expire` int(11) default NULL,
+ `minimum` int(11) default NULL,
+ `ispconfig_id` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `type` (`type`),
+ KEY `host` (`host`),
+ KEY `zone` (`zone`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE IF NOT EXISTS `xfr` (
+ `id` int(11) NOT NULL auto_increment,
+ `zone` varchar(255) NOT NULL,
+ `client` varchar(255) NOT NULL,
+ `ispconfig_id` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `zone` (`zone`),
+ KEY `client` (`client`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+*/
+
+class bind_dlz_plugin {
+
+ var $plugin_name = 'bind_dlz_plugin';
+ var $class_name = 'bind_dlz_plugin';
+
+ //* This function is called during ispconfig installation to determine
+ // if a symlink shall be created for this plugin.
+ function onInstall()
+ {
+ global $conf;
+
+ if(isset($conf['bind']['installed']) && $conf['bind']['installed'] == true) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /*
+ This function is called when the plugin is loaded
+ */
+
+ function onLoad()
+ {
+ global $app;
+
+ /*
+ Register for the events
+ */
+
+ //* SOA
+ $app->plugins->registerEvent('dns_soa_insert',$this->plugin_name,'soa_insert');
+ $app->plugins->registerEvent('dns_soa_update',$this->plugin_name,'soa_update');
+ $app->plugins->registerEvent('dns_soa_delete',$this->plugin_name,'soa_delete');
+
+ //* RR
+ $app->plugins->registerEvent('dns_rr_insert',$this->plugin_name,'rr_insert');
+ $app->plugins->registerEvent('dns_rr_update',$this->plugin_name,'rr_update');
+ $app->plugins->registerEvent('dns_rr_delete',$this->plugin_name,'rr_delete');
+ }
+
+
+ function soa_insert($event_name,$data)
+ {
+ global $app, $conf;
+
+ if($data["new"]["active"] != 'Y') return;
+
+ $origin = substr($data["new"]["origin"], 0, -1);
+ $ispconfig_id = $data["new"]["id"];
+ $serial = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$ispconfig_id);
+
+ $ttl = $data["new"]["ttl"];
+
+ $_db = clone $app->db;
+ $_db->dbName = 'named';
+
+ $_db->query("INSERT INTO records (zone, ttl, type, primary_ns, resp_contact, serial, refresh, retry, expire, minimum, ispconfig_id) VALUES ".
+ "('$origin', $ttl, 'SOA', '{$data["new"]["ns"]}', '{$data["new"]["mbox"]}', '{$serial["serial"]}', '{$serial["refresh"]}'," .
+ "'{$serial["retry"]}', '{$serial["expire"]}', '{$serial["minimum"]}', $ispconfig_id)");
+ unset($_db);
+ }
+
+ function soa_update($event_name,$data)
+ {
+ global $app, $conf;
+
+ if($data["new"]["active"] != 'Y')
+ {
+ if($data["old"]["active"] != 'Y') return;
+ $this->soa_delete($event_name,$data);
+ }
+ else
+ {
+ if($data["old"]["active"] == 'Y')
+ {
+ $origin = substr($data["new"]["origin"], 0, -1);
+ $ispconfig_id = $data["new"]["id"];
+ $serial = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$ispconfig_id);
+
+ $ttl = $data["new"]["ttl"];
+
+ $_db = clone $app->db;
+ $_db->dbName = 'named';
+
+ $_db->query("UPDATE records SET zone = '$origin', ttl = $ttl, primary_ns = '{$data["new"]["ns"]}', resp_contact = '{$data["new"]["mbox"]}', ".
+ "serial = '{$serial["serial"]}', refresh = '{$serial["refresh"]}', retry = '{$serial["retry"]}', expire = '{$serial["expire"]}', ".
+ "minimum = '{$serial["minimum"]}' WHERE ispconfig_id = ".$data["new"]["id"]." AND type = 'SOA'");
+ unset($_db);
+ }
+ else
+ {
+ $this->soa_insert($event_name,$data);
+ $ispconfig_id = $data["new"]["id"];
+
+ if ($records = $app->db->queryAllRecords("SELECT * FROM dns_rr WHERE zone = $ispconfig_id AND active = 'Y'"))
+ {
+ foreach($records as $record)
+ {
+ foreach ($record as $key => $val) {
+ $data["new"][$key] = $val;
+ }
+ $this->rr_insert("dns_rr_insert", $data);
+ }
+ }
+ }
+ }
+
+ }
+
+ function soa_delete($event_name,$data)
+ {
+ global $app, $conf;
+
+ $_db = clone $app->db;
+ $_db->dbName = 'named';
+
+ $_db->query("DELETE FROM records WHERE ispconfig_id = {$data["old"]["id"]}");
+ unset($_db);
+ }
+
+ function rr_insert($event_name,$data)
+ {
+ global $app, $conf;
+ if($data["new"]["active"] != 'Y') return;
+
+ $zone = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$data["new"]["zone"]);
+ $origin = substr($zone["origin"], 0, -1);
+ $ispconfig_id = $data["new"]["id"];
+
+ $type = $data["new"]["type"];
+
+ if (substr($data["new"]["name"], -1) == '.') {
+ $name = substr($data["new"]["name"], 0, -1);
+ } else {
+ $name = ($data["new"]["name"] == "") ? $name = '@' : $data["new"]["name"];
+ }
+
+ if ($name == $origin || $name == '') {
+ $name = '@';
+ }
+
+ switch ($type)
+ {
+ case "CNAME":
+ case "MX":
+ case "NS":
+ case "ALIAS":
+ case "PTR":
+ case "SRV":
+ if(substr($data["new"]["data"], -1) != '.'){
+ $content = $data["new"]["data"] . '.';
+ } else {
+ $content = $data["new"]["data"];
+ }
+ break;
+ case "HINFO":
+ $content = $data["new"]["data"];
+ $quote1 = strpos($content, '"');
+
+ if($quote1 !== FALSE) {
+ $quote2 = strpos(substr($content, ($quote1 + 1)), '"');
+ }
+
+ if ($quote1 !== FALSE && $quote2 !== FALSE) {
+ $text_between_quotes = str_replace(' ', '_', substr($content, ($quote1 + 1), (($quote2 - $quote1))));
+ $content = $text_between_quotes.substr($content, ($quote2 + 2));
+ }
+ break;
+ default:
+ $content = $data["new"]["data"];
+ }
+
+ $ttl = $data["new"]["ttl"];
+
+ $_db = clone $app->db;
+ $_db->dbName = 'named';
+
+ if ($type == 'MX') {
+ $_db->query("INSERT INTO records (zone, ttl, type, host, mx_priority, data, ispconfig_id)".
+ " VALUES ('$origin', $ttl, '$type', '$name', {$data["new"]["aux"]}, '$content', $ispconfig_id)");
+ } else {
+ $_db->query("INSERT INTO records (zone, ttl, type, host, data, ispconfig_id)".
+ " VALUES ('$origin', $ttl, '$type', '$name', '$content', $ispconfig_id)");
+ }
+
+ unset($_db);
+ }
+
+ function rr_update($event_name,$data)
+ {
+ global $app, $conf;
+
+ if ($data["new"]["active"] != 'Y')
+ {
+ if($data["old"]["active"] != 'Y') return;
+ $this->rr_delete($event_name,$data);
+ }
+ else
+ {
+ if ($data["old"]["active"] == 'Y')
+ {
+ $zone = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$data["new"]["zone"]);
+ $origin = substr($zone["origin"], 0, -1);
+ $ispconfig_id = $data["new"]["id"];
+
+ $type = $data["new"]["type"];
+
+ if (substr($data["new"]["name"], -1) == '.') {
+ $name = substr($data["new"]["name"], 0, -1);
+ } else {
+ $name = ($data["new"]["name"] == "") ? $name = '@' : $data["new"]["name"];
+ }
+
+ if ($name == $origin || $name == '') {
+ $name = '@';
+ }
+
+ switch ($type)
+ {
+ case "CNAME":
+ case "MX":
+ case "NS":
+ case "ALIAS":
+ case "PTR":
+ case "SRV":
+ if(substr($data["new"]["data"], -1) != '.'){
+ $content = $data["new"]["data"] . '.';
+ } else {
+ $content = $data["new"]["data"];
+ }
+ break;
+ case "HINFO":
+ $content = $data["new"]["data"];
+ $quote1 = strpos($content, '"');
+ if($quote1 !== FALSE){
+ $quote2 = strpos(substr($content, ($quote1 + 1)), '"');
+ }
+ if($quote1 !== FALSE && $quote2 !== FALSE){
+ $text_between_quotes = str_replace(' ', '_', substr($content, ($quote1 + 1), (($quote2 - $quote1))));
+ $content = $text_between_quotes.substr($content, ($quote2 + 2));
+ }
+ break;
+ default:
+ $content = $data["new"]["data"];
+ }
+
+ $ttl = $data["new"]["ttl"];
+ $prio = (int)$data["new"]["aux"];
+
+ $_db = clone $app->db;
+ $_db->dbName = 'named';
+
+ if ($type == 'MX') {
+ $_db->query("UPDATE records SET zone = '$origin', ttl = $ttl, type = '$type', host = '$name', mx_priority = $prio, ".
+ "data = '$content' WHERE ispconfig_id = $ispconfig_id AND type != 'SOA'");
+ } else {
+ $_db->query("UPDATE records SET zone = '$origin', ttl = $ttl, type = '$type', host = '$name', ".
+ "data = '$content' WHERE ispconfig_id = $ispconfig_id AND type != 'SOA'");
+ }
+
+ unset($_db);
+ } else {
+ $this->rr_insert($event_name,$data);
+ }
+ }
+ }
+
+ function rr_delete($event_name,$data) {
+ global $app, $conf;
+
+ $_db = clone $app->db;
+ $_db->dbName = 'named';
+
+ $_db->query("DELETE FROM named.records WHERE ispconfig_id = {$data["old"]["id"]} AND type != 'SOA'");
+ unset($_db);
+ }
+} // end class
+?>
\ No newline at end of file
--
Gitblit v1.9.1