Project

General

Profile

Download (15.1 KB) Statistics
| Branch: | Tag: | Revision:
1 7ed0e844 Warren Baker
<?php
2
/* $Id$ */
3
/*
4
	services_unbound.php
5 c7281770 Chris Buechler
	part of the pfSense project (https://www.pfsense.org)
6 fff4a9d1 Warren Baker
	Copyright (C) 2014	Warren Baker (warren@pfsense.org)
7 ce77a9c4 Phil Davis
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
8 7ed0e844 Warren Baker
	All rights reserved.
9
10
	Redistribution and use in source and binary forms, with or without
11 fff4a9d1 Warren Baker
	modification, are permitted provided that the following conditions are met:
12 7ed0e844 Warren Baker
13 a88ec513 Renato Botelho
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in the
18
	   documentation and/or other materials provided with the distribution.
19
20
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
24
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
	POSSIBILITY OF SUCH DAMAGE.
30 7ed0e844 Warren Baker
*/
31
/*
32 51c224bc sbeaver
	pfSense_MODULE: dnsresolver
33 7ed0e844 Warren Baker
*/
34
35
##|+PRIV
36
##|*IDENT=page-services-unbound
37
##|*NAME=Services: DNS Resolver page
38
##|*DESCR=Allow access to the 'Services: DNS Resolver' page.
39
##|*MATCH=services_unbound.php*
40
##|-PRIV
41
42
require_once("guiconfig.inc");
43
require_once("unbound.inc");
44 4dbcf2fb Renato Botelho
require_once("system.inc");
45 7ed0e844 Warren Baker
46 be11b6f1 Warren Baker
if (!is_array($config['unbound'])) {
47 2783e408 Renato Botelho
	$config['unbound'] = array();
48 be11b6f1 Warren Baker
}
49
50 7ed0e844 Warren Baker
$a_unboundcfg =& $config['unbound'];
51
52 be11b6f1 Warren Baker
if (!is_array($config['unbound']['hosts'])) {
53 2783e408 Renato Botelho
	$config['unbound']['hosts'] = array();
54 be11b6f1 Warren Baker
}
55
56 7ed0e844 Warren Baker
$a_hosts =& $config['unbound']['hosts'];
57
58 be11b6f1 Warren Baker
if (!is_array($config['unbound']['domainoverrides'])) {
59 2783e408 Renato Botelho
	$config['unbound']['domainoverrides'] = array();
60 be11b6f1 Warren Baker
}
61
62 7ed0e844 Warren Baker
$a_domainOverrides = &$config['unbound']['domainoverrides'];
63
64 be11b6f1 Warren Baker
if (isset($config['unbound']['enable'])) {
65 fe9d4894 Renato Botelho
	$pconfig['enable'] = true;
66 be11b6f1 Warren Baker
}
67
if (isset($config['unbound']['dnssec'])) {
68 fe9d4894 Renato Botelho
	$pconfig['dnssec'] = true;
69 be11b6f1 Warren Baker
}
70
if (isset($config['unbound']['forwarding'])) {
71 fe9d4894 Renato Botelho
	$pconfig['forwarding'] = true;
72 be11b6f1 Warren Baker
}
73
if (isset($config['unbound']['regdhcp'])) {
74 fe9d4894 Renato Botelho
	$pconfig['regdhcp'] = true;
75 be11b6f1 Warren Baker
}
76
if (isset($config['unbound']['regdhcpstatic'])) {
77 fe9d4894 Renato Botelho
	$pconfig['regdhcpstatic'] = true;
78 be11b6f1 Warren Baker
}
79
if (isset($config['unbound']['txtsupport'])) {
80 fe9d4894 Renato Botelho
	$pconfig['txtsupport'] = true;
81 be11b6f1 Warren Baker
}
82 615ae81f Renato Botelho
83
$pconfig['port'] = $config['unbound']['port'];
84 cfb5073f Renato Botelho
$pconfig['custom_options'] = base64_decode($config['unbound']['custom_options']);
85 615ae81f Renato Botelho
86 be11b6f1 Warren Baker
if (empty($config['unbound']['active_interface'])) {
87 2783e408 Renato Botelho
	$pconfig['active_interface'] = array();
88 be11b6f1 Warren Baker
} else {
89 2783e408 Renato Botelho
	$pconfig['active_interface'] = explode(",", $config['unbound']['active_interface']);
90 be11b6f1 Warren Baker
}
91 51c224bc sbeaver
92 be11b6f1 Warren Baker
if (empty($config['unbound']['outgoing_interface'])) {
93 2783e408 Renato Botelho
	$pconfig['outgoing_interface'] = array();
94 be11b6f1 Warren Baker
} else {
95 2783e408 Renato Botelho
	$pconfig['outgoing_interface'] = explode(",", $config['unbound']['outgoing_interface']);
96 be11b6f1 Warren Baker
}
97 615ae81f Renato Botelho
98 7ed0e844 Warren Baker
if ($_POST) {
99 2783e408 Renato Botelho
	$pconfig = $_POST;
100
	unset($input_errors);
101
102
	if ($_POST['apply']) {
103
		$retval = services_unbound_configure();
104
		$savemsg = get_std_save_message($retval);
105
		if ($retval == 0) {
106
			clear_subsystem_dirty('unbound');
107 fe9d4894 Renato Botelho
		}
108 2783e408 Renato Botelho
		/* Update resolv.conf in case the interface bindings exclude localhost. */
109
		system_resolvconf_generate();
110 4dbcf2fb Renato Botelho
		/* Start or restart dhcpleases when it's necessary */
111
		system_dhcpleases_configure();
112 2783e408 Renato Botelho
	} else {
113
		if (isset($_POST['enable']) && isset($config['dnsmasq']['enable'])) {
114 e92ee598 Phil Davis
			if ($_POST['port'] == $config['dnsmasq']['port']) {
115 8106d446 Chris Buechler
				$input_errors[] = "The DNS Forwarder is enabled using this port. Choose a non-conflicting port, or disable the DNS Forwarder.";
116 e92ee598 Phil Davis
			}
117 fe9d4894 Renato Botelho
		}
118 615ae81f Renato Botelho
119 2783e408 Renato Botelho
		if (empty($_POST['active_interface'])) {
120 b026cb18 Chris Buechler
			$input_errors[] = "One or more Network Interfaces must be selected for binding.";
121 b7960673 Chris Buechler
		} else if (!isset($config['system']['dnslocalhost']) && (!in_array("lo0", $_POST['active_interface']) && !in_array("all", $_POST['active_interface']))) {
122
			$input_errors[] = "This system is configured to use the DNS Resolver as its DNS server, so Localhost or All must be selected in Network Interfaces.";
123 fe9d4894 Renato Botelho
		}
124 7ed0e844 Warren Baker
125 2783e408 Renato Botelho
		if (empty($_POST['outgoing_interface'])) {
126 b026cb18 Chris Buechler
			$input_errors[] = "One or more Outgoing Network Interfaces must be selected.";
127 fe9d4894 Renato Botelho
		}
128 7ed0e844 Warren Baker
129 2783e408 Renato Botelho
		if ($_POST['port']) {
130
			if (is_port($_POST['port'])) {
131
				$a_unboundcfg['port'] = $_POST['port'];
132 fe9d4894 Renato Botelho
			} else {
133 2783e408 Renato Botelho
				$input_errors[] = gettext("You must specify a valid port number.");
134 fe9d4894 Renato Botelho
			}
135
		} else if (isset($config['unbound']['port'])) {
136 2783e408 Renato Botelho
			unset($config['unbound']['port']);
137 fe9d4894 Renato Botelho
		}
138 fff4a9d1 Warren Baker
139 2783e408 Renato Botelho
		if (isset($_POST['enable'])) {
140
			$a_unboundcfg['enable'] = true;
141 fe9d4894 Renato Botelho
		} else {
142 2783e408 Renato Botelho
			unset($a_unboundcfg['enable']);
143 fe9d4894 Renato Botelho
		}
144 2783e408 Renato Botelho
		if (isset($_POST['dnssec'])) {
145
			$a_unboundcfg['dnssec'] = true;
146 fe9d4894 Renato Botelho
		} else {
147 2783e408 Renato Botelho
			unset($a_unboundcfg['dnssec']);
148 fe9d4894 Renato Botelho
		}
149 2783e408 Renato Botelho
		if (isset($_POST['forwarding'])) {
150
			$a_unboundcfg['forwarding'] = true;
151 fe9d4894 Renato Botelho
		} else {
152 2783e408 Renato Botelho
			unset($a_unboundcfg['forwarding']);
153 fe9d4894 Renato Botelho
		}
154
		if (isset($_POST['regdhcp'])) {
155 2783e408 Renato Botelho
			$a_unboundcfg['regdhcp'] = true;
156 fe9d4894 Renato Botelho
		} else {
157 2783e408 Renato Botelho
			unset($a_unboundcfg['regdhcp']);
158 fe9d4894 Renato Botelho
		}
159 2783e408 Renato Botelho
		if (isset($_POST['regdhcpstatic'])) {
160
			$a_unboundcfg['regdhcpstatic'] = true;
161 fe9d4894 Renato Botelho
		} else {
162 2783e408 Renato Botelho
			unset($a_unboundcfg['regdhcpstatic']);
163 fe9d4894 Renato Botelho
		}
164 2783e408 Renato Botelho
		if (isset($_POST['txtsupport'])) {
165
			$a_unboundcfg['txtsupport'] = true;
166 fe9d4894 Renato Botelho
		} else {
167 2783e408 Renato Botelho
			unset($a_unboundcfg['txtsupport']);
168 fe9d4894 Renato Botelho
		}
169 2783e408 Renato Botelho
		if (is_array($_POST['active_interface']) && !empty($_POST['active_interface'])) {
170
			$a_unboundcfg['active_interface'] = implode(",", $_POST['active_interface']);
171 fe9d4894 Renato Botelho
		}
172 7ed0e844 Warren Baker
173 2783e408 Renato Botelho
		if (is_array($_POST['outgoing_interface']) && !empty($_POST['outgoing_interface'])) {
174
			$a_unboundcfg['outgoing_interface'] = implode(",", $_POST['outgoing_interface']);
175 fe9d4894 Renato Botelho
		}
176 188609c6 Warren Baker
177 cfb5073f Renato Botelho
		$a_unboundcfg['custom_options'] = base64_encode(str_replace("\r\n", "\n", $_POST['custom_options']));
178 7ed0e844 Warren Baker
179 2783e408 Renato Botelho
		if (!$input_errors) {
180
			write_config("DNS Resolver configured.");
181
			mark_subsystem_dirty('unbound');
182
		}
183
	}
184 7ed0e844 Warren Baker
}
185
186 f2bc186f Warren Baker
if ($_GET['act'] == "del") {
187 2783e408 Renato Botelho
	if ($_GET['type'] == 'host') {
188
		if ($a_hosts[$_GET['id']]) {
189
			unset($a_hosts[$_GET['id']]);
190
			write_config();
191
			mark_subsystem_dirty('unbound');
192
			header("Location: services_unbound.php");
193
			exit;
194
		}
195
	} elseif ($_GET['type'] == 'doverride') {
196
		if ($a_domainOverrides[$_GET['id']]) {
197
			unset($a_domainOverrides[$_GET['id']]);
198
			write_config();
199
			mark_subsystem_dirty('unbound');
200
			header("Location: services_unbound.php");
201
			exit;
202
		}
203
	}
204 f2bc186f Warren Baker
}
205
206 51c224bc sbeaver
function build_if_list() {
207
	$interface_addresses = get_possible_listen_ips(true);
208
	$iflist = array('options' => array(), 'selected' => array());
209
210 7275a7a2 Stephen Beaver
	$iflist['options']['all']	= "All";
211 51c224bc sbeaver
	if (empty($pconfig['interface']) || empty($pconfig['interface'][0]))
212 7275a7a2 Stephen Beaver
		array_push($iflist['selected'], "all");
213 51c224bc sbeaver
214
	foreach ($interface_addresses as $laddr => $ldescr) {
215
		$iflist['options'][$laddr] = htmlspecialchars($ldescr);
216
217
		if ($pconfig['interface'] && in_array($laddr, $pconfig['interface']))
218
			array_push($iflist['selected'], $laddr);
219
	}
220
221
	unset($interface_addresses);
222
223
	return($iflist);
224
}
225
226 931f47ea Colin Fleming
$closehead = false;
227 e92ee598 Phil Davis
$pgtitle = array(gettext("Services"), gettext("DNS Resolver"));
228 db88a3a2 Phil Davis
$shortcut_section = "resolver";
229 7ed0e844 Warren Baker
230 51c224bc sbeaver
include_once("head.inc");
231 7ed0e844 Warren Baker
232 51c224bc sbeaver
if ($input_errors)
233
	print_input_errors($input_errors);
