Project

General

Profile

Download (17.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	system.php
4
*/
5
/* ====================================================================
6
 *	Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved.
7
 *
8
 *	Some or all of this file is based on the m0n0wall project which is
9
 *	Copyright (c)  2004 Manuel Kasper (BSD 2 clause)
10
 *
11
 *	Redistribution and use in source and binary forms, with or without modification,
12
 *	are permitted provided that the following conditions are met:
13
 *
14
 *	1. Redistributions of source code must retain the above copyright notice,
15
 *		this list of conditions and the following disclaimer.
16
 *
17
 *	2. Redistributions in binary form must reproduce the above copyright
18
 *		notice, this list of conditions and the following disclaimer in
19
 *		the documentation and/or other materials provided with the
20
 *		distribution.
21
 *
22
 *	3. All advertising materials mentioning features or use of this software
23
 *		must display the following acknowledgment:
24
 *		"This product includes software developed by the pfSense Project
25
 *		 for use in the pfSense software distribution. (http://www.pfsense.org/).
26
 *
27
 *	4. The names "pfSense" and "pfSense Project" must not be used to
28
 *		 endorse or promote products derived from this software without
29
 *		 prior written permission. For written permission, please contact
30
 *		 coreteam@pfsense.org.
31
 *
32
 *	5. Products derived from this software may not be called "pfSense"
33
 *		nor may "pfSense" appear in their names without prior written
34
 *		permission of the Electric Sheep Fencing, LLC.
35
 *
36
 *	6. Redistributions of any form whatsoever must retain the following
37
 *		acknowledgment:
38
 *
39
 *	"This product includes software developed by the pfSense Project
40
 *	for use in the pfSense software distribution (http://www.pfsense.org/).
41
 *
42
 *	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
43
 *	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44
 *	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
45
 *	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
46
 *	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47
 *	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48
 *	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50
 *	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
51
 *	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52
 *	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
53
 *	OF THE POSSIBILITY OF SUCH DAMAGE.
54
 *
55
 *	====================================================================
56
 *
57
 */
58

    
59
##|+PRIV
60
##|*IDENT=page-system-generalsetup
61
##|*NAME=System: General Setup
62
##|*DESCR=Allow access to the 'System: General Setup' page.
63
##|*MATCH=system.php*
64
##|-PRIV
65

    
66
require("guiconfig.inc");
67
require_once("functions.inc");
68
require_once("filter.inc");
69
require_once("shaper.inc");
70
require_once("system.inc");
71

    
72
$pconfig['hostname'] = $config['system']['hostname'];
73
$pconfig['domain'] = $config['system']['domain'];
74
list($pconfig['dns1'], $pconfig['dns2'], $pconfig['dns3'], $pconfig['dns4']) = $config['system']['dnsserver'];
75

    
76
$arr_gateways = return_gateways_array();
77

    
78
// set default colmns to two if unset
79
if (!isset($config['system']['webgui']['dashboardcolumns'])) {
80
	$config['system']['webgui']['dashboardcolumns'] = 2;
81
}
82

    
83
$pconfig['dns1gw'] = $config['system']['dns1gw'];
84
$pconfig['dns2gw'] = $config['system']['dns2gw'];
85
$pconfig['dns3gw'] = $config['system']['dns3gw'];
86
$pconfig['dns4gw'] = $config['system']['dns4gw'];
87

    
88
$pconfig['dnsallowoverride'] = isset($config['system']['dnsallowoverride']);
89
$pconfig['timezone'] = $config['system']['timezone'];
90
$pconfig['timeservers'] = $config['system']['timeservers'];
91
$pconfig['language'] = $config['system']['language'];
92
$pconfig['webguicss'] = $config['system']['webgui']['webguicss'];
93
$pconfig['webguifixedmenu'] = $config['system']['webgui']['webguifixedmenu'];
94
$pconfig['dashboardcolumns'] = $config['system']['webgui']['dashboardcolumns'];
95
$pconfig['dnslocalhost'] = isset($config['system']['dnslocalhost']);
96

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

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

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

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

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

    
120
$timezonelist = system_get_timezone_list();
121

    
122
$multiwan = false;
123
$interfaces = get_configured_interface_list();
124
foreach ($interfaces as $interface) {
125
	if (interface_has_gateway($interface)) {
126
		$multiwan = true;
127
	}
128
}
129

    
130
if ($_POST) {
131

    
132
	$changecount++;
133

    
134
	unset($input_errors);
135
	$pconfig = $_POST;
136

    
137
	/* input validation */
138
	$reqdfields = explode(" ", "hostname domain");
139
	$reqdfieldsn = array(gettext("Hostname"), gettext("Domain"));
140

    
141
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
142

    
143
	if ($_POST['webguicss']) {
144
		$config['system']['webgui']['webguicss'] = $_POST['webguicss'];
145
	} else {
146
		unset($config['system']['webgui']['webguicss']);
147
	}
148

    
149
	if ($_POST['webguifixedmenu']) {
150
		$config['system']['webgui']['webguifixedmenu'] = $_POST['webguifixedmenu'];
151
	} else {
152
		unset($config['system']['webgui']['webguifixedmenu']);
153
	}
154

    
155
	if ($_POST['dashboardcolumns']) {
156
		$config['system']['webgui']['dashboardcolumns'] = $_POST['dashboardcolumns'];
157
	} else {
158
		unset($config['system']['webgui']['dashboardcolumns']);
159
	}
160

    
161
	if ($_POST['hostname']) {
162
		if (!is_hostname($_POST['hostname'])) {
163
			$input_errors[] = gettext("The hostname can only contain the characters A-Z, 0-9 and '-'. It may not start or end with '-'.");
164
		} else {
165
			if (!is_unqualified_hostname($_POST['hostname'])) {
166
				$input_errors[] = gettext("A valid hostname is specified, but the domain name part should be omitted");
167
			}
168
		}
169
	}
170
	if ($_POST['domain'] && !is_domain($_POST['domain'])) {
171
		$input_errors[] = gettext("The domain may only contain the characters a-z, 0-9, '-' and '.'.");
172
	}
173

    
174
	$ignore_posted_dnsgw = array();
175

    
176
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
177
		$dnsname="dns{$dnscounter}";
178
		$dnsgwname="dns{$dnscounter}gw";
179
		if (($_POST[$dnsname] && !is_ipaddr($_POST[$dnsname]))) {
180
			$input_errors[] = gettext("A valid IP address must be specified for DNS server $dnscounter.");
181
		} else {
182
			if (($_POST[$dnsgwname] <> "") && ($_POST[$dnsgwname] <> "none")) {
183
				// A real gateway has been selected.
184
				if (is_ipaddr($_POST[$dnsname])) {
185
					if ((is_ipaddrv4($_POST[$dnsname])) && (validate_address_family($_POST[$dnsname], $_POST[$dnsgwname]) === false)) {
186
						$input_errors[] = gettext("You can not specify IPv6 gateway '{$_POST[$dnsgwname]}' for IPv4 DNS server '{$_POST[$dnsname]}'");
187
					}
188
					if ((is_ipaddrv6($_POST[$dnsname])) && (validate_address_family($_POST[$dnsname], $_POST[$dnsgwname]) === false)) {
189
						$input_errors[] = gettext("You can not specify IPv4 gateway '{$_POST[$dnsgwname]}' for IPv6 DNS server '{$_POST[$dnsname]}'");
190
					}
191
				} else {
192
					// The user selected a gateway but did not provide a DNS address. Be nice and set the gateway back to "none".
193
					$ignore_posted_dnsgw[$dnsgwname] = true;
194
				}
195
			}
196
		}
197
	}
198

    
199
	$direct_networks_list = explode(" ", filter_get_direct_networks_list());
200
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
201
		$dnsitem = "dns{$dnscounter}";
202
		$dnsgwitem = "dns{$dnscounter}gw";
203
		if ($_POST[$dnsgwitem]) {
204
			if (interface_has_gateway($_POST[$dnsgwitem])) {
205
				foreach ($direct_networks_list as $direct_network) {
206
					if (ip_in_subnet($_POST[$dnsitem], $direct_network)) {
207
						$input_errors[] = sprintf(gettext("You can not assign a gateway to DNS '%s' server which is on a directly connected network."), $_POST[$dnsitem]);
208
					}
209
				}
210
			}
211
		}
212
	}
