bind_plugin.inc.php 22.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

/*
Copyright (c) 2009, 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.
*/

class bind_plugin {
32

33
34
35
	var $plugin_name = 'bind_plugin';
	var $class_name  = 'bind_plugin';
	var $action = 'update';
36

37
38
39
40
	//* This function is called during ispconfig installation to determine
	//  if a symlink shall be created for this plugin.
	function onInstall() {
		global $conf;
41

42
		if(isset($conf['bind']['installed']) && $conf['bind']['installed'] == true && @is_link('/usr/local/ispconfig/server/mods-enabled/dns_module.inc.php')) {
43
44
45
46
			return true;
		} else {
			return false;
		}
47

48
	}
49
50


51
52
53
	/*
	 	This function is called when the plugin is loaded
	*/
54

55
56
	function onLoad() {
		global $app;
57

58
59
60
		/*
		Register for the events
		*/
61

62
		//* SOA
63
64
65
66
67
68
69
70
71
		$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');

		//* SLAVE
		$app->plugins->registerEvent('dns_slave_insert', $this->plugin_name, 'slave_insert');
		$app->plugins->registerEvent('dns_slave_update', $this->plugin_name, 'slave_update');
		$app->plugins->registerEvent('dns_slave_delete', $this->plugin_name, 'slave_delete');

72
		//* RR
73
74
75
76
		$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');

77
	}
78

79
	//* This creates DNSSEC-Keys and calls soa_dnssec_update.
80
	function soa_dnssec_create(&$data) {
81
82
83
84
85
86
87
88
		global $app, $conf;

		//* Load libraries
		$app->uses("getconf,tpl");

		//* load the server configuration options
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
		
A. Täffner's avatar
A. Täffner committed
89
90
91
		//TODO : change this when distribution information has been integrated into server record
		$filespre = (file_exists('/etc/gentoo-release')) ? 'pri/' : 'pri.';
		
92
		$domain = substr($data['new']['origin'], 0, strlen($data['new']['origin'])-1);
A. Täffner's avatar
A. Täffner committed
93
		if (!file_exists($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain)) return false;
94
		
95
96
		//* Check Entropy
		if (file_get_contents('/proc/sys/kernel/random/entropy_avail') < 400) {
A. Täffner's avatar
oops    
A. Täffner committed
97
98
			$app->log('DNSSEC ERROR: We are low on entropy. Not generating new Keys for '.$domain.'. Please consider installing package haveged.', LOGLEVEL_WARN);
			echo "DNSSEC ERROR: We are low on entropy. Not generating new Keys for $domain. Please consider installing package haveged.\n";
99
100
101
102
			return false;
		}
		
		//* Verify that we do not already have keys (overwriting-protection)
103
		if (file_exists($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.')) {
A. Täffner's avatar
A. Täffner committed
104
			return $this->soa_dnssec_update($data);
105
106
107
108
109
110
111
112
113
		} else if ($data['new']['dnssec_initialized'] == 'Y') { //In case that we generated keys but the dsset-file was not generated
			$keycount=0;
			foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'*.key') as $keyfile) {
				$keycount++;
			}
			if ($keycount > 0) {
				$this->soa_dnssec_sign($data);
				return true;
			}
114
115
116
		}
		
		//Do some magic...
117
		exec('cd '.escapeshellcmd($dns_config['bind_zonefiles_dir']).';'.
A. Täffner's avatar
A. Täffner committed
118
119
		'dnssec-keygen -a NSEC3RSASHA1 -b 2048 -n ZONE '.escapeshellcmd($domain).';'.
		'dnssec-keygen -f KSK -a NSEC3RSASHA1 -b 4096 -n ZONE '.escapeshellcmd($domain));
120

121
122
123
124
125
126
127
128
129
130
131
132
		$this->soa_dnssec_sign($data); //Now sign the zone for the first time
		$data['new']['dnssec_initialized']='Y';
	}
	
	function soa_dnssec_sign(&$data) {
		global $app, $conf;
		
		//* Load libraries
		$app->uses("getconf,tpl");

		//* load the server configuration options
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
133
		
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
		//TODO : change this when distribution information has been integrated into server record
		$filespre = (file_exists('/etc/gentoo-release')) ? 'pri/' : 'pri.';
		
		$domain = substr($data['new']['origin'], 0, strlen($data['new']['origin'])-1);
		if (!file_exists($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain)) return false;
		
		$zonefile = file_get_contents($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain);
		$keycount=0;
		foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'*.key') as $keyfile) {
			$includeline = '$INCLUDE '.basename($keyfile);
			if (!preg_match('@'.preg_quote($includeline).'@', $zonefile)) $zonefile .= "\n".$includeline."\n";
			$keycount++;
		}
		if ($keycount != 2) $app->log('DNSSEC Warning: There are more or less than 2 keyfiles for zone '.$domain, LOGLEVEL_WARN);
		file_put_contents($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain, $zonefile);
		
		//Sign the zone and set it valid for max. 16 days
		exec('cd '.escapeshellcmd($dns_config['bind_zonefiles_dir']).';'.
A. Täffner's avatar
A. Täffner committed
152
			 'dnssec-signzone -A -e +1382400 -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N increment -o '.escapeshellcmd($domain).' -t '.$filespre.escapeshellcmd($domain));