234
235
if ($savemsg)
236
	print_info_box($savemsg, 'success');
237
238
$tab_array = array();
239
$tab_array[] = array(gettext("General settings"), true, "services_unbound.php");
240
$tab_array[] = array(gettext("Advanced settings"), false, "services_unbound_advanced.php");
241
$tab_array[] = array(gettext("Access Lists"), false, "/services_unbound_acls.php");
242
display_top_tabs($tab_array, true);
243
244 49840447 PiBa-NL
require_once('classes/Form.class.php');
245 51c224bc sbeaver
246
$form = new Form();
247
248
$section = new Form_Section('General DNS Resolver Options');
249
250
$section->addInput(new Form_Checkbox(
251
	'enable',
252
	'Enable',
253
	'Enable DNS resolver',
254
	$pconfig['enable']
255
));
256
257
$section->addInput(new Form_Input(
258
	'port',
259
	'Listen Port',
260
	'text',
261
	$pconfig['port']
262
))->setHelp('The port used for responding to DNS queries. It should normally be left blank unless another service needs to bind to TCP/UDP port 53.');
263
264
$iflist = build_if_list();
265
266
$section->addInput(new Form_Select(
267
	'active_interface',
268
	'Network Interfaces',
269
	$iflist['selected'],
270
	$iflist['options'],
271
	true
272
))->setHelp('Interface IPs used by the DNS Resolver for responding to queries from clients. If an interface has both IPv4 and IPv6 IPs, both are used. Queries to other interface IPs not selected below are discarded. ' .
273
			'The default behavior is to respond to queries on every available IPv4 and IPv6 address.');