213

    
214
	# it's easy to have a little too much whitespace in the field, clean it up for the user before processing.
215
	$_POST['timeservers'] = preg_replace('/[[:blank:]]+/', ' ', $_POST['timeservers']);
216
	$_POST['timeservers'] = trim($_POST['timeservers']);
217
	foreach (explode(' ', $_POST['timeservers']) as $ts) {
218
		if (!is_domain($ts)) {
219
			$input_errors[] = gettext("A NTP Time Server name may only contain the characters a-z, 0-9, '-' and '.'.");
220
		}
221
	}
222

    
223
	if (!$input_errors) {
224
		update_if_changed("hostname", $config['system']['hostname'], $_POST['hostname']);
225
		update_if_changed("domain", $config['system']['domain'], $_POST['domain']);
226
		update_if_changed("timezone", $config['system']['timezone'], $_POST['timezone']);
227
		update_if_changed("NTP servers", $config['system']['timeservers'], strtolower($_POST['timeservers']));
228

    
229
		if ($_POST['language'] && $_POST['language'] != $config['system']['language']) {
230
			$config['system']['language'] = $_POST['language'];
231
			set_language($config['system']['language']);
232
		}
233

    
234
		/* XXX - billm: these still need updating after figuring out how to check if they actually changed */
235
		$olddnsservers = $config['system']['dnsserver'];
236
		unset($config['system']['dnsserver']);
237
		if ($_POST['dns1']) {
238
			$config['system']['dnsserver'][] = $_POST['dns1'];
239
		}
240
		if ($_POST['dns2']) {
241
			$config['system']['dnsserver'][] = $_POST['dns2'];
242
		}
243
		if ($_POST['dns3']) {
244
			$config['system']['dnsserver'][] = $_POST['dns3'];
245
		}
246
		if ($_POST['dns4']) {
247
			$config['system']['dnsserver'][] = $_POST['dns4'];
248
		}
249

    
250
		$olddnsallowoverride = $config['system']['dnsallowoverride'];
251

    
252
		unset($config['system']['dnsallowoverride']);
253
		$config['system']['dnsallowoverride'] = $_POST['dnsallowoverride'] ? true : false;
254

    
255
		if ($_POST['dnslocalhost'] == "yes") {
256
			$config['system']['dnslocalhost'] = true;
257
		} else {
258
			unset($config['system']['dnslocalhost']);
259
		}
260

    
261
		/* which interface should the dns servers resolve through? */
262
		$outdnscounter = 0;
263
		for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
264
			$dnsname="dns{$dnscounter}";
265
			$dnsgwname="dns{$dnscounter}gw";
266
			$olddnsgwname = $config['system'][$dnsgwname];
267

    
268
			if ($ignore_posted_dnsgw[$dnsgwname]) {
269
				$thisdnsgwname = "none";
270
			} else {
271
				$thisdnsgwname = $pconfig[$dnsgwname];
272
			}
273

    
274
			// "Blank" out the settings for this index, then we set them below using the "outdnscounter" index.
275
			$config['system'][$dnsgwname] = "none";
276
			$pconfig[$dnsgwname] = "none";
277
			$pconfig[$dnsname] = "";
278

    
279
			if ($_POST[$dnsname]) {
280
				// Only the non-blank DNS servers were put into the config above.
281
				// So we similarly only add the corresponding gateways sequentially to the config (and to pconfig), as we find non-blank DNS servers.
282
				// 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.
283
				$outdnscounter++;
284
				$outdnsname="dns{$outdnscounter}";
285
				$outdnsgwname="dns{$outdnscounter}gw";
286
				$pconfig[$outdnsname] = $_POST[$dnsname];
287
				if ($_POST[$dnsgwname]) {
288
					$config['system'][$outdnsgwname] = $thisdnsgwname;
289
					$pconfig[$outdnsgwname] = $thisdnsgwname;
290
				} else {
291
					// Note: when no DNS GW name is chosen, the entry is set to "none", so actually this case never happens.
292
					unset($config['system'][$outdnsgwname]);
293
					$pconfig[$outdnsgwname] = "";
294
				}
295
			}
296
			if (($olddnsgwname != "") && ($olddnsgwname != "none") && (($olddnsgwname != $thisdnsgwname) || ($olddnsservers[$dnscounter-1] != $_POST[$dnsname]))) {
297
				// A previous DNS GW name was specified. It has now gone or changed, or the DNS server address has changed.
298
				// Remove the route. Later calls will add the correct new route if needed.
299
				if (is_ipaddrv4($olddnsservers[$dnscounter-1])) {
300
					mwexec("/sbin/route delete " . escapeshellarg($olddnsservers[$dnscounter-1]));
301
				} else if (is_ipaddrv6($olddnsservers[$dnscounter-1])) {
302
					mwexec("/sbin/route delete -inet6 " . escapeshellarg($olddnsservers[$dnscounter-1]));
303
				}
304
			}
305
		}
