Project

General

Profile

Download (26.8 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-2022 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['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

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

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

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

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

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

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

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

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

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

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

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

    
168
if ($_POST) {
169

    
170
	$changecount++;
171

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

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

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

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

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

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

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

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

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

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

    
240
	$direct_networks_list = explode(" ", filter_get_direct_networks_list());
241
	while (isset($_POST[$dnsname])) {
242
		$dnsgwname = "dnsgw{$dnscounter}";
243
		if ($_POST[$dnsgwname] && ($_POST[$dnsgwname] <> "none")) {
244
			foreach ($direct_networks_list as $direct_network) {
245
				if (ip_in_subnet($_POST[$dnsname], $direct_network)) {
246
					$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);
247
				}
248
			}
249
		}
250
		$dnscounter++;
251
		$dnsname = "dns{$dnscounter}";
252
	}
253

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
358
		$dnscounter = 0;
359
		$dnsname = "dns{$dnscounter}";
360

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

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

    
372
		$olddnsallowoverride = $config['system']['dnsallowoverride'];
373

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

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

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

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

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

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

    
416
			if ($_POST[$dnsname]) {
417
				// Only the non-blank DNS servers were put into the config above.
418
				// So we similarly only add the corresponding gateways sequentially to the config (and to pconfig), as we find non-blank DNS servers.
419
				// 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.
420

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

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

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

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

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

    
473
		if ($changecount > 0) {
474
			write_config($changedesc);
475
		}
476

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

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

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

    
498
	unset($ignore_posted_dnsgw);
499
}
500

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

    
504
if ($input_errors) {
505
	print_input_errors($input_errors);
506
}
507

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

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

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

    
540
$form->add($section);
541

    
542
$section = new Form_Section('DNS Server Settings');
543

    
544
if (!is_array($pconfig['dnsserver'])) {
545
	$pconfig['dnsserver'] = array();
546
}
547

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

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

    
561
foreach ($pconfig['dnsserver'] as $dnsserver) {
562

    
563
	$is_last_dnsserver = (($dnsserver_num == $dnsserver_count - 1) || $dnsserver_count == 0);
564
	$group = new Form_Group($dnsserver_num == 0 ? 'DNS Servers':'');
565
	$group->addClass('repeatable');
566

    
567
	$group->add(new Form_Input(
568
		'dns' . $dnsserver_num,
569
		'DNS Server',
570
		'text',
571
		$dnsserver
572
	))->setHelp(($is_last_dnsserver) ? $dnsserver_help:null);
573

    
574
	$group->add(new Form_Input(
575
		'dnshost' . $dnsserver_num,
576
		'DNS Hostname',
577
		'text',
578
		$pconfig['dnshost' . $dnsserver_num]
579
	))->setHelp(($is_last_dnsserver) ? $dnshost_help:null);
580

    
581
	if (($multiwan > 1) || ($multiwan6 > 1)) {
582
		$options = array('none' => 'none');
583

    
584
		foreach ($arr_gateways as $gwname => $gwitem) {
585
			if ((is_ipaddrv4(lookup_gateway_ip_by_name($pconfig[$dnsgw])) && (is_ipaddrv6($gwitem['gateway'])))) {
586
				continue;
587
			}
588

    
589
			if ((is_ipaddrv6(lookup_gateway_ip_by_name($pconfig[$dnsgw])) && (is_ipaddrv4($gwitem['gateway'])))) {
590
				continue;
591
			}
592

    
593
			$options[$gwname] = $gwname.' - '.$gwitem['friendlyiface'].' - '.$gwitem['gateway'];
594
		}
595

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

    
604
	$group->add(new Form_Button(
605
		'deleterow' . $dnsserver_num,
606
		'Delete',
607
		null,
608
		'fa-trash'
609
	))->setWidth(2)->addClass('btn-warning');
610

    
611
	$section->add($group);
612
	$dnsserver_num++;
613
}
614

    
615
$section->addInput(new Form_Button(
616
	'addrow',
617
	'Add DNS Server',
618
	null,
619
	'fa-plus'
620
))->addClass('btn-success addbtn');
621

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

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

    
646
$form->add($section);
647

    
648
$section = new Form_Section('Localization');
649

    
650
$section->addInput(new Form_Select(
651
	'timezone',
652
	'*Timezone',
653
	$pconfig['timezone'],
654
	array_combine($timezonelist, $timezonedesc)
655
))->setHelp('Select a geographic region name (Continent/Location) to determine the timezone for the firewall. %1$s' .
656
	'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/>');
657

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

    
666
$section->addInput(new Form_Select(
667
	'language',
668
	'*Language',
669
	$pconfig['language'],
670
	get_locale_list()
671
))->setHelp('Choose a language for the webConfigurator');
672

    
673
$form->add($section);
674

    
675
$section = new Form_Section('webConfigurator');
676

    
677
gen_webguicss_field($section, $pconfig['webguicss']);
678
gen_webguifixedmenu_field($section, $pconfig['webguifixedmenu']);
679
gen_webguihostnamemenu_field($section, $pconfig['webguihostnamemenu']);
680
gen_dashboardcolumns_field($section, $pconfig['dashboardcolumns']);
681
gen_interfacessort_field($section, $pconfig['interfacessort']);
682
gen_associatedpanels_fields(
683
	$section,
684
	$pconfig['dashboardavailablewidgetspanel'],
685
	$pconfig['systemlogsfilterpanel'],
686
	$pconfig['systemlogsmanagelogpanel'],
687
	$pconfig['statusmonitoringsettingspanel']);
688
gen_requirestatefilter_field($section, $pconfig['requirestatefilter']);
689
gen_webguileftcolumnhyper_field($section, $pconfig['webguileftcolumnhyper']);
690
gen_disablealiaspopupdetail_field($section, $pconfig['disablealiaspopupdetail']);
691

    
692
$section->addInput(new Form_Checkbox(
693
	'roworderdragging',
694
	'Disable dragging',
695
	'Disable dragging of firewall/NAT rules',
696
	$pconfig['roworderdragging']
697
))->setHelp('Disables dragging rows to allow selecting and copying row contents and avoid accidental changes.');
698

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

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

    
729
print $form;
730

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

    
733
?>
734
</div>
735

    
736
<script type="text/javascript">
737
//<![CDATA[
738
events.push(function() {
739

    
740
	function setThemeWarning() {
741
		if ($('#webguicss').val().startsWith("pfSense")) {
742
			$('#csstxt').html("").addClass("text-default");
743
		} else {
744
			$('#csstxt').html("<?=$csswarning?>").addClass("text-danger");
745
		}
746
	}
747

    
748
	$('#webguicss').change(function() {
749
		setThemeWarning();
750
	});
751

    
752
	setThemeWarning();
753

    
754
	// Suppress "Delete row" button if there are fewer than two rows
755
	checkLastRow();
756
});
757
//]]>
758
</script>
759

    
760
<?php
761
include("foot.inc");
762
?>
(184-184/228)