274
275
$section->addInput(new Form_Select(
276
	'outgoing_interface',
277
	'Outgoing Network Interfaces',
278
	$iflist['selected'],
279
	$iflist['options'],
280
	true
281
))->setHelp('Utilize different network interface(s) that the DNS Resolver will use to send queries to authoritative servers and receive their replies. By default all interfaces are used.');
282
283
$section->addInput(new Form_Checkbox(
284
	'dnssec',
285
	'DNSSEC',
286
	'Enable DNSSEC Support',
287
	$pconfig['dnssec']
288
));
289
290
$section->addInput(new Form_Checkbox(
291
	'forwarding',
292
	'DNS Query Forwarding',
293
	'Enable Forwarding Mode',
294
	$pconfig['forwarding']
295
));
296
297
$section->addInput(new Form_Checkbox(
298
	'regdhcp',
299
	'DHCP Registration',
300
	'Register DHCP leases in the DNS Resolver',
301
	$pconfig['regdhcp']
302
))->setHelp(sprintf('If this option is set, then machines that specify their hostname when requesting a DHCP lease will be registered'.
303
					' in the DNS Resolver, so that their name can be resolved.'.
304
					' You should also set the domain in %sSystem: General setup%s to the proper value.','<a href="system.php">','</a>'));
305
306
$section->addInput(new Form_Checkbox(
307
	'regdhcpstatic',
308
	'Static DHCP',
309
	'Register DHCP static mappings in the DNS Resolver',
310
	$pconfig['regdhcpstatic']
311
))->setHelp(sprintf('If this option is set, then DHCP static mappings will be registered in the DNS Resolver, so that their name can be '.
312
					'resolved. You should also set the domain in %s'.
313
					'System: General setup%s to the proper value.','<a href="system.php">','</a>'));
