Marius Cramer
2015-08-06 37b29231e47a0c4458dc1c15d98588f16f07e1e2
commit | author | age
40e657 1 <?php
W 2
3 /*
4 Copyright (c) 2009, Falko Timme, Till Brehm, projektfarm Gmbh
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /*
32 TABLE STRUCTURE of the "named" database:
33
34 CREATE TABLE IF NOT EXISTS `records` (
35   `id` int(10) unsigned NOT NULL auto_increment,
36   `zone` varchar(255) NOT NULL,
b41803 37   `ttl` int(11) NOT NULL default '3600',
40e657 38   `type` varchar(255) NOT NULL,
W 39   `host` varchar(255) NOT NULL default '@',
40   `mx_priority` int(11) default NULL,
41   `data` text,
42   `primary_ns` varchar(255) default NULL,
43   `resp_contact` varchar(255) default NULL,
44   `serial` bigint(20) default NULL,
45   `refresh` int(11) default NULL,
46   `retry` int(11) default NULL,
47   `expire` int(11) default NULL,
48   `minimum` int(11) default NULL,
49   `ispconfig_id` int(11) NOT NULL,
50   PRIMARY KEY  (`id`),
51   KEY `type` (`type`),
52   KEY `host` (`host`),
53   KEY `zone` (`zone`)
54 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
55
56 CREATE TABLE IF NOT EXISTS `xfr` (
57   `id` int(11) NOT NULL auto_increment,
58   `zone` varchar(255) NOT NULL,
59   `client` varchar(255) NOT NULL,
60   `ispconfig_id` int(11) NOT NULL,
61   PRIMARY KEY  (`id`),
62   KEY `zone` (`zone`),
63   KEY `client` (`client`)
64 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
65
66 */
67
68 class bind_dlz_plugin {
7fe908 69
40e657 70     var $plugin_name = 'bind_dlz_plugin';
W 71     var $class_name  = 'bind_dlz_plugin';
7fe908 72
40e657 73     //* This function is called during ispconfig installation to determine
W 74     //  if a symlink shall be created for this plugin.
75     function onInstall()
76     {
77         global $conf;
7fe908 78
40e657 79         if(isset($conf['bind']['installed']) && $conf['bind']['installed'] == true) {
7fe908 80             // Temporarily disabled until the installer supports the automatic creation of the necessary
MC 81             // database or at least to select between filebased nd db based bind, as not all bind versions
c5e095 82             // support dlz out of the box. To enable this plugin manually, create a symlink from the plugins-enabled
T 83             // directory to this file in the plugins-available directory.
84             return false;
85             //return true;
40e657 86         } else {
W 87             return false;
88         }
7fe908 89
40e657 90     }
7fe908 91
40e657 92     /*
W 93          This function is called when the plugin is loaded
94     */
7fe908 95
MC 96     function onLoad()
40e657 97     {
W 98         global $app;
7fe908 99
40e657 100         /*
W 101         Register for the events
102         */
7fe908 103
40e657 104         //* SOA
7fe908 105         $app->plugins->registerEvent('dns_soa_insert', $this->plugin_name, 'soa_insert');
MC 106         $app->plugins->registerEvent('dns_soa_update', $this->plugin_name, 'soa_update');
107         $app->plugins->registerEvent('dns_soa_delete', $this->plugin_name, 'soa_delete');
108
40e657 109         //* RR
7fe908 110         $app->plugins->registerEvent('dns_rr_insert', $this->plugin_name, 'rr_insert');
MC 111         $app->plugins->registerEvent('dns_rr_update', $this->plugin_name, 'rr_update');
112         $app->plugins->registerEvent('dns_rr_delete', $this->plugin_name, 'rr_delete');
40e657 113     }
7fe908 114
MC 115
116     function soa_insert($event_name, $data)
40e657 117     {
W 118         global $app, $conf;
7fe908 119
40e657 120         if($data["new"]["active"] != 'Y') return;
7fe908 121
40e657 122         $origin = substr($data["new"]["origin"], 0, -1);
W 123         $ispconfig_id = $data["new"]["id"];
cc7a82 124         $serial = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $ispconfig_id);
40e657 125
W 126         $ttl = $data["new"]["ttl"];
7fe908 127
cc6568 128         //$_db = clone $app->db;
H 129         //$_db->dbName = 'named';
7fe908 130
cc6568 131         $app->db->query("INSERT INTO named.records (zone, ttl, type, primary_ns, resp_contact, serial, refresh, retry, expire, minimum, ispconfig_id) VALUES ".
2af58c 132             "(?, ?, 'SOA', ?, ?, ?, ?, ?, ?, ?, ?)", $origin, $ttl, $data["new"]["ns"], $data["new"]["mbox"], $serial["serial"], $serial["refresh"], $serial["retry"], $serial["expire"], $serial["minimum"], $ispconfig_id);
7fe908 133         //unset($_db);
40e657 134     }
7fe908 135
MC 136     function soa_update($event_name, $data)
40e657 137     {
W 138         global $app, $conf;
7fe908 139
40e657 140         if($data["new"]["active"] != 'Y')
W 141         {
142             if($data["old"]["active"] != 'Y') return;
7fe908 143             $this->soa_delete($event_name, $data);
MC 144         }
145         else
40e657 146         {
W 147             if($data["old"]["active"] == 'Y')
148             {
149                 $origin = substr($data["new"]["origin"], 0, -1);
150                 $ispconfig_id = $data["new"]["id"];
2af58c 151                 $serial = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $ispconfig_id);
40e657 152
W 153                 $ttl = $data["new"]["ttl"];
7fe908 154
cc6568 155                 //$_db = clone $app->db;
H 156                 //$_db->dbName = 'named';
7fe908 157
2af58c 158                 $app->db->query("UPDATE named.records SET zone = ?, ttl = ?, primary_ns = ?, resp_contact = ?, serial = ?, refresh = ?, retry = ?, expire = ?, minimum = ? WHERE ispconfig_id = ? AND type = 'SOA'", $origin, $ttl, $data["new"]["ns"], $data["new"]["mbox"], $serial["serial"], $serial["refresh"], $serial["retry"], $serial["expire"], $serial["minimum"], $data["new"]["id"]);
cc6568 159                 //unset($_db);
7fe908 160             }
MC 161             else
40e657 162             {
7fe908 163                 $this->soa_insert($event_name, $data);
40e657 164                 $ispconfig_id = $data["new"]["id"];
7fe908 165
2af58c 166                 if ($records = $app->db->queryAllRecords("SELECT * FROM dns_rr WHERE zone = ? AND active = 'Y'", $ispconfig_id))
40e657 167                 {
7fe908 168                     foreach($records as $record)
40e657 169                     {
W 170                         foreach ($record as $key => $val) {
171                             $data["new"][$key] = $val;
172                         }
173                         $this->rr_insert("dns_rr_insert", $data);
174                     }
175                 }
176             }
177         }
7fe908 178
40e657 179     }
7fe908 180
MC 181     function soa_delete($event_name, $data)
40e657 182     {
W 183         global $app, $conf;
7fe908 184
cc6568 185         //$_db = clone $app->db;
H 186         //$_db->dbName = 'named';
7fe908 187
2af58c 188         $app->db->query( "DELETE FROM named.dns_records WHERE zone = ?", substr($data['old']['origin'], 0, -1));
7fe908 189         //unset($_db);
40e657 190     }
7fe908 191
MC 192     function rr_insert($event_name, $data)
40e657 193     {
W 194         global $app, $conf;
195         if($data["new"]["active"] != 'Y') return;
7fe908 196
2af58c 197         $zone = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $data["new"]["zone"]);
40e657 198         $origin = substr($zone["origin"], 0, -1);
W 199         $ispconfig_id = $data["new"]["id"];
7fe908 200
40e657 201         $type = $data["new"]["type"];
7fe908 202
40e657 203         if (substr($data["new"]["name"], -1) == '.') {
W 204             $name = substr($data["new"]["name"], 0, -1);
205         } else {
206             $name = ($data["new"]["name"] == "") ? $name = '@' : $data["new"]["name"];
207         }
7fe908 208
40e657 209         if ($name == $origin || $name == '') {
W 210             $name = '@';
211         }
7fe908 212
MC 213         switch ($type)
40e657 214         {
7fe908 215         case "CNAME":
MC 216         case "MX":
217         case "NS":
218         case "ALIAS":
219         case "PTR":
220         case "SRV":
221             if(substr($data["new"]["data"], -1) != '.'){
222                 $content = $data["new"]["data"] . '.';
223             } else {
40e657 224                 $content = $data["new"]["data"];
7fe908 225             }
MC 226             break;
227         case "HINFO":
228             $content = $data["new"]["data"];
229             $quote1 = strpos($content, '"');
230
231             if($quote1 !== FALSE) {
232                 $quote2 = strpos(substr($content, ($quote1 + 1)), '"');
233             }
234
235             if ($quote1 !== FALSE && $quote2 !== FALSE) {
236                 $text_between_quotes = str_replace(' ', '_', substr($content, ($quote1 + 1), (($quote2 - $quote1))));
237                 $content = $text_between_quotes.substr($content, ($quote2 + 2));
238             }
239             break;
240         default:
241             $content = $data["new"]["data"];
40e657 242         }
7fe908 243
40e657 244         $ttl = $data["new"]["ttl"];
7fe908 245
cc6568 246         //$_db = clone $app->db;
H 247         //$_db->dbName = 'named';
7fe908 248
40e657 249         if ($type == 'MX') {
cc6568 250             $app->db->query("INSERT INTO named.records (zone, ttl, type, host, mx_priority, data, ispconfig_id)".
2af58c 251                 " VALUES (?, ?, ?, ?, ?, ?, ?)", $origin, $ttl, $type, $name, $data["new"]["aux"], $content, $ispconfig_id);
75cc84 252         } elseif ($type == 'SRV') {
TB 253             $app->db->query("INSERT INTO named.records (zone, ttl, type, data, ispconfig_id)".
2af58c 254                 " VALUES (?, ?, ?, ?, ?)", $origin, $ttl, $type, $data["new"]["aux"] . ' ' . $content, $ispconfig_id);
40e657 255         } else {
cc6568 256             $app->db->query("INSERT INTO named.records (zone, ttl, type, host, data, ispconfig_id)".
2af58c 257                 " VALUES (?, ?, ?, ?, ?, ?)", $origin, $ttl, $type, $name, $content, $ispconfig_id);
40e657 258         }
W 259
cc6568 260         //unset($_db);
40e657 261     }
7fe908 262
MC 263     function rr_update($event_name, $data)
40e657 264     {
W 265         global $app, $conf;
7fe908 266
40e657 267         if ($data["new"]["active"] != 'Y')
W 268         {
269             if($data["old"]["active"] != 'Y') return;
7fe908 270             $this->rr_delete($event_name, $data);
40e657 271         }
W 272         else
273         {
274             if ($data["old"]["active"] == 'Y')
275             {
2af58c 276                 $zone = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $data["new"]["zone"]);
40e657 277                 $origin = substr($zone["origin"], 0, -1);
W 278                 $ispconfig_id = $data["new"]["id"];
7fe908 279
MC 280                 $type = $data["new"]["type"];
281
40e657 282                 if (substr($data["new"]["name"], -1) == '.') {
W 283                     $name = substr($data["new"]["name"], 0, -1);
284                 } else {
285                     $name = ($data["new"]["name"] == "") ? $name = '@' : $data["new"]["name"];
286                 }
7fe908 287
40e657 288                 if ($name == $origin || $name == '') {
W 289                     $name = '@';
290                 }
291
7fe908 292                 switch ($type)
40e657 293                 {
7fe908 294                 case "CNAME":
MC 295                 case "MX":
296                 case "NS":
297                 case "ALIAS":
298                 case "PTR":
299                 case "SRV":
300                     if(substr($data["new"]["data"], -1) != '.'){
301                         $content = $data["new"]["data"] . '.';
302                     } else {
40e657 303                         $content = $data["new"]["data"];
7fe908 304                     }
MC 305                     break;
306                 case "HINFO":
307                     $content = $data["new"]["data"];
308                     $quote1 = strpos($content, '"');
309                     if($quote1 !== FALSE){
310                         $quote2 = strpos(substr($content, ($quote1 + 1)), '"');
311                     }
312                     if($quote1 !== FALSE && $quote2 !== FALSE){
313                         $text_between_quotes = str_replace(' ', '_', substr($content, ($quote1 + 1), (($quote2 - $quote1))));
314                         $content = $text_between_quotes.substr($content, ($quote2 + 2));
315                     }
316                     break;
317                 default:
318                     $content = $data["new"]["data"];
40e657 319                 }
7fe908 320
40e657 321                 $ttl = $data["new"]["ttl"];
W 322                 $prio = (int)$data["new"]["aux"];
7fe908 323
cc6568 324                 //$_db = clone $app->db;
H 325                 //$_db->dbName = 'named';
7fe908 326
40e657 327                 if ($type == 'MX') {
2af58c 328                     $app->db->query("UPDATE named.records SET zone = ?, ttl = ?, type = ?, host = ?, mx_priority = ?, data = ? WHERE ispconfig_id = ? AND type != 'SOA'", $origin, $ttl, $type, $name, $prio, $content, $ispconfig_id);
75cc84 329                 } elseif ($type == 'SRV') {
2af58c 330                     $app->db->query("UPDATE named.records SET zone = ?, ttl = ?, type = ?, data = ? WHERE ispconfig_id = ? AND type != 'SOA'", $origin, $ttl, $type, $prio . ' ' . $content, $ispconfig_id);
40e657 331                 } else {
2af58c 332                     $app->db->query("UPDATE named.records SET zone = ?, ttl = ?, type = ?, host = ?, data = ? WHERE ispconfig_id = ? AND type != 'SOA'", $origin, $ttl, $type, $name, $content, $ispconfig_id);
40e657 333                 }
7fe908 334
cc6568 335                 //unset($_db);
40e657 336             } else {
7fe908 337                 $this->rr_insert($event_name, $data);
40e657 338             }
W 339         }
340     }
7fe908 341
MC 342     function rr_delete($event_name, $data) {
40e657 343         global $app, $conf;
7fe908 344
cc6568 345         //$_db = clone $app->db;
H 346         //$_db->dbName = 'named';
7fe908 347
2af58c 348         $app->db->query( "DELETE FROM named.dns_records WHERE type != 'SOA' AND zone = ?", substr($data['old']['origin'], 0, -1));
cc6568 349         //unset($_db);
40e657 350     }
7fe908 351
40e657 352 } // end class
c128b1 353 ?>