306

    
307
		if ($changecount > 0) {
308
			write_config($changedesc);
309
		}
310

    
311
		$retval = 0;
312
		$retval = system_hostname_configure();
313
		$retval |= system_hosts_generate();
314
		$retval |= system_resolvconf_generate();
315
		if (isset($config['dnsmasq']['enable'])) {
316
			$retval |= services_dnsmasq_configure();
317
		} elseif (isset($config['unbound']['enable'])) {
318
			$retval |= services_unbound_configure();
319
		}
320
		$retval |= system_timezone_configure();
321
		$retval |= system_ntp_configure();
322

    
323
		if ($olddnsallowoverride != $config['system']['dnsallowoverride']) {
324
			$retval |= send_event("service reload dns");
325
		}
326

    
327
		// Reload the filter - plugins might need to be run.
328
		$retval |= filter_configure();
329

    
330
		$savemsg = get_std_save_message($retval);
331
	}
332

    
333
	unset($ignore_posted_dnsgw);
334
}
335

    
336
$pgtitle = array(gettext("System"), gettext("General Setup"));
337
include("head.inc");
338

    
339
if ($input_errors) {
340
	print_input_errors($input_errors);
341
}
342

    
343
if ($savemsg) {
344
	print_info_box($savemsg, success);
345
}
346
?>
347
<div id="container">
348
<?php
349

    
350
$form = new Form;
351
$section = new Form_Section('System');
352
$section->addInput(new Form_Input(
353
	'hostname',
354
	'Hostname',
355
	'text',
356
	$pconfig['hostname'],
357
	['placeholder' => 'pfSense']
358
))->setHelp('Name of the firewall host, without domain part');
359
$section->addInput(new Form_Input(
360
	'domain',
361
	'Domain',
362
	'text',
363
	$pconfig['domain'],
364
	['placeholder' => 'mycorp.com, home, office, private, etc.']
365
))->setHelp('Do not use \'local\' as a domain name. It will cause local '.
366
	'hosts running mDNS (avahi, bonjour, etc.) to be unable to resolve '.
367
	'local hosts not running mDNS.');