314
315
$section->addInput(new Form_Checkbox(
316
	'txtsupport',
317
	'TXT Comment Support',
318
	'Register DHCP static mappings in the DNS Resolver',
319
	$pconfig['txtsupport']
320
))->setHelp('Any descriptions associated with Host entries and DHCP Static mappings will create a corresponding TXT record.');
321
322
$btnadvdns = new Form_Button(
323
	'btnadvdns',
324
	'Advanced'
325
);
326
327
$btnadvdns->removeClass('btn-primary')->addClass('btn-default btn-sm');
328
329
$section->addInput(new Form_StaticText(
330
	'Advanced',
331
	$btnadvdns . '&nbsp;' . 'Show advanced optionss'
332
));
333
334
$section->addInput(new Form_TextArea (
335
	'custom_options',
336
	'Custom options',
337
	$pconfig['custom_options']
338
))->setHelp('Enter any additional configuration parameters to add to the DNS Resolver configuration here, separated by a newline');
339
340
$form->add($section);
341
print($form);
342
343
print_info_box(sprintf(gettext("If the DNS Resolver is enabled, the DHCP".
344 2783e408 Renato Botelho
" service (if enabled) will automatically serve the LAN IP".
345
" address as a DNS server to DHCP clients so they will use".
346
" the DNS Resolver. If Forwarding, is enabled, the DNS Resolver will use the DNS servers".
347
" entered in %sSystem: General setup%s".
348
" or those obtained via DHCP or PPP on WAN if the &quot;Allow".
349
" DNS server list to be overridden by DHCP/PPP on WAN&quot;".
350 51c224bc sbeaver
" is checked."),'<a href="system.php">','</a>'));
351
?>
352
353
<script>
354
//<![CDATA[
355
events.push(function(){
356
357 96c18fe4 Stephen Beaver
	// If the enable checkbox is not checked, disable the next three checkboxes
358 51c224bc sbeaver
	function disableDHCP() {
359
		var hide = ! $('#enable').prop('checked');
360
361
		disableInput('port', hide);
362
		disableInput('active_interface', hide);
363
		disableInput('outgoing_interface', hide);
364
		disableInput('regdhcpstatic', hide);
365
		disableInput('dnssec', hide);
366
		disableInput('forwarding', hide);
367
		disableInput('regdhcp', hide);
368
		disableInput('regdhcpstatic', hide);
369
		disableInput('txtsupport', hide);
370
		disableInput('btnadvdns', hide);
371
	}
372
373
	// Make the ‘aditional options’ button a plain button, not a submit button
374
	$("#btnadvdns").prop('type','button');
375
376
	// Un-hide aditional  controls
377
	$("#btnadvdns").click(function() {
378
		hideInput('custom_options', false);
379
380
	});
381
382
	// When 'enable' is clicked, diable/enable the following three checkboxes
383
	$('#enable').click(function() {
384
		disableDHCP();
385
	});
386
387
	// On initial load
388
	hideInput('custom_options', true);
389
	disableDHCP();
390
391
});
392
//]]>
393
</script>
394
395
<div class="panel panel-default">
396 f17594c7 Sjon Hortensius
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Host Overrides")?></h2></div>
397 51c224bc sbeaver
	<div class="panel-body table-responsive">