153
154
			 
		//Write Data back ino DB
155
156
		$dnssecdata = "DS-Records:\n".file_get_contents($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.');
		$dnssecdata .= "\n------------------------------------\n\nDNSKEY-Records:\n";
157
		foreach (glob($dns_config['bind_zonefiles_dir'].'/K'.$domain.'*.key') as $keyfile) {
158
159
160
			$dnssecdata .= file_get_contents($keyfile)."\n\n";
		}
		
A. Täffner's avatar
A. Täffner committed
161
162
		if ($app->dbmaster !== $app->db) $app->dbmaster->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=\'Y\', dnssec_last_signed=? WHERE id=?', $dnssecdata, intval(time()), intval($data['new']['id']));
		$app->db->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=\'Y\', dnssec_last_signed=? WHERE id=?', $dnssecdata, intval(time()), intval($data['new']['id']));
163
164
	}
	
165
	function soa_dnssec_update(&$data, $new=false) {
166
167
168
169
170
171
172
173
		global $app, $conf;

		//* Load libraries
		$app->uses("getconf,tpl");

		//* load the server configuration options
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
		
A. Täffner's avatar
A. Täffner committed
174
175
176
177
178
179
180
		//TODO : change this when distribution information has been integrated into server record
		$filespre = (file_exists('/etc/gentoo-release')) ? 'pri/' : 'pri.';
		
		$domain = substr($data['new']['origin'], 0, strlen($data['new']['origin'])-1);
		if (!file_exists($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain)) return false;
		
		//* Check for available entropy
181
182
		if (file_get_contents('/proc/sys/kernel/random/entropy_avail') < 200) {
			$app->log('DNSSEC ERROR: We are low on entropy. This could cause server script to fail. Please consider installing package haveged.', LOGLEVEL_ERR);
183
			echo "DNSSEC ERROR: We are low on entropy. This could cause server script to fail. Please consider installing package haveged.\n";
184
185
186
			return false;
		}
		
187
		if (!$new && !file_exists($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.')) $this->soa_dnssec_create($data);
188
		
A. Täffner's avatar
A. Täffner committed
189
		$dbdata = $app->db->queryOneRecord('SELECT id,serial FROM dns_soa WHERE id=?', intval($data['new']['id']));
A. Täffner's avatar
A. Täffner committed
190
		exec('cd '.escapeshellcmd($dns_config['bind_zonefiles_dir']).';'.
A. Täffner's avatar
A. Täffner committed
191
			 'named-checkzone '.escapeshellcmd($domain).' '.escapeshellcmd($dns_config['bind_zonefiles_dir']).'/'.$filespre.escapeshellcmd($domain).' | egrep -ho \'[0-9]{10}\'', $serial, $retState);
A. Täffner's avatar
A. Täffner committed
192
193
194
195
		if ($retState != 0) {
			$app->log('DNSSEC Error: Error in Zonefile for '.$domain, LOGLEVEL_ERR);
			return false;
		}
196
		
197
198
199
200
201
202
203
204
205
206
207
		$this->soa_dnssec_sign($data);
	}
	
	function soa_dnssec_delete(&$data) {
		global $app, $conf;

		//* Load libraries
		$app->uses("getconf,tpl");

		//* load the server configuration options
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
208
		
209
210
211
212
213
214
215
216
217
		//TODO : change this when distribution information has been integrated into server record
		$filespre = (file_exists('/etc/gentoo-release')) ? 'pri/' : 'pri.';
		
		$domain = substr($data['new']['origin'], 0, strlen($data['new']['origin'])-1);
		
		unlink($dns_config['bind_zonefiles_dir'].'/K'.$domain.'.+*');
		unlink($dns_config['bind_zonefiles_dir'].'/'.$filespre.$domain.'.signed');
		unlink($dns_config['bind_zonefiles_dir'].'/dsset-'.$domain.'.');
		
A. Täffner's avatar
A. Täffner committed
218
219
		if ($app->dbmaster !== $app->db) $app->dbmaster->query('UPDATE dns_soa SET dnssec_info=\'\', dnssec_initialized=\'N\' WHERE id=?', intval($data['new']['id']));
		$app->db->query('UPDATE dns_soa SET dnssec_info=\'\', dnssec_initialized=\'N\' WHERE id=?', intval($data['new']['id']));
220
	}
221
222

	function soa_insert($event_name, $data) {
223
		global $app, $conf;
224

225
		$this->action = 'insert';
226
227
		$this->soa_update($event_name, $data);

228
	}
229
230

	function soa_update($event_name, $data) {
231
		global $app, $conf;
232

233
234
		//* Load libraries
		$app->uses("getconf,tpl");
235

236
237
		//* load the server configuration options
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
238

239
		//* Write the domain file
tbrehm's avatar
tbrehm committed
240
		if(!empty($data['new']['id'])) {
tbrehm's avatar
tbrehm committed
241
242
			$tpl = new tpl();
			$tpl->newTemplate("bind_pri.domain.master");
243

tbrehm's avatar
tbrehm committed
244
245
			$zone = $data['new'];
			$tpl->setVar($zone);
246

A. Täffner's avatar
A. Täffner committed
247
			$records = $app->db->queryAllRecords("SELECT * FROM dns_rr WHERE zone = ? AND active = 'Y'", $zone['id']);
248
249
250
			if(is_array($records) && !empty($records)){
				for($i=0;$i<sizeof($records);$i++){
					if($records[$i]['ttl'] == 0) $records[$i]['ttl'] = '';
251
					if($records[$i]['name'] == '') $records[$i]['name'] = '@';
252
253
254
255
					//* Split TXT records, if nescessary
					if($records[$i]['type'] == 'TXT' && strlen($records[$i]['data']) > 255) {
						$records[$i]['data'] = implode('" "',str_split( $records[$i]['data'], 255));
					}
256
257
				}
			}
258
259
			$tpl->setLoop('zones', $records);

wyrie's avatar
wyrie committed
260
			//TODO : change this when distribution information has been integrated into server record
261
			if (file_exists('/etc/gentoo-release')) {
262
				$filename = escapeshellcmd($dns_config['bind_zonefiles_dir'].'/pri/'.str_replace("/", "_", substr($zone['origin'], 0, -1)));
263
264
265
266
267
			}
			else {
				$filename = escapeshellcmd($dns_config['bind_zonefiles_dir'].'/pri.'.str_replace("/", "_", substr($zone['origin'], 0, -1)));
			}

268
			$old_zonefile = @file_get_contents($filename);
269
			file_put_contents($filename, $tpl->grab());
270
271
			chown($filename, escapeshellcmd($dns_config['bind_user']));
			chgrp($filename, escapeshellcmd($dns_config['bind_group']));
272

273
274
			//* Check the zonefile
			if(is_file($filename.'.err')) unlink($filename.'.err');
275
			exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename), $out, $return_status);
276
			if($return_status === 0) {
277
				$app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG);
278
			} else {
279
				$loglevel = @($dns_config['disable_bind_log'] === 'y')?'LOGLEVEL_DEBUG':'LOGLEVEL_WARN';
280
281
282
283
284
285
286
287
288
289
				$app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), $loglevel);
				if(is_array($out) && !empty($out)){
					$app->log('Reason for Bind restart failure: '.implode("\n", $out), $loglevel);
					$app->dbmaster->datalogError(implode("\n", $out));
				}
				if ($old_zonefile != '') {
					rename($filename, $filename.'.err');
					file_put_contents($filename, $old_zonefile);
					chown($filename, escapeshellcmd($dns_config['bind_user']));
					chgrp($filename, escapeshellcmd($dns_config['bind_group']));
290
				} else {
291
					rename($filename, $filename.'.err');
292
				}