368
$form->add($section);
369

    
370
$section = new Form_Section('DNS server settings');
371

    
372
for ($i=1; $i<5; $i++) {
373
//	if (!isset($pconfig['dns'.$i]))
374
//		continue;
375

    
376
	$group = new Form_Group('DNS Server ' . $i);
377

    
378
	$group->add(new Form_Input(
379
		'dns' . $i,
380
		'DNS Server',
381
		'text',
382
		$pconfig['dns'. $i]
383
	))->setHelp(($i == 4) ? 'Address':null);
384

    
385
	$help = "Enter IP addresses to be used by the system for DNS resolution. " .
386
		"These are also used for the DHCP service, DNS forwarder and for PPTP VPN clients.";
387

    
388
	if ($multiwan)	{
389
		$options = array('none' => 'none');
390

    
391
		foreach ($arr_gateways as $gwname => $gwitem) {
392
			if ((is_ipaddrv4(lookup_gateway_ip_by_name($pconfig[$dnsgw])) && (is_ipaddrv6($gwitem['gateway'])))) {
393
				continue;
394
			}
395

    
396
			if ((is_ipaddrv6(lookup_gateway_ip_by_name($pconfig[$dnsgw])) && (is_ipaddrv4($gwitem['gateway'])))) {
397
				continue;
398
			}
399

    
400
			$options[$gwname] = $gwname.' - '.$gwitem['friendlyiface'].' - '.$gwitem['gateway'];
401
		}
402

    
403
		$group->add(new Form_Select(
404
			'dns' . $i . 'gw',
405
			null,
406
			$pconfig['dns' . $i . 'gw'],
407
			$options
408
		))->setHelp(($i == 4) ? 'Gateway':null);;
409

    
410
		$help .= '<br/>'. "In addition, optionally select the gateway for each DNS server. " .
411
			"When using multiple WAN connections there should be at least one unique DNS server per gateway.";
412
	}
413

    
414
	if ($i == 4) {
415
		$group->setHelp($help);
416
	}
417

    
418
	$section->add($group);
419
}
420

    
421
$section->addInput(new Form_Checkbox(
422
	'dnsallowoverride',
423
	'DNS server override',
424
	'Allow DNS server list to be overridden by DHCP/PPP on WAN',
425
	$pconfig['dnsallowoverride']
426
))->setHelp(sprintf(gettext('If this option is set, %s will use DNS servers'.
427
	'assigned by a DHCP/PPP server on WAN for its own purposes (including '.
428
	'the DNS forwarder). However, they will not be assigned to DHCP and PPTP '.
429
	'VPN clients.'), $g['product_name']));
