Project

General

Profile

Download (27.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * system.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2023 Rubicon Communications, LLC (Netgate)
9
 * All rights reserved.
10
 *
11
 * originally based on m0n0wall (http://m0n0.ch/wall)
12
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
 * All rights reserved.
14
 *
15
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18
 *
19
 * http://www.apache.org/licenses/LICENSE-2.0
20
 *
21
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26
 */
27

    
28
##|+PRIV
29
##|*IDENT=page-system-generalsetup
30
##|*NAME=System: General Setup
31
##|*DESCR=Allow access to the 'System: General Setup' page.
32
##|*MATCH=system.php*
33
##|-PRIV
34

    
35
require_once("guiconfig.inc");
36
require_once("functions.inc");
37
require_once("filter.inc");
38
require_once("shaper.inc");
39
require_once("system.inc");
40

    
41
$pconfig['hostname'] = $config['system']['hostname'];
42
$pconfig['domain'] = $config['system']['domain'];
43
$pconfig['dnsserver'] = $config['system']['dnsserver'];
44

    
45
$arr_gateways = return_gateways_array();
46

    
47
// set default columns to two if unset
48
if (!isset($config['system']['webgui']['dashboardcolumns'])) {
49
	config_set_path('system/webgui/dashboardcolumns', 2);
50
}
51

    
52
// set default language if unset
53
if (!isset($config['system']['language'])) {
54
	config_set_path('system/language', g_get('language'));
55
}
56

    
57
$dnshost_counter = 1;
58

    
59
while (isset($config["system"]["dns{$dnshost_counter}host"])) {
60
	$pconfig_dnshost_counter = $dnshost_counter - 1;
61
	$pconfig["dnshost{$pconfig_dnshost_counter}"] = $config["system"]["dns{$dnshost_counter}host"];
62
	$dnshost_counter++;
63
}
64

    
65
$dnsgw_counter = 1;
66

    
67
while (isset($config["system"]["dns{$dnsgw_counter}gw"])) {
68
	$pconfig_dnsgw_counter = $dnsgw_counter - 1;
69
	$pconfig["dnsgw{$pconfig_dnsgw_counter}"] = $config["system"]["dns{$dnsgw_counter}gw"];
70
	$dnsgw_counter++;
71
}
72

    
73
$pconfig['dnsallowoverride'] = isset($config['system']['dnsallowoverride']);
74
$pconfig['timezone'] = $config['system']['timezone'];
75
$pconfig['timeservers'] = $config['system']['timeservers'];
76
$pconfig['language'] = $config['system']['language'];
77
$pconfig['webguicss'] = $config['system']['webgui']['webguicss'];
78
$pconfig['logincss'] = $config['system']['webgui']['logincss'];
79
$pconfig['webguifixedmenu'] = $config['system']['webgui']['webguifixedmenu'];
80
$pconfig['dashboardcolumns'] = $config['system']['webgui']['dashboardcolumns'];
81
$pconfig['interfacessort'] = isset($config['system']['webgui']['interfacessort']);
82
$pconfig['webguileftcolumnhyper'] = isset($config['system']['webgui']['webguileftcolumnhyper']);
83
$pconfig['disablealiaspopupdetail'] = isset($config['system']['webgui']['disablealiaspopupdetail']);
84
$pconfig['dashboardavailablewidgetspanel'] = isset($config['system']['webgui']['dashboardavailablewidgetspanel']);
85
$pconfig['systemlogsfilterpanel'] = isset($config['system']['webgui']['systemlogsfilterpanel']);
86
$pconfig['systemlogsmanagelogpanel'] = isset($config['system']['webgui']['systemlogsmanagelogpanel']);
87
$pconfig['statusmonitoringsettingspanel'] = isset($config['system']['webgui']['statusmonitoringsettingspanel']);
88
$pconfig['webguihostnamemenu'] = $config['system']['webgui']['webguihostnamemenu'];
89
$pconfig['dnslocalhost'] = $config['system']['dnslocalhost'];
90
//$pconfig['dashboardperiod'] = isset($config['widgets']['period']) ? $config['widgets']['period']:"10";
91
$pconfig['roworderdragging'] = isset($config['system']['webgui']['roworderdragging']);
92
$pconfig['loginshowhost'] = isset($config['system']['webgui']['loginshowhost']);
93
$pconfig['requirestatefilter'] = isset($config['system']['webgui']['requirestatefilter']);
94
$pconfig['requirefirewallinterface'] = isset($config['system']['webgui']['requirefirewallinterface']);
95

    
96
if (!$pconfig['timezone']) {
97
	if (isset($g['default_timezone']) && !empty(g_get('default_timezone'))) {
98
		$pconfig['timezone'] = g_get('default_timezone');
99
	} else {
100
		$pconfig['timezone'] = "Etc/UTC";
101
	}
102
}
103

    
104
if (!$pconfig['timeservers']) {
105
	$pconfig['timeservers'] = "pool.ntp.org";
106
}
107

    
108
$changedesc = gettext("System") . ": ";
109
$changecount = 0;
110

    
111
function is_timezone($elt) {
112
	return !preg_match("/\/$/", $elt);
113
}
114

    
115
if ($pconfig['timezone'] <> $_POST['timezone']) {
116
	filter_pflog_start();
117
}
118

    
119
$timezonelist = system_get_timezone_list();
120
$timezonedesc = $timezonelist;
121

    
122
/*
123
 * Etc/GMT entries work the opposite way to what people expect.
124
 * Ref: https://github.com/eggert/tz/blob/master/etcetera and Redmine issue 7089
125
 * Add explanatory text to entries like:
126
 * Etc/GMT+1 and Etc/GMT-1
127
 * but not:
128
 * Etc/GMT or Etc/GMT+0
129
 */
130
foreach ($timezonedesc as $idx => $desc) {
131
	if (substr($desc, 0, 7) != "Etc/GMT" || substr($desc, 8, 1) == "0") {
132
		continue;
133
	}
134

    
135
	$direction = substr($desc, 7, 1);
136

    
137
	switch ($direction) {
138
	case '-':
139
		$direction_str = gettext('AHEAD of');
140
		break;
141
	case '+':
142
		$direction_str = gettext('BEHIND');
143
		break;
144
	default:
145
		continue 2;
146
	}
147

    
148
	$hr_offset = substr($desc, 8);
149
	$timezonedesc[$idx] = $desc . " " .
150
	    sprintf(ngettext('(%1$s hour %2$s GMT)', '(%1$s hours %2$s GMT)', intval($hr_offset)), $hr_offset, $direction_str);
151
}
152

    
153
$multiwan = 0;
154
$multiwan6 = 0;
155
foreach ($arr_gateways as $gw) {
156
	if ($gw['ipprotocol'] == 'inet') {
157
		$multiwan++;
158
		if ($multiwan > 1) {
159
			break;
160
		}
161
	} else {
162
		$multiwan6++;
163
		if ($multiwan6 > 1) {
164
			break;
165
		}
166
	}
167
}
168

    
169
if ($_POST) {
170

    
171
	$changecount++;
172

    
173
	unset($input_errors);
174
	$pconfig = $_POST;
175

    
176
	/* input validation */
177
	$reqdfields = explode(" ", "hostname domain");
178
	$reqdfieldsn = array(gettext("Hostname"), gettext("Domain"));
179

    
180
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
181

    
182
	if ($_POST['hostname']) {
183
		if (!is_hostname($_POST['hostname'])) {
184
			$input_errors[] = gettext("The hostname can only contain the characters A-Z, 0-9 and '-'. It may not start or end with '-'.");
185
		} else {
186
			if (!is_unqualified_hostname($_POST['hostname'])) {
187
				$input_errors[] = gettext("A valid hostname is specified, but the domain name part should be omitted");
188
			}
189
		}
190
	}
191
	if ($_POST['domain'] && (!is_domain($_POST['domain'], false, false))) {
192
		$input_errors[] = gettext("The domain may only contain the characters a-z, 0-9, '-' and '.', and it cannot start with '.' or '-'.");
193
	}
194
	validate_webguicss_field($input_errors, $_POST['webguicss']);
195
	validate_webguifixedmenu_field($input_errors, $_POST['webguifixedmenu']);
196
	validate_webguihostnamemenu_field($input_errors, $_POST['webguihostnamemenu']);
197
	validate_dashboardcolumns_field($input_errors, $_POST['dashboardcolumns']);
198

    
199
	$dnslist = $ignore_posted_dnsgw = array();
200

    
201
	$dnscounter = 0;
202
	$dnsname = "dns{$dnscounter}";
203

    
204
	while (isset($_POST[$dnsname])) {
205
		$dnsgwname = "dnsgw{$dnscounter}";
206
		$dnshostname = "dnshost{$dnscounter}";
207
		$dnslist[] = $_POST[$dnsname];
208

    
209
		if (($_POST[$dnsname] && !is_ipaddr($_POST[$dnsname]))) {
210
			$input_errors[] = sprintf(gettext("A valid IP address must be specified for DNS server %s."), $dnscounter+1);
211
		} else {
212
			if (!empty($_POST[$dnshostname]) && !is_hostname($_POST[$dnshostname])) {
213
				$input_errors[] = sprintf(gettext('The hostname provided for DNS server "%1$s" is not valid.'), $_POST[$dnsname]);
214
			}
215
			if (($_POST[$dnsgwname] <> "") && ($_POST[$dnsgwname] <> "none")) {
216
				// A real gateway has been selected.
217
				if (is_ipaddr($_POST[$dnsname])) {
218
					if ((is_ipaddrv4($_POST[$dnsname])) && (validate_address_family($_POST[$dnsname], $_POST[$dnsgwname]) === false)) {
219
						$input_errors[] = sprintf(gettext('The IPv6 gateway "%1$s" can not be specified for IPv4 DNS server "%2$s".'), $_POST[$dnsgwname], $_POST[$dnsname]);
220
					}
221
					if ((is_ipaddrv6($_POST[$dnsname])) && (validate_address_family($_POST[$dnsname], $_POST[$dnsgwname]) === false)) {
222
						$input_errors[] = sprintf(gettext('The IPv4 gateway "%1$s" can not be specified for IPv6 DNS server "%2$s".'), $_POST[$dnsgwname], $_POST[$dnsname]);
223
					}
224
				} else {
225
					// The user selected a gateway but did not provide a DNS address. Be nice and set the gateway back to "none".
226
					$ignore_posted_dnsgw[$dnsgwname] = true;
227
				}
228
			}
229
		}
230
		$dnscounter++;
231
		$dnsname = "dns{$dnscounter}";
232
	}
233

    
234
	if (count(array_filter($dnslist)) != count(array_unique(array_filter($dnslist)))) {
235
		$input_errors[] = gettext('Each configured DNS server must have a unique IP address. Remove the duplicated IP.');
236
	}
237

    
238
	$dnscounter = 0;
239
	$dnsname = "dns{$dnscounter}";
240

    
241
	$direct_networks_list = explode(" ", filter_get_direct_networks_list());
242
	while (isset($_POST[$dnsname])) {
243
		$dnsgwname = "dnsgw{$dnscounter}";
244
		if ($_POST[$dnsgwname] && ($_POST[$dnsgwname] <> "none")) {
245
			foreach ($direct_networks_list as $direct_network) {
246
				if (ip_in_subnet($_POST[$dnsname], $direct_network)) {
247
					$input_errors[] = sprintf(gettext("A gateway cannot be specified for %s because that IP address is part of a directly connected subnet %s. To use that nameserver, change its Gateway to `none`."), $_POST[$dnsname], $direct_network);
248
				}
249
			}
250
		}
251
		$dnscounter++;
252
		$dnsname = "dns{$dnscounter}";
253
	}
254

    
255
	# it's easy to have a little too much whitespace in the field, clean it up for the user before processing.
256
	$_POST['timeservers'] = preg_replace('/[[:blank:]]+/', ' ', $_POST['timeservers']);
257
	$_POST['timeservers'] = trim($_POST['timeservers']);
258
	foreach (explode(' ', $_POST['timeservers']) as $ts) {
259
		if (!is_domain($ts) && (!is_ipaddr($ts))) {
260
			$input_errors[] = gettext("NTP Time Server names must be valid domain names, IPv4 addresses, or IPv6 addresses");
261
		}
262
	}
263

    
264
	if ($input_errors) {
265
		// Put the user-entered list back into place so it will be redisplayed for correction.
266
		$pconfig['dnsserver'] = $dnslist;
267
	} else {
268
		// input validation passed, so we can proceed with removing static routes for dead DNS gateways
269
		if (is_array($config['system']['dnsserver'])) {
270
		  	$dns_servers_arr = $config['system']['dnsserver'];
271
	 		foreach ($dns_servers_arr as $arr_index => $this_dnsserver) {
272
				$i = (int)$arr_index + 1;
273
				$this_dnsgw = config_get_path("system/dns{$i}gw");
274
				unset($gatewayip);
275
				unset($inet6);
276
				if ((!empty($this_dnsgw)) && ($this_dnsgw != 'none') && (!empty($this_dnsserver))) {
277
					$gatewayip = lookup_gateway_ip_by_name($this_dnsgw);
278
					$inet6 = is_ipaddrv6($gatewayip) ? '-inet6 ' : '';
279
					mwexec("/sbin/route -q delete -host {$inet6}{$this_dnsserver} " . escapeshellarg($gatewayip));
280
				}
281
			}
282
		}
283

    
284
		update_if_changed("hostname", $config['system']['hostname'], $_POST['hostname']);
285
		update_if_changed("domain", $config['system']['domain'], $_POST['domain']);
286
		update_if_changed("timezone", $config['system']['timezone'], $_POST['timezone']);
287
		update_if_changed("NTP servers", $config['system']['timeservers'], strtolower($_POST['timeservers']));
288

    
289
		if ($_POST['language'] && $_POST['language'] != $config['system']['language']) {
290
			config_set_path('system/language', $_POST['language']);
291
			set_language();
292
		}
293

    
294
		config_del_path('system/webgui/interfacessort');
295
		config_set_path('system/webgui/interfacessort', $_POST['interfacessort'] ? true : false);
296

    
297
		config_del_path('system/webgui/webguileftcolumnhyper');
298
		config_set_path('system/webgui/webguileftcolumnhyper', $_POST['webguileftcolumnhyper'] ? true : false);
299

    
300
		config_del_path('system/webgui/disablealiaspopupdetail');
301
		config_set_path('system/webgui/disablealiaspopupdetail', $_POST['disablealiaspopupdetail'] ? true : false);
302

    
303
		config_del_path('system/webgui/dashboardavailablewidgetspanel');
304
		config_set_path('system/webgui/dashboardavailablewidgetspanel', $_POST['dashboardavailablewidgetspanel'] ? true : false);
305

    
306
		config_del_path('system/webgui/systemlogsfilterpanel');
307
		config_set_path('system/webgui/systemlogsfilterpanel', $_POST['systemlogsfilterpanel'] ? true : false);
308

    
309
		config_del_path('system/webgui/systemlogsmanagelogpanel');
310
		config_set_path('system/webgui/systemlogsmanagelogpanel', $_POST['systemlogsmanagelogpanel'] ? true : false);
311

    
312
		config_del_path('system/webgui/statusmonitoringsettingspanel');
313
		config_set_path('system/webgui/statusmonitoringsettingspanel', $_POST['statusmonitoringsettingspanel'] ? true : false);
314

    
315
//		if ($_POST['dashboardperiod']) {
316
//			$config['widgets']['period'] = $_POST['dashboardperiod'];
317
//		}
318

    
319
		if ($_POST['webguicss']) {
320
			config_set_path('system/webgui/webguicss', $_POST['webguicss']);
321
		} else {
322
			config_del_path('system/webgui/webguicss');
323
		}
324

    
325
		config_set_path('system/webgui/roworderdragging', $_POST['roworderdragging'] ? true:false);
326

    
327
		if ($_POST['logincss']) {
328
			config_set_path('system/webgui/logincss', $_POST['logincss']);
329
		} else {
330
			config_del_path('system/webgui/logincss');
331
		}
332

    
333
		config_set_path('system/webgui/loginshowhost', $_POST['loginshowhost'] ? true:false);
334

    
335
		if ($_POST['webguifixedmenu']) {
336
			config_set_path('system/webgui/webguifixedmenu', $_POST['webguifixedmenu']);
337
		} else {
338
			config_del_path('system/webgui/webguifixedmenu');
339
		}
340

    
341
		if ($_POST['webguihostnamemenu']) {
342
			config_set_path('system/webgui/webguihostnamemenu', $_POST['webguihostnamemenu']);
343
		} else {
344
			config_del_path('system/webgui/webguihostnamemenu');
345
		}
346

    
347
		if ($_POST['dashboardcolumns']) {
348
			config_set_path('system/webgui/dashboardcolumns', $_POST['dashboardcolumns']);
349
		} else {
350
			config_del_path('system/webgui/dashboardcolumns');
351
		}
352

    
353
		config_set_path('system/webgui/requirestatefilter', $_POST['requirestatefilter'] ? true : false);
354
		config_set_path('system/webgui/requirefirewallinterface', $_POST['requirefirewallinterface'] ? true : false);
355

    
356
		/* XXX - billm: these still need updating after figuring out how to check if they actually changed */
357
		$olddnsservers = $config['system']['dnsserver'];
358
		config_del_path('system/dnsserver');
359

    
360
		$dnscounter = 0;
361
		$dnsname = "dns{$dnscounter}";
362

    
363
		while (isset($_POST[$dnsname])) {
364
			if ($_POST[$dnsname]) {
365
				$config['system']['dnsserver'][] = $_POST[$dnsname];
366
			}
367
			$dnscounter++;
368
			$dnsname = "dns{$dnscounter}";
369
		}
370

    
371
		// Remember the new list for display also.
372
		$pconfig['dnsserver'] = $config['system']['dnsserver'];
373

    
374
		$olddnsallowoverride = $config['system']['dnsallowoverride'];
375

    
376
		config_del_path('system/dnsallowoverride');
377
		config_set_path('system/dnsallowoverride', $_POST['dnsallowoverride'] ? true : false);
378

    
379
		if ($_POST['dnslocalhost']) {
380
			config_set_path('system/dnslocalhost', $_POST['dnslocalhost']);
381
		} else {
382
			config_del_path('system/dnslocalhost');
383
		}
384

    
385
		/* which interface should the dns servers resolve through? */
386
		$dnscounter = 0;
387
		// The $_POST array key of the DNS IP (starts from 0)
388
		$dnsname = "dns{$dnscounter}";
389
		$outdnscounter = 0;
390
		while (isset($_POST[$dnsname])) {
391
			// The $_POST array key of the corresponding gateway (starts from 0)
392
			$dnsgwname = "dnsgw{$dnscounter}";
393
			$dnshostname = "dnshost{$dnscounter}";
394
			// The numbering of DNS GW/host entries in the config starts from 1
395
			$dnsgwconfigcounter = $dnscounter + 1;
396
			$dnshostconfigcounter = $dnscounter + 1;
397
			// So this is the array key of the DNS GW entry in $config['system']
398
			$dnsgwconfigname = "dns{$dnsgwconfigcounter}gw";
399
			$dnshostconfigname = "dns{$dnshostconfigcounter}host";
400

    
401
			$olddnsgwname = config_get_path("system/{$dnsgwconfigname}");
402
			$olddnshostname = config_get_path("system/{$dnshostconfigname}");
403

    
404
			if ($ignore_posted_dnsgw[$dnsgwname]) {
405
				$thisdnsgwname = "none";
406
			} else {
407
				$thisdnsgwname = $pconfig[$dnsgwname];
408
			}
409
			$thisdnshostname = $pconfig[$dnshostname];
410

    
411
			// "Blank" out the settings for this index, then we set them below using the "outdnscounter" index.
412
			$config['system'][$dnsgwconfigname] = "none";
413
			$pconfig[$dnsgwname] = "none";
414
			$config['system'][$dnshostconfigname] = "";
415
			$pconfig[$dnshostname] = "";
416
			$pconfig[$dnsname] = "";
417

    
418
			if ($_POST[$dnsname]) {
419
				// Only the non-blank DNS servers were put into the config above.
420
				// So we similarly only add the corresponding gateways sequentially to the config (and to pconfig), as we find non-blank DNS servers.
421
				// This keeps the DNS server IP and corresponding gateway "lined up" when the user blanks out a DNS server IP in the middle of the list.
422

    
423
				// The $pconfig array key of the DNS IP (starts from 0)
424
				$outdnsname = "dns{$outdnscounter}";
425
				// The $pconfig array key of the corresponding gateway (starts from 0)
426
				$outdnsgwname = "dnsgw{$outdnscounter}";
427
				// The $pconfig array key of the corresponding hostname (starts from 0)
428
				$outdnshostname = "dnshost{$outdnscounter}";
429

    
430
				// The numbering of DNS GW/host entries in the config starts from 1
431
				$outdnsgwconfigcounter = $outdnscounter + 1;
432
				$outdnshostconfigcounter = $outdnscounter + 1;
433
				// So this is the array key of the output DNS GW entry in $config['system']
434
				$outdnsgwconfigname = "dns{$outdnsgwconfigcounter}gw";
435
				$outdnshostconfigname = "dns{$outdnshostconfigcounter}host";
436

    
437
				$pconfig[$outdnsname] = $_POST[$dnsname];
438
				if ($_POST[$dnsgwname]) {
439
					$config['system'][$outdnsgwconfigname] = $thisdnsgwname;
440
					$pconfig[$outdnsgwname] = $thisdnsgwname;
441
				} else {
442
					// Note: when no DNS GW name is chosen, the entry is set to "none", so actually this case never happens.
443
					config_del_path("system/{$outdnsgwconfigname}");
444
					$pconfig[$outdnsgwname] = "";
445
				}
446
				if ($_POST[$dnshostname]) {
447
					$config['system'][$outdnshostconfigname] = $thisdnshostname;
448
					$pconfig[$outdnshostname] = $thisdnshostname;
449
				} else {
450
					// Note: when no DNS hostname is chosen, unset the value.
451
					config_del_path("system/{$outdnshostconfigname}");
452
					$pconfig[$outdnshostname] = "";
453
				}
454
				$outdnscounter++;
455
			}
456

    
457
			$dnscounter++;
458
			// The $_POST array key of the DNS IP (starts from 0)
459
			$dnsname = "dns{$dnscounter}";
460
		}
461

    
462
		// clean up dnsgw orphans
463
		$oldgwcounter = 1;
464
		$olddnsgwconfigname = "dns{$oldgwcounter}gw";
465
		while (isset($config['system'][$olddnsgwconfigname])) {
466
			if (empty($config['system']['dnsserver'][$oldgwcounter - 1])) {
467
				config_del_path("system/{$olddnsgwconfigname}");
468
			}
469
			$oldgwcounter++;
470
			$olddnsgwconfigname = "dns{$oldgwcounter}gw";
471
		}
472
		unset($oldgwcounter);
473
		unset($olddnsgwconfigname);
474

    
475
		if ($changecount > 0) {
476
			write_config($changedesc);
477
		}
478

    
479
		$changes_applied = true;
480
		$retval = 0;
481
		$retval |= system_hostname_configure();
482
		$retval |= system_hosts_generate();
483
		$retval |= system_resolvconf_generate();
484
		if (isset($config['dnsmasq']['enable'])) {
485
			$retval |= services_dnsmasq_configure();
486
		} elseif (isset($config['unbound']['enable'])) {
487
			$retval |= services_unbound_configure();
488
		}
489
		$retval |= system_timezone_configure();
490
		$retval |= system_ntp_configure();
491

    
492
		if ($olddnsallowoverride != $config['system']['dnsallowoverride']) {
493
			$retval |= send_event("service reload dns");
494
		}
495

    
496
		// Reload the filter - plugins might need to be run.
497
		$retval |= filter_configure();
498
	}
499

    
500
	unset($ignore_posted_dnsgw);
501
}
502

    
503
$pgtitle = array(gettext("System"), gettext("General Setup"));
504
include("head.inc");
505

    
506
if ($input_errors) {
507
	print_input_errors($input_errors);
508
}
509

    
510
if ($changes_applied) {
511
	print_apply_result_box($retval);
512
}
513
?>
514
<div id="container">
515
<?php
516

    
517
$form = new Form;
518
$section = new Form_Section('System');
519
$section->addInput(new Form_Input(
520
	'hostname',
521
	'*Hostname',
522
	'text',
523
	$pconfig['hostname'],
524
	['placeholder' => 'pfSense']
525
))->setHelp('Name of the firewall host, without domain part.');
526

    
527
$section->addInput(new Form_Input(
528
	'domain',
529
	'*Domain',
530
	'text',
531
	$pconfig['domain'],
532
	['placeholder' => 'home.arpa, example.com, home, office, private, etc.']
533
))->setHelp('Domain name for the firewall.%1$s%1$s' .
534
	'Do not end the domain name with \'.local\' as the final part (Top Level Domain, TLD). ' .
535
	'The \'local\' TLD is %2$swidely used%3$s by mDNS (e.g. Avahi, Bonjour, Rendezvous, Airprint, Airplay) ' .
536
	'and some Windows systems and networked devices. ' .
537
	'These will not network correctly if the router uses \'local\' as its TLD. ' .
538
	'Alternatives such as \'home.arpa\', \'local.lan\', or \'mylocal\' are safe.',
539
	'<br/>',
540
	'<a target="_blank" href="https://www.unbound.net/pipermail/unbound-users/2011-March/001735.html">',
541
	'</a>'
542
);
543

    
544
$form->add($section);
545

    
546
$section = new Form_Section('DNS Server Settings');
547

    
548
if (!is_array($pconfig['dnsserver'])) {
549
	$pconfig['dnsserver'] = array();
550
}
551

    
552
$dnsserver_count = count($pconfig['dnsserver']);
553
$dnsserver_num = 0;
554
$dnsserver_help = gettext("Address") . '<br/>' . gettext("Enter IP addresses to be used by the system for DNS resolution.") . " " .
555
	gettext("These are also used for the DHCP service, DNS Forwarder and DNS Resolver when it has DNS Query Forwarding enabled.");
556
$dnshost_help = gettext("Hostname") . '<br/>' . gettext("Enter the DNS Server Hostname for TLS Verification in the DNS Resolver (optional).");
557
$dnsgw_help = gettext("Gateway") . '<br/>'. gettext("Optionally select the gateway for each DNS server.") . " " .
558
	gettext("When using multiple WAN connections there should be at least one unique DNS server per gateway.");
559

    
560
// If there are no DNS servers, make an empty entry for initial display.
561
if ($dnsserver_count == 0) {
562
	$pconfig['dnsserver'][] = '';
563
}
564

    
565
foreach ($pconfig['dnsserver'] as $dnsserver) {
566

    
567
	$is_last_dnsserver = (($dnsserver_num == $dnsserver_count - 1) || $dnsserver_count == 0);
568
	$group = new Form_Group($dnsserver_num == 0 ? 'DNS Servers':'');
569
	$group->addClass('repeatable');
570

    
571
	$group->add(new Form_Input(
572
		'dns' . $dnsserver_num,
573
		'DNS Server',
574
		'text',
575
		$dnsserver
576
	))->setHelp(($is_last_dnsserver) ? $dnsserver_help:null);
577

    
578
	$group->add(new Form_Input(
579
		'dnshost' . $dnsserver_num,
580
		'DNS Hostname',
581
		'text',
582
		$pconfig['dnshost' . $dnsserver_num]
583
	))->setHelp(($is_last_dnsserver) ? $dnshost_help:null);
584

    
585
	if (($multiwan > 1) || ($multiwan6 > 1)) {
586
		$options = array('none' => 'none');
587

    
588
		foreach ($arr_gateways as $gwname => $gwitem) {
589
			if ((is_ipaddrv4(lookup_gateway_ip_by_name($pconfig[$dnsgw])) && (is_ipaddrv6($gwitem['gateway'])))) {
590
				continue;
591
			}
592

    
593
			if ((is_ipaddrv6(lookup_gateway_ip_by_name($pconfig[$dnsgw])) && (is_ipaddrv4($gwitem['gateway'])))) {
594
				continue;
595
			}
596

    
597
			$options[$gwname] = $gwname.' - '.$gwitem['friendlyiface'].' - '.$gwitem['gateway'];
598
		}
599

    
600
		$group->add(new Form_Select(
601
			'dnsgw' . $dnsserver_num,
602
			'Gateway',
603
			$pconfig['dnsgw' . $dnsserver_num],
604
			$options
605
		))->setWidth(4)->setHelp(($is_last_dnsserver) ? $dnsgw_help:null);
606
	}
607

    
608
	$group->add(new Form_Button(
609
		'deleterow' . $dnsserver_num,
610
		'Delete',
611
		null,
612
		'fa-trash'
613
	))->setWidth(2)->addClass('btn-warning');
614

    
615
	$section->add($group);
616
	$dnsserver_num++;
617
}
618

    
619
$section->addInput(new Form_Button(
620
	'addrow',
621
	'Add DNS Server',
622
	null,
623
	'fa-plus'
624
))->addClass('btn-success addbtn');
625

    
626
$section->addInput(new Form_Checkbox(
627
	'dnsallowoverride',
628
	'DNS Server Override',
629
	'Allow DNS server list to be overridden by DHCP/PPP on WAN or remote OpenVPN server',
630
	$pconfig['dnsallowoverride']
631
))->setHelp('If this option is set, %s will use DNS servers '.
632
	'assigned by a DHCP/PPP server on WAN or a remote OpenVPN server (if Pull DNS ' .
633
	'option is enabled) for its own purposes (including the DNS Forwarder/DNS Resolver). '.
634
        'However, they will not be assigned to DHCP clients.', g_get('product_label'));
635

    
636
$section->addInput(new Form_Select(
637
	'dnslocalhost',
638
	'DNS Resolution Behavior',
639
	$pconfig['dnslocalhost'],
640
	array(
641
		''       => 'Use local DNS (127.0.0.1), fall back to remote DNS Servers (Default)',
642
		'local'  => 'Use local DNS (127.0.0.1), ignore remote DNS Servers',
643
		'remote' => 'Use remote DNS Servers, ignore local DNS',
644
	)
645
))->setHelp('By default the firewall will use local DNS service (127.0.0.1, DNS '.
646
	'Resolver or Forwarder) as the first DNS server when possible, and it '.
647
	'will fall back to remote DNS servers otherwise. Use this option to '.
648
	'choose alternate behaviors.');
649

    
650
$form->add($section);
651

    
652
$section = new Form_Section('Localization');
653

    
654
$section->addInput(new Form_Select(
655
	'timezone',
656
	'*Timezone',
657
	$pconfig['timezone'],
658
	array_combine($timezonelist, $timezonedesc)
659
))->setHelp('Select a geographic region name (Continent/Location) to determine the timezone for the firewall. %1$s' .
660
	'Choose a special or "Etc" zone only in cases where the geographic zones do not properly handle the clock offset required for this firewall.', '<br/>');
661

    
662
$section->addInput(new Form_Input(
663
	'timeservers',
664
	'Timeservers',
665
	'text',
666
	$pconfig['timeservers']
667
))->setHelp('Use a space to separate multiple hosts (only one required). '.
668
	'Remember to set up at least one DNS server if a host name is entered here!');
669

    
670
$section->addInput(new Form_Select(
671
	'language',
672
	'*Language',
673
	$pconfig['language'],
674
	get_locale_list()
675
))->setHelp('Choose a language for the webConfigurator');
676

    
677
$form->add($section);
678

    
679
$section = new Form_Section('webConfigurator');
680

    
681
gen_webguicss_field($section, $pconfig['webguicss']);
682
gen_webguifixedmenu_field($section, $pconfig['webguifixedmenu']);
683
gen_webguihostnamemenu_field($section, $pconfig['webguihostnamemenu']);
684
gen_dashboardcolumns_field($section, $pconfig['dashboardcolumns']);
685
gen_interfacessort_field($section, $pconfig['interfacessort']);
686
gen_associatedpanels_fields(
687
	$section,
688
	$pconfig['dashboardavailablewidgetspanel'],
689
	$pconfig['systemlogsfilterpanel'],
690
	$pconfig['systemlogsmanagelogpanel'],
691
	$pconfig['statusmonitoringsettingspanel']);
692
gen_requirestatefilter_field($section, $pconfig['requirestatefilter']);
693
gen_requirefirewallinterface_field($section, $pconfig['requirefirewallinterface']);
694
gen_webguileftcolumnhyper_field($section, $pconfig['webguileftcolumnhyper']);
695
gen_disablealiaspopupdetail_field($section, $pconfig['disablealiaspopupdetail']);
696

    
697
$section->addInput(new Form_Checkbox(
698
	'roworderdragging',
699
	'Disable dragging',
700
	'Disable dragging of firewall/NAT rules',
701
	$pconfig['roworderdragging']
702
))->setHelp('Disables dragging rows to allow selecting and copying row contents and avoid accidental changes.');
703

    
704
$section->addInput(new Form_Select(
705
	'logincss',
706
	'Login page color',
707
	$pconfig['logincss'],
708
	["1e3f75;" => gettext("Dark Blue"), "003300" => gettext("Dark green"), "770101" => gettext("Crimson red"),
709
	 "4b1263" => gettext("Purple"), "424142" => gettext("Gray"), "333333" => gettext("Dark gray"),
710
	 "000000" => gettext("Black"), "633215" => gettext("Dark brown"), "bf7703" => gettext("Brown"), 
711
	 "008000" => gettext("Green"), "007faa" => gettext("Light Blue"), "dc2a2a" => gettext("Red"),
712
	 "9b59b6" => gettext("Violet")]
713
))->setHelp('Choose a color for the login page');
714

    
715
$section->addInput(new Form_Checkbox(
716
	'loginshowhost',
717
	'Login hostname',
718
	'Show hostname on login banner',
719
	$pconfig['loginshowhost']
720
));
721
/*
722
$section->addInput(new Form_Input(
723
	'dashboardperiod',
724
	'Dashboard update period',
725
	'number',
726
	$pconfig['dashboardperiod'],
727
	['min' => '5', 'max' => '600']
728
))->setHelp('Time in seconds between dashboard widget updates. Small values cause ' .
729
			'more frequent updates but increase the load on the web server. ' .
730
			'Minimum is 5 seconds, maximum 600 seconds');
731
*/
732
$form->add($section);
733

    
734
print $form;
735

    
736
$csswarning = sprintf(gettext("%sUser-created themes are unsupported, use at your own risk."), "<br />");
737

    
738
?>
739
</div>
740

    
741
<script type="text/javascript">
742
//<![CDATA[
743
events.push(function() {
744

    
745
	function setThemeWarning() {
746
		if ($('#webguicss').val().startsWith("pfSense")) {
747
			$('#csstxt').html("").addClass("text-default");
748
		} else {
749
			$('#csstxt').html("<?=$csswarning?>").addClass("text-danger");
750
		}
751
	}
752

    
753
	$('#webguicss').change(function() {
754
		setThemeWarning();
755
	});
756

    
757
	setThemeWarning();
758

    
759
	// Suppress "Delete row" button if there are fewer than two rows
760
	checkLastRow();
761
});
762
//]]>
763
</script>
764

    
765
<?php
766
include("foot.inc");
767
?>
(184-184/228)