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 |
?> |