293
			}
tbrehm's avatar
tbrehm committed
294
295
			unset($tpl);
			unset($records);
296
			unset($records_out);
tbrehm's avatar
tbrehm committed
297
298
			unset($zone);
		}
299
300
301
		
		//* DNSSEC-Implementation
		if($data['old']['origin'] != $data['new']['origin']) {			
302
			if (@$data['old']['dnssec_initialized'] == 'Y' && strlen(@$data['old']['origin']) > 3) $this->soa_dnssec_delete($data); //delete old keys
303
			if ($data['new']['dnssec_wanted'] == 'Y') $this->soa_dnssec_create($data);
304
		}
305
		else if ($data['new']['dnssec_wanted'] == 'Y' && $data['old']['dnssec_initialized'] == 'N') $this->soa_dnssec_create($data);
306
		else if ($data['new']['dnssec_wanted'] == 'N' && $data['old']['dnssec_initialized'] == 'Y') {	//delete old signed file if dnssec is no longer wanted
307
308
309
310
311
312
313
314
			//TODO : change this when distribution information has been integrated into server record
			if (file_exists('/etc/gentoo-release')) {
				$filename = $dns_config['bind_zonefiles_dir'].'/pri/'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
			}
			else {
				$filename = $dns_config['bind_zonefiles_dir'].'/pri.'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
			}
			if(is_file($filename.'.signed')) unlink($filename.'.signed');
315
 		} else if ($data['new']['dnssec_wanted'] == 'Y') $this->soa_dnssec_update($data);