398
		<table class="table table-striped table-hover table-condensed">
399
			<thead>
400 2783e408 Renato Botelho
				<tr>
401 51c224bc sbeaver
					<th><?=gettext("Host")?></th>
402
					<th><?=gettext("Domain")?></th>
403
					<th><?=gettext("IP")?></th>
404
					<th><?=gettext("Description")?></th>
405
					<th></th>
406 2783e408 Renato Botelho
				</tr>
407 51c224bc sbeaver
			</thead>
408
			<tbody>
409
<?php
410
$i = 0;
411
foreach ($a_hosts as $hostent):
412
?>
413 2783e408 Renato Botelho
				<tr>
414 51c224bc sbeaver
					<td>
415
						<?=strtolower($hostent['host'])?>
416
					</td>
417
					<td>
418
						<?=strtolower($hostent['domain'])?>
419
					</td>
420
					<td>
421
						<?=$hostent['ip']?>&nbsp;
422
					</td>
423
					<td>
424
						<?=htmlspecialchars($hostent['descr'])?>
425
					</td>
426
					<td>
427 49840447 PiBa-NL
						<a href="services_unbound_host_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
428 6f65dc19 Chris Buechler
						<a href="services_unbound.php?type=host&amp;act=del&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
429 51c224bc sbeaver
					</td>
