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, |
|
37 |
`ttl` int(11) NOT NULL default '86400', |
|
38 |
`type` varchar(255) NOT NULL, |
|
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"]; |
|
124 |
$serial = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$ispconfig_id); |
|
125 |
|
|
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 ". |
7fe908
|
132 |
"('$origin', $ttl, 'SOA', '{$data["new"]["ns"]}', '{$data["new"]["mbox"]}', '{$serial["serial"]}', '{$serial["refresh"]}'," . |
MC |
133 |
"'{$serial["retry"]}', '{$serial["expire"]}', '{$serial["minimum"]}', $ispconfig_id)"); |
|
134 |
//unset($_db); |
40e657
|
135 |
} |
7fe908
|
136 |
|
MC |
137 |
function soa_update($event_name, $data) |
40e657
|
138 |
{ |
W |
139 |
global $app, $conf; |
7fe908
|
140 |
|
40e657
|
141 |
if($data["new"]["active"] != 'Y') |
W |
142 |
{ |
|
143 |
if($data["old"]["active"] != 'Y') return; |
7fe908
|
144 |
$this->soa_delete($event_name, $data); |
MC |
145 |
} |
|
146 |
else |
40e657
|
147 |
{ |
W |
148 |
if($data["old"]["active"] == 'Y') |
|
149 |
{ |
|
150 |
$origin = substr($data["new"]["origin"], 0, -1); |
|
151 |
$ispconfig_id = $data["new"]["id"]; |
|
152 |
$serial = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$ispconfig_id); |
|
153 |
|
|
154 |
$ttl = $data["new"]["ttl"]; |
7fe908
|
155 |
|
cc6568
|
156 |
//$_db = clone $app->db; |
H |
157 |
//$_db->dbName = 'named'; |
7fe908
|
158 |
|
cc6568
|
159 |
$app->db->query("UPDATE named.records SET zone = '$origin', ttl = $ttl, primary_ns = '{$data["new"]["ns"]}', resp_contact = '{$data["new"]["mbox"]}', ". |
7fe908
|
160 |
"serial = '{$serial["serial"]}', refresh = '{$serial["refresh"]}', retry = '{$serial["retry"]}', expire = '{$serial["expire"]}', ". |
MC |
161 |
"minimum = '{$serial["minimum"]}' WHERE ispconfig_id = ".$data["new"]["id"]." AND type = 'SOA'"); |
cc6568
|
162 |
//unset($_db); |
7fe908
|
163 |
} |
MC |
164 |
else |
40e657
|
165 |
{ |
7fe908
|
166 |
$this->soa_insert($event_name, $data); |
40e657
|
167 |
$ispconfig_id = $data["new"]["id"]; |
7fe908
|
168 |
|
40e657
|
169 |
if ($records = $app->db->queryAllRecords("SELECT * FROM dns_rr WHERE zone = $ispconfig_id AND active = 'Y'")) |
W |
170 |
{ |
7fe908
|
171 |
foreach($records as $record) |
40e657
|
172 |
{ |
W |
173 |
foreach ($record as $key => $val) { |
|
174 |
$data["new"][$key] = $val; |
|
175 |
} |
|
176 |
$this->rr_insert("dns_rr_insert", $data); |
|
177 |
} |
|
178 |
} |
|
179 |
} |
|
180 |
} |
7fe908
|
181 |
|
40e657
|
182 |
} |
7fe908
|
183 |
|
MC |
184 |
function soa_delete($event_name, $data) |
40e657
|
185 |
{ |
W |
186 |
global $app, $conf; |
7fe908
|
187 |
|
cc6568
|
188 |
//$_db = clone $app->db; |
H |
189 |
//$_db->dbName = 'named'; |
7fe908
|
190 |
|
4c842d
|
191 |
$app->db->query( "DELETE FROM named.dns_records WHERE zone = '".substr($data['old']['origin'], 0, -1)."'"); |
7fe908
|
192 |
//unset($_db); |
40e657
|
193 |
} |
7fe908
|
194 |
|
MC |
195 |
function rr_insert($event_name, $data) |
40e657
|
196 |
{ |
W |
197 |
global $app, $conf; |
|
198 |
if($data["new"]["active"] != 'Y') return; |
7fe908
|
199 |
|
40e657
|
200 |
$zone = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$data["new"]["zone"]); |
W |
201 |
$origin = substr($zone["origin"], 0, -1); |
|
202 |
$ispconfig_id = $data["new"]["id"]; |
7fe908
|
203 |
|
40e657
|
204 |
$type = $data["new"]["type"]; |
7fe908
|
205 |
|
40e657
|
206 |
if (substr($data["new"]["name"], -1) == '.') { |
W |
207 |
$name = substr($data["new"]["name"], 0, -1); |
|
208 |
} else { |
|
209 |
$name = ($data["new"]["name"] == "") ? $name = '@' : $data["new"]["name"]; |
|
210 |
} |
7fe908
|
211 |
|
40e657
|
212 |
if ($name == $origin || $name == '') { |
W |
213 |
$name = '@'; |
|
214 |
} |
7fe908
|
215 |
|
MC |
216 |
switch ($type) |
40e657
|
217 |
{ |
7fe908
|
218 |
case "CNAME": |
MC |
219 |
case "MX": |
|
220 |
case "NS": |
|
221 |
case "ALIAS": |
|
222 |
case "PTR": |
|
223 |
case "SRV": |
|
224 |
if(substr($data["new"]["data"], -1) != '.'){ |
|
225 |
$content = $data["new"]["data"] . '.'; |
|
226 |
} else { |
40e657
|
227 |
$content = $data["new"]["data"]; |
7fe908
|
228 |
} |
MC |
229 |
break; |
|
230 |
case "HINFO": |
|
231 |
$content = $data["new"]["data"]; |
|
232 |
$quote1 = strpos($content, '"'); |
|
233 |
|
|
234 |
if($quote1 !== FALSE) { |
|
235 |
$quote2 = strpos(substr($content, ($quote1 + 1)), '"'); |
|
236 |
} |
|
237 |
|
|
238 |
if ($quote1 !== FALSE && $quote2 !== FALSE) { |
|
239 |
$text_between_quotes = str_replace(' ', '_', substr($content, ($quote1 + 1), (($quote2 - $quote1)))); |
|
240 |
$content = $text_between_quotes.substr($content, ($quote2 + 2)); |
|
241 |
} |
|
242 |
break; |
|
243 |
default: |
|
244 |
$content = $data["new"]["data"]; |
40e657
|
245 |
} |
7fe908
|
246 |
|
40e657
|
247 |
$ttl = $data["new"]["ttl"]; |
7fe908
|
248 |
|
cc6568
|
249 |
//$_db = clone $app->db; |
H |
250 |
//$_db->dbName = 'named'; |
7fe908
|
251 |
|
40e657
|
252 |
if ($type == 'MX') { |
cc6568
|
253 |
$app->db->query("INSERT INTO named.records (zone, ttl, type, host, mx_priority, data, ispconfig_id)". |
7fe908
|
254 |
" VALUES ('$origin', $ttl, '$type', '$name', {$data["new"]["aux"]}, '$content', $ispconfig_id)"); |
75cc84
|
255 |
} elseif ($type == 'SRV') { |
TB |
256 |
$app->db->query("INSERT INTO named.records (zone, ttl, type, data, ispconfig_id)". |
|
257 |
" VALUES ('$origin', $ttl, '$type', '{$data["new"]["aux"]} $content', $ispconfig_id)"); |
40e657
|
258 |
} else { |
cc6568
|
259 |
$app->db->query("INSERT INTO named.records (zone, ttl, type, host, data, ispconfig_id)". |
7fe908
|
260 |
" VALUES ('$origin', $ttl, '$type', '$name', '$content', $ispconfig_id)"); |
40e657
|
261 |
} |
W |
262 |
|
cc6568
|
263 |
//unset($_db); |
40e657
|
264 |
} |
7fe908
|
265 |
|
MC |
266 |
function rr_update($event_name, $data) |
40e657
|
267 |
{ |
W |
268 |
global $app, $conf; |
7fe908
|
269 |
|
40e657
|
270 |
if ($data["new"]["active"] != 'Y') |
W |
271 |
{ |
|
272 |
if($data["old"]["active"] != 'Y') return; |
7fe908
|
273 |
$this->rr_delete($event_name, $data); |
40e657
|
274 |
} |
W |
275 |
else |
|
276 |
{ |
|
277 |
if ($data["old"]["active"] == 'Y') |
|
278 |
{ |
|
279 |
$zone = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ".$data["new"]["zone"]); |
|
280 |
$origin = substr($zone["origin"], 0, -1); |
|
281 |
$ispconfig_id = $data["new"]["id"]; |
7fe908
|
282 |
|
MC |
283 |
$type = $data["new"]["type"]; |
|
284 |
|
40e657
|
285 |
if (substr($data["new"]["name"], -1) == '.') { |
W |
286 |
$name = substr($data["new"]["name"], 0, -1); |
|
287 |
} else { |
|
288 |
$name = ($data["new"]["name"] == "") ? $name = '@' : $data["new"]["name"]; |
|
289 |
} |
7fe908
|
290 |
|
40e657
|
291 |
if ($name == $origin || $name == '') { |
W |
292 |
$name = '@'; |
|
293 |
} |
|
294 |
|
7fe908
|
295 |
switch ($type) |
40e657
|
296 |
{ |
7fe908
|
297 |
case "CNAME": |
MC |
298 |
case "MX": |
|
299 |
case "NS": |
|
300 |
case "ALIAS": |
|
301 |
case "PTR": |
|
302 |
case "SRV": |
|
303 |
if(substr($data["new"]["data"], -1) != '.'){ |
|
304 |
$content = $data["new"]["data"] . '.'; |
|
305 |
} else { |
40e657
|
306 |
$content = $data["new"]["data"]; |
7fe908
|
307 |
} |
MC |
308 |
break; |
|
309 |
case "HINFO": |
|
310 |
$content = $data["new"]["data"]; |
|
311 |
$quote1 = strpos($content, '"'); |
|
312 |
if($quote1 !== FALSE){ |
|
313 |
$quote2 = strpos(substr($content, ($quote1 + 1)), '"'); |
|
314 |
} |
|
315 |
if($quote1 !== FALSE && $quote2 !== FALSE){ |
|
316 |
$text_between_quotes = str_replace(' ', '_', substr($content, ($quote1 + 1), (($quote2 - $quote1)))); |
|
317 |
$content = $text_between_quotes.substr($content, ($quote2 + 2)); |
|
318 |
} |
|
319 |
break; |
|
320 |
default: |
|
321 |
$content = $data["new"]["data"]; |
40e657
|
322 |
} |
7fe908
|
323 |
|
40e657
|
324 |
$ttl = $data["new"]["ttl"]; |
W |
325 |
$prio = (int)$data["new"]["aux"]; |
7fe908
|
326 |
|
cc6568
|
327 |
//$_db = clone $app->db; |
H |
328 |
//$_db->dbName = 'named'; |
7fe908
|
329 |
|
40e657
|
330 |
if ($type == 'MX') { |
cc6568
|
331 |
$app->db->query("UPDATE named.records SET zone = '$origin', ttl = $ttl, type = '$type', host = '$name', mx_priority = $prio, ". |
7fe908
|
332 |
"data = '$content' WHERE ispconfig_id = $ispconfig_id AND type != 'SOA'"); |
75cc84
|
333 |
} elseif ($type == 'SRV') { |
TB |
334 |
$app->db->query("UPDATE named.records SET zone = '$origin', ttl = $ttl, type = '$type', ". |
|
335 |
"data = '$prio $content' WHERE ispconfig_id = $ispconfig_id AND type != 'SOA'"); |
40e657
|
336 |
} else { |
cc6568
|
337 |
$app->db->query("UPDATE named.records SET zone = '$origin', ttl = $ttl, type = '$type', host = '$name', ". |
7fe908
|
338 |
"data = '$content' WHERE ispconfig_id = $ispconfig_id AND type != 'SOA'"); |
40e657
|
339 |
} |
7fe908
|
340 |
|
cc6568
|
341 |
//unset($_db); |
40e657
|
342 |
} else { |
7fe908
|
343 |
$this->rr_insert($event_name, $data); |
40e657
|
344 |
} |
W |
345 |
} |
|
346 |
} |
7fe908
|
347 |
|
MC |
348 |
function rr_delete($event_name, $data) { |
40e657
|
349 |
global $app, $conf; |
7fe908
|
350 |
|
cc6568
|
351 |
//$_db = clone $app->db; |
H |
352 |
//$_db->dbName = 'named'; |
7fe908
|
353 |
|
4c842d
|
354 |
$app->db->query( "DELETE FROM named.dns_records WHERE type != 'SOA' AND zone = '".substr($data['old']['origin'], 0, -1)."'"); |
cc6568
|
355 |
//unset($_db); |
40e657
|
356 |
} |
7fe908
|
357 |
|
40e657
|
358 |
} // end class |
c128b1
|
359 |
?> |