316
		// END DNSSEC
317
		
318
		//* rebuild the named.conf file if the origin has changed or when the origin is inserted.
319
		//if($this->action == 'insert' || $data['old']['origin'] != $data['new']['origin']) {
320
		$this->write_named_conf($data, $dns_config);
321
		//}
322

323
324
		//* Delete old domain file, if domain name has been changed
		if($data['old']['origin'] != $data['new']['origin']) {
wyrie's avatar
wyrie committed
325
			//TODO : change this when distribution information has been integrated into server record
326
			if (file_exists('/etc/gentoo-release')) {
327
				$filename = $dns_config['bind_zonefiles_dir'].'/pri/'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
328
329
330
331
332
			}
			else {
				$filename = $dns_config['bind_zonefiles_dir'].'/pri.'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
			}

333
334
			if(is_file($filename)) unlink($filename);
			if(is_file($filename.'.err')) unlink($filename.'.err');
335
			if(is_file($filename.'.signed')) unlink($filename.'.signed');
336
337
 		}
 		
338
339
340
341
342
343
		//* Restart bind nameserver if update_acl is not empty, otherwise reload it
		if($data['new']['update_acl'] != '') {
			$app->services->restartServiceDelayed('bind', 'restart');
		} else {
			$app->services->restartServiceDelayed('bind', 'reload');
		}
344

345
	}
346
347

	function soa_delete($event_name, $data) {
348
		global $app, $conf;
349

350
		//* load the server configuration options
351
		$app->uses("getconf,tpl");
352
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
353

354
		//* rebuild the named.conf file
355
356
		$this->write_named_conf($data, $dns_config);

357
		//* Delete the domain file
wyrie's avatar
wyrie committed
358
		//TODO : change this when distribution information has been integrated into server record
359
360
361
362
363
364
365
		if (file_exists('/etc/gentoo-release')) {
			$zone_file_name = $dns_config['bind_zonefiles_dir'].'/pri/'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
		}
		else {
			$zone_file_name = $dns_config['bind_zonefiles_dir'].'/pri.'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
		}

366
		if(is_file($zone_file_name)) unlink($zone_file_name);
367
		if(is_file($zone_file_name.'.err')) unlink($zone_file_name.'.err');
368
369
		$app->log("Deleting BIND domain file: ".$zone_file_name, LOGLEVEL_DEBUG);

370
 		//* DNSSEC-Implementation
371
 		if ($data['old']['dnssec_initialized'] == 'Y') exec('/usr/local/ispconfig/server/scripts/dnssec-delete.sh '.$data['old']['origin']); //delete keys
372
 		
373
		//* Reload bind nameserver
374
375
		$app->services->restartServiceDelayed('bind', 'reload');

376
377
	}