430

    
431
$section->addInput(new Form_Checkbox(
432
	'dnslocalhost',
433
	'Disable DNS forwarder',
434
	'Do not use the DNS Forwarder as a DNS server for the firewall',
435
	$pconfig['dnslocalhost']
436
))->setHelp('By default localhost (127.0.0.1) will be used as the first DNS'.
437
	'server where the DNS Forwarder or DNS Resolver is enabled and set to '.
438
	'listen on Localhost, so system can use the local DNS service to perform'.
439
	'lookups. Checking this box omits localhost from the list of DNS servers.');
440

    
441
$form->add($section);
442

    
443
$section = new Form_Section('Localization');
444
$section->addInput(new Form_Select(
445
	'timezone',
446
	'Timezone',
447
	$pconfig['timezone'],
448
	array_combine($timezonelist, $timezonelist)
449
))->setHelp('Select the location closest to you');
450
$section->addInput(new Form_Input(
451
	'timeservers',
452
	'Timeservers',
453
	'text',
454
	$pconfig['timeservers']
455
))->setHelp('Use a space to separate multiple hosts (only one required). '.
456
	'Remember to set up at least one DNS server if you enter a host name here!');
457
$section->addInput(new Form_Select(
458
	'language',
459
	'Language',
460
	$pconfig['language'],
461
	get_locale_list()
462
))->setHelp('Choose a language for the webConfigurator');
463

    
464
$form->add($section);
465

    
466
$csslist = array();
467
$css = glob("/usr/local/www/bootstrap/css/*.css");
468
foreach ($css as $file) {
469
	$file = basename($file);
470
	if (substr($file, 0, 9) !== 'bootstrap') {
471
		$csslist[$file] = pathinfo($file, PATHINFO_FILENAME);
472
	}
473
}
474

    
475
asort($csslist);
476

    
477
if (!isset($pconfig['webguicss']) || !isset($csslist[$pconfig['webguicss']])) {
478
	$pconfig['webguicss'] = "pfSense.css";
479
}
480

    
481
$section = new Form_Section('Web Configurator');
482

    
483
$section->addInput(new Form_Select(
484
	'webguicss',
485
	'Theme',
486
	$pconfig['webguicss'],
487
	$csslist
488
))->setHelp('Choose an alternative css file (if installed) to change the appearance of the Web configurator. css files are located in /usr/local/www/bootstrap/css');
489

    
490
$section->addInput(new Form_Select(
491
	'webguifixedmenu',
492
	'Top Navigation',
493
	$pconfig['webguifixedmenu'],
494
	["" => "Scrolls with page", "fixed" => "Fixed (Remains visible at top of page)"]
495
))->setHelp("The fixed option is intended for large screens only.");
496

    
497
$section->addInput(new Form_Input(
498
	'dashboardcolumns',
499
	'Dashboard Columns',
500
	'number',
501
	$pconfig['dashboardcolumns'],
502
	[min => 1, max => 4]
503
))->setHelp('<span class="badge" title="This feature is in BETA">BETA</span>');
504

    
505
$form->add($section);
506

    
507
print $form;
508
?>
509
</div>
510
<?php
511
include("foot.inc");
512
?>
(186-186/228)