Project

General

Profile

Download (27.5 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-2024 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_get_path('system/hostname');
42
$pconfig['domain'] = config_get_path('system/domain');
43
$pconfig['dnsserver'] = config_get_path('system/dnsserver');
44

    
45
$arr_gateways = get_gateways();
46

    
47
// set default columns to two if unset
48
if (!is_numericint(config_get_path('system/webgui/dashboardcolumns'))) {
49
	config_set_path('system/webgui/dashboardcolumns', 2);
50
}
51

    
52
// set default language if unset
53
if (!config_path_enabled('system', 'language')) {
54
	config_set_path('system/language', g_get('language'));
55
}
56

    
57
$dnshost_counter = 1;
58

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

    
65
$dnsgw_counter = 1;
66

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

    
73
$pconfig['dnsallowoverride'] = config_path_enabled('system', 'dnsallowoverride');
74
$pconfig['timezone'] = config_get_path('system/timezone');
75
$pconfig['timeservers'] = config_get_path('system/timeservers');
76
$pconfig['language'] = config_get_path('system/language');
77
$pconfig['webguicss'] = config_get_path('system/webgui/webguicss');
78
$pconfig['logincss'] = config_get_path('system/webgui/logincss');
79
$pconfig['webguifixedmenu'] = config_get_path('system/webgui/webguifixedmenu');
80
$pconfig['dashboardcolumns'] = config_get_path('system/webgui/dashboardcolumns');
81
$pconfig['interfacessort'] = config_path_enabled('system/webgui', 'interfacessort');
82
$pconfig['webguileftcolumnhyper'] = config_path_enabled('system/webgui', 'webguileftcolumnhyper');
83
$pconfig['disablealiaspopupdetail'] = config_path_enabled('system/webgui', 'disablealiaspopupdetail');
84
$pconfig['dashboardavailablewidgetspanel'] = config_path_enabled('system/webgui', 'dashboardavailablewidgetspanel');
85
$pconfig['systemlogsfilterpanel'] = config_path_enabled('system/webgui', 'systemlogsfilterpanel');
86
$pconfig['systemlogsmanagelogpanel'] = config_path_enabled('system/webgui', 'systemlogsmanagelogpanel');
87
$pconfig['statusmonitoringsettingspanel'] = config_path_enabled('system/webgui', 'statusmonitoringsettingspanel');
88
$pconfig['webguihostnamemenu'] = config_get_path('system/webgui/webguihostnamemenu');
89
$pconfig['dnslocalhost'] = config_get_path('system/dnslocalhost');
90
//$pconfig['dashboardperiod'] = isset($config['widgets']['period']) ? $config['widgets']['period']:"10";
91
$pconfig['roworderdragging'] = config_path_enabled('system/webgui', 'roworderdragging');
92
$pconfig['loginshowhost'] = config_path_enabled('system/webgui', 'loginshowhost');
93
$pconfig['requirestatefilter'] = config_path_enabled('system/webgui', 'requirestatefilter');
94
$pconfig['requirefirewallinterface'] = config_path_enabled('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_get_path('system/dnsserver'))) {
270
		  	$dns_servers_arr = config_get_path('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
		$system_config = config_get_path('system');
285
		update_if_changed("hostname", $system_config['hostname'], $_POST['hostname']);
286
		update_if_changed("domain", $system_config['domain'], $_POST['domain']);
287
		update_if_changed("timezone", $system_config['timezone'], $_POST['timezone']);
288
		update_if_changed("NTP servers", $system_config['timeservers'], strtolower($_POST['timeservers']));
289
		config_set_path('system', $system_config);
290

    
291
		if ($_POST['language'] && $_POST['language'] != config_get_path('system/language')) {
292
			config_set_path('system/language', $_POST['language']);
293
			set_language();
294
		}
295

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
362
		$dnscounter = 0;
363
		$dnsname = "dns{$dnscounter}";
364

    
365
		while (isset($_POST[$dnsname])) {
366
			if ($_POST[$dnsname]) {
367
				config_set_path('system/dnsserver/', $_POST[$dnsname]);
368
			}
369
			$dnscounter++;
370
			$dnsname = "dns{$dnscounter}";
371
		}
372

    
373
		// Remember the new list for display also.
374
		$pconfig['dnsserver'] = config_get_path('system/dnsserver');
375

    
376
		$olddnsallowoverride = config_get_path('system/dnsallowoverride');
377

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

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

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

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

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

    
413
			// "Blank" out the settings for this index, then we set them below using the "outdnscounter" index.
414
			config_set_path("system/{$dnsgwconfigname}", 'none');
415
			$pconfig[$dnsgwname] = "none";
416
			config_set_path("system/{$dnshostconfigname}", '');
417
			$pconfig[$dnshostname] = "";
418
			$pconfig[$dnsname] = "";
419

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

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

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

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

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

    
464
		// clean up dnsgw orphans
465
		$oldgwcounter = 1;
466
		$olddnsgwconfigname = "dns{$oldgwcounter}gw";
467
		while (config_get_path("system/{$olddnsgwconfigname}") !== null) {
468
			if (empty(config_get_path('system/dnsserver/' . ($oldgwcounter - 1)))) {
469
				config_del_path("system/{$olddnsgwconfigname}");
470
			}
471
			$oldgwcounter++;
472
			$olddnsgwconfigname = "dns{$oldgwcounter}gw";
473
		}
474
		unset($oldgwcounter);
475
		unset($olddnsgwconfigname);
476

    
477
		if ($changecount > 0) {
478
			write_config($changedesc);
479
		}
480

    
481
		$changes_applied = true;
482
		$retval = 0;
483
		$retval |= system_hostname_configure();
484
		$retval |= system_hosts_generate();
485
		$retval |= system_resolvconf_generate();
486
		if (config_path_enabled('dnsmasq')) {
487
			$retval |= services_dnsmasq_configure();
488
		} elseif (config_path_enabled('unbound')) {
489
			$retval |= services_unbound_configure();
490
		}
491
		$retval |= system_timezone_configure();
492
		$retval |= system_ntp_configure();
493

    
494
		if ($olddnsallowoverride != config_get_path('system/dnsallowoverride')) {
495
			$retval |= send_event("service reload dns");
496
		}
497

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

    
502
	unset($ignore_posted_dnsgw);
503
}
504

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

    
508
if ($input_errors) {
509
	print_input_errors($input_errors);
510
}
511

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

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

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

    
546
$form->add($section);
547

    
548
$section = new Form_Section('DNS Server Settings');
549

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

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

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

    
567
foreach ($pconfig['dnsserver'] as $dnsserver) {
568

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

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

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

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

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

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

    
599
			$options[$gwname] = $gwname.' - '.$gwitem['friendlyiface'].' - '.$gwitem['gateway'];
600
		}
601

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

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

    
617
	$section->add($group);
618
	$dnsserver_num++;
619
}
620

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

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

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

    
652
$form->add($section);
653

    
654
$section = new Form_Section('Localization');
655

    
656
$section->addInput(new Form_Select(
657
	'timezone',
658
	'*Timezone',
659
	$pconfig['timezone'],
660
	array_combine($timezonelist, $timezonedesc)
661
))->setHelp('Select a geographic region name (Continent/Location) to determine the timezone for the firewall. %1$s' .
662
	'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/>');
663

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

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

    
679
$form->add($section);
680

    
681
$section = new Form_Section('webConfigurator');
682

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

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

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

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

    
736
print $form;
737

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

    
740
?>
741
</div>
742

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

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

    
755
	$('#webguicss').change(function() {
756
		setThemeWarning();
757
	});
758

    
759
	setThemeWarning();
760

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

    
767
<?php
768
include("foot.inc");
769
?>
(188-188/232)