378
	function slave_insert($event_name, $data) {
379
		global $app, $conf;
380

381
		$this->action = 'insert';
382
383
		$this->slave_update($event_name, $data);

384
	}
385
386

	function slave_update($event_name, $data) {
387
		global $app, $conf;
388

389
390
		//* Load libraries
		$app->uses("getconf,tpl");
391

392
393
		//* load the server configuration options
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
394

395
396
		//* rebuild the named.conf file if the origin has changed or when the origin is inserted.
		//if($this->action == 'insert' || $data['old']['origin'] != $data['new']['origin']) {
397
		$this->write_named_conf($data, $dns_config);
398
		//}
399

400
401
		//* Delete old domain file, if domain name has been changed
		if($data['old']['origin'] != $data['new']['origin']) {
wyrie's avatar
wyrie committed
402
			//TODO : change this when distribution information has been integrated into server record
403
404
405
406
407
408
409
			if (file_exists('/etc/gentoo-release')) {
				$filename = $dns_config['bind_zonefiles_dir'].'/sec/'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
			}
			else {
				$filename = $dns_config['bind_zonefiles_dir'].'/slave/sec.'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
			}

410
411
			if(is_file($filename)) unset($filename);
		}
412

413
414
415
416
417
418
		//* Ensure that the named slave directory is writable by the named user
		if (file_exists('/etc/gentoo-release')) {
			$slave_record_dir = $dns_config['bind_zonefiles_dir'].'/sec';
		} else {
			$slave_record_dir = $dns_config['bind_zonefiles_dir'].'/slave';
		}
419
420
421
422
		if(!@is_dir($slave_record_dir)) mkdir($slave_record_dir, 0770);
		chown($slave_record_dir, $dns_config['bind_user']);
		chgrp($slave_record_dir, $dns_config['bind_group']);

423
		//* Reload bind nameserver
424
425
		$app->services->restartServiceDelayed('bind', 'reload');

426
	}
427
428

	function slave_delete($event_name, $data) {
429
		global $app, $conf;
430
431


432
433
434
		//* load the server configuration options
		$app->uses("getconf,tpl");
		$dns_config = $app->getconf->get_server_config($conf["server_id"], 'dns');
435

436
		//* rebuild the named.conf file
437
438
		$this->write_named_conf($data, $dns_config);

439
		//* Delete the domain file
wyrie's avatar
wyrie committed
440
		//TODO : change this when distribution information has been integrated into server record
441
442
443
444
445
446
447
		if (file_exists('/etc/gentoo-release')) {
			$zone_file_name = $dns_config['bind_zonefiles_dir'].'/sec/'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
		}
		else {
			$zone_file_name = $dns_config['bind_zonefiles_dir'].'/slave/sec.'.str_replace("/", "_", substr($data['old']['origin'], 0, -1));
		}

448
		if(is_file($zone_file_name)) unlink($zone_file_name);
449
450
		$app->log("Deleting BIND domain file for secondary zone: ".$zone_file_name, LOGLEVEL_DEBUG);

451
		//* Reload bind nameserver
452
453
454
		$app->services->restartServiceDelayed('bind', 'reload');


455
	}
456
457

	function rr_insert($event_name, $data) {
458
		global $app, $conf;
459

460
		//* Get the data of the soa and call soa_update
461
		$tmp = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $data['new']['zone']);
462
463
464
		$data["new"] = $tmp;
		$data["old"] = $tmp;
		$this->action = 'update';
465
		$this->soa_update($event_name, $data);
466
467

	}
468
469

	function rr_update($event_name, $data) {
470
		global $app, $conf;
471

472
		//* Get the data of the soa and call soa_update
473
		$tmp = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $data['new']['zone']);
474
475
476
		$data["new"] = $tmp;
		$data["old"] = $tmp;
		$this->action = 'update';
477
478
		$this->soa_update($event_name, $data);

479
	}
480
481

	function rr_delete($event_name, $data) {
482
		global $app, $conf;
483

484
		//* Get the data of the soa and call soa_update
485
		$tmp = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE id = ?", $data['old']['zone']);
486
487
488
		$data["new"] = $tmp;
		$data["old"] = $tmp;
		$this->action = 'update';
489
490
		$this->soa_update($event_name, $data);

491
	}