430 2783e408 Renato Botelho
				</tr>
431 51c224bc sbeaver
432
<?php
433
	if ($hostent['aliases']['item'] && is_array($hostent['aliases']['item'])):
434
		foreach ($hostent['aliases']['item'] as $alias):
435
?>
436 2783e408 Renato Botelho
				<tr>
437 51c224bc sbeaver
					<td>
438
						<?=strtolower($alias['host'])?>
439
					</td>
440
					<td>
441
						<?=strtolower($alias['domain'])?>
442
					</td>
443
					<td>
444
						Alias for <?=$hostent['host'] ? $hostent['host'] . '.' . $hostent['domain'] : $hostent['domain']?>
445
					</td>
446
					<td>
447
						<?=htmlspecialchars($alias['description'])?>
448
					</td>
449
					<td>
450 6f65dc19 Chris Buechler
						<a href="services_unbound_host_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
451 51c224bc sbeaver
					</td>
452 2783e408 Renato Botelho
				</tr>
453 51c224bc sbeaver
<?php
454
		endforeach;
455
	endif;
456
	$i++;
457
endforeach;
458
?>
459
			</tbody>
460
		</table>
461
	</div>
462
</div>
463
464
<nav class="action-buttons">
465 6f65dc19 Chris Buechler
	<a href="services_unbound_host_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
466 51c224bc sbeaver
</nav>
467
468
<div class="panel panel-default">
469 f17594c7 Sjon Hortensius
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Domain Overrides")?></h2></div>
470 51c224bc sbeaver
	<div class="panel-body table-responsive">
471
		<table class="table table-striped table-hover table-condensed">
472
			<thead>
473 2783e408 Renato Botelho
				<tr>
474 51c224bc sbeaver
					<th><?=gettext("Domain")?></th>
475
					<th><?=gettext("IP")?></th>
476
					<th><?=gettext("Description")?></th>
477
					<th></th>
478 2783e408 Renato Botelho
				</tr>
479 51c224bc sbeaver
			</thead>
480
481
			<tbody>
482
<?php
483
$i = 0;
484
foreach ($a_domainOverrides as $doment):
485
?>
486 2783e408 Renato Botelho
				<tr>
487 51c224bc sbeaver
					<td>
488
						<?=strtolower($doment['domain'])?>&nbsp;
489
					</td>
490
					<td>
491
						<?=$doment['ip']?>&nbsp;
492
					</td>
493
					<td>
494
						<?=htmlspecialchars($doment['descr'])?>&nbsp;
495
					</td>
496
					<td>
497 9eb965f6 Stephen Beaver
						<a href="services_unbound_domainoverride_edit.php?id=<?=$i?>" class="btn btn-xs btn-info"><?=gettext('Edit')?></a>
498
						<a href="services_unbound.php?act=del&amp;type=doverride&amp;id=<?=$i?>" class="btn btn-xs btn-danger"><?=gettext('Delete')?></a>
499 51c224bc sbeaver
					</td>
500 2783e408 Renato Botelho
				</tr>
501 51c224bc sbeaver
<?php
502
	$i++;
503
endforeach;
504
?>
505
			</tbody>
506
		</table>
507
	</div>
508
</div>
509
510
<nav class="action-buttons">
511 9eb965f6 Stephen Beaver
	<a href="services_unbound_domainoverride_edit.php" class="btn btn-sm btn-success"><?=gettext('Add')?></a>
512 51c224bc sbeaver
</nav>
513 6f65dc19 Chris Buechler
<?php include("foot.inc");