492
493
494

	//##################################################################

495
496
	function write_named_conf($data, $dns_config) {
		global $app, $conf;
497
498

		//* Only write the master file for the current server
499
		$tmps = $app->db->queryAllRecords("SELECT origin, xfer, also_notify, update_acl, dnssec_wanted FROM dns_soa WHERE active = 'Y' AND server_id=?", $conf["server_id"]);
500
		$zones = array();
501

502
		//* Check if the current zone that triggered this function has at least one NS record
503

wyrie's avatar
wyrie committed
504
		//TODO : change this when distribution information has been integrated into server record
505
506
507
508
509
510
511
512
513
		if (file_exists('/etc/gentoo-release')) {
			$pri_zonefiles_path = $dns_config['bind_zonefiles_dir'].'/pri/';
			$sec_zonefiles_path = $dns_config['bind_zonefiles_dir'].'/sec/';

		}
		else {
			$pri_zonefiles_path = $dns_config['bind_zonefiles_dir'].'/pri.';
			$sec_zonefiles_path = $dns_config['bind_zonefiles_dir'].'/slave/sec.';
		}
514

515
		//* Loop trough zones
516
		foreach($tmps as $tmp) {
517
			$zone_file = $pri_zonefiles_path.str_replace("/", "_", substr($tmp['origin'], 0, -1));
518
			if ($tmp['dnssec_wanted'] == 'Y') $zone_file .= '.signed'; //.signed is for DNSSEC-Implementation
519

520
			$options = '';
521
			if(trim($tmp['xfer']) != '') {
522
				$options .= "        allow-transfer {".str_replace(',', ';', $tmp['xfer']).";};\n";
523
524
525
			} else {
				$options .= "        allow-transfer {none;};\n";
			}
526
527
528
			if(trim($tmp['also_notify']) != '') $options .= '        also-notify {'.str_replace(',', ';', $tmp['also_notify']).";};\n";
			if(trim($tmp['update_acl']) != '') $options .= "        allow-update {".str_replace(',', ';', $tmp['update_acl']).";};\n";

529
			if(file_exists($zone_file)) {
530
531
532
533
				$zones[] = array( 'zone' => substr($tmp['origin'], 0, -1),
					'zonefile_path' => $zone_file,
					'options' => $options
				);
534
			}
535
		}
536

537
538
		$tpl = new tpl();
		$tpl->newTemplate("bind_named.conf.local.master");
539
540
		$tpl->setLoop('zones', $zones);

541
		//* And loop through the secondary zones, but only for the current server
542
		$tmps_sec = $app->db->queryAllRecords("SELECT origin, xfer, ns FROM dns_slave WHERE active = 'Y' AND server_id=?", $conf["server_id"]);
543
544
545
		$zones_sec = array();

		foreach($tmps_sec as $tmp) {
546

547
			$options = "        masters {".$tmp['ns'].";};\n";
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
			if(trim($tmp['xfer']) != '') {
				$options .= "        allow-transfer {".str_replace(',', ';', $tmp['xfer']).";};\n";
			} else {
				$options .= "        allow-transfer {none;};\n";
			}


			$zones_sec[] = array( 'zone' => substr($tmp['origin'], 0, -1),
				'zonefile_path' => $sec_zonefiles_path.str_replace("/", "_", substr($tmp['origin'], 0, -1)),
				'options' => $options
			);

			//   $filename = escapeshellcmd($dns_config['bind_zonefiles_dir'].'/slave/sec.'.substr($tmp['origin'],0,-1));
			//   $app->log("Writing BIND domain file: ".$filename,LOGLEVEL_DEBUG);


564
		}
565

566
567
		$tpl_sec = new tpl();
		$tpl_sec->newTemplate("bind_named.conf.local.slave");
568
569
570
571
572
573
574
575
		$tpl_sec->setLoop('zones', $zones_sec);

		file_put_contents($dns_config['named_conf_local_path'], $tpl->grab()."\n".$tpl_sec->grab());
		$app->log("Writing BIND named.conf.local file: ".$dns_config['named_conf_local_path'], LOGLEVEL_DEBUG);

		unset($tpl_sec);
		unset($zones_sec);
		unset($tmps_sec);
576
		unset($tpl);
577
578
		unset($zones);
		unset($tmps);
579

580
	}
581
582
583



584
585
586

} // end class

587
?>