Project

General

Profile

Download (34.9 KB) Statistics
| Branch: | Tag: | Revision:
1 12df7edc Erik
<?php
2 09221bc3 Renato Botelho
/*
3 ac24dc24 Renato Botelho
 * config.lib.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 8f2f85c3 Luiz Otavio O Souza
 * Copyright (c) 2014-2022 Rubicon Communications, LLC (Netgate)
9 ac24dc24 Renato Botelho
 * Copyright (c) 2009 Erik Kristensen
10
 * All rights reserved.
11
 *
12
 * originally part of m0n0wall (http://m0n0.ch/wall)
13 c5d81585 Renato Botelho
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14 ac24dc24 Renato Botelho
 * All rights reserved.
15
 *
16 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
17
 * you may not use this file except in compliance with the License.
18
 * You may obtain a copy of the License at
19 ac24dc24 Renato Botelho
 *
20 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
21 ac24dc24 Renato Botelho
 *
22 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
23
 * distributed under the License is distributed on an "AS IS" BASIS,
24
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
 * See the License for the specific language governing permissions and
26
 * limitations under the License.
27 ac24dc24 Renato Botelho
 */
28 12df7edc Erik
29
/****f* config/encrypted_configxml
30
 * NAME
31
 *   encrypted_configxml - Checks to see if config.xml is encrypted and if so, prompts to unlock.
32
 * INPUTS
33
 *   None
34
 * RESULT
35
 *   $config 	- rewrites config.xml without encryption
36
 ******/
37
function encrypted_configxml() {
38
	global $g, $config;
39 02e9880e Ermal
40 1e0b1727 Phil Davis
	if (!file_exists($g['conf_path'] . "/config.xml")) {
41 02e9880e Ermal
		return;
42 1e0b1727 Phil Davis
	}
43 02e9880e Ermal
44 1e0b1727 Phil Davis
	if (!platform_booting()) {
45 02e9880e Ermal
		return;
46 1e0b1727 Phil Davis
	}
47 02e9880e Ermal
48 1e0b1727 Phil Davis
	$configtxt = file_get_contents($g['conf_path'] . "/config.xml");
49
	if (tagfile_deformat($configtxt, $configtxt, "config.xml")) {
50 02e9880e Ermal
		$fp = fopen('php://stdin', 'r');
51
		$data = "";
52
		echo "\n\n*** Encrypted config.xml detected ***\n";
53 1e0b1727 Phil Davis
		while ($data == "") {
54 02e9880e Ermal
			echo "\nEnter the password to decrypt config.xml: ";
55
			$decrypt_password = chop(fgets($fp));
56
			$data = decrypt_data($configtxt, $decrypt_password);
57 1e0b1727 Phil Davis
			if (!strstr($data, "<pfsense>")) {
58 12df7edc Erik
				$data = "";
59 1e0b1727 Phil Davis
			}
60
			if ($data) {
61 02e9880e Ermal
				$fd = fopen($g['conf_path'] . "/config.xml.tmp", "w");
62
				fwrite($fd, $data);
63
				fclose($fd);
64
				exec("/bin/mv {$g['conf_path']}/config.xml.tmp {$g['conf_path']}/config.xml");
65 9d3d8d00 Vinicius Coque
				echo "\n" . gettext("Config.xml unlocked.") . "\n";
66 02e9880e Ermal
				fclose($fp);
67 c5663bf5 Renato Botelho
				//pfSense_fsync("{$g['conf_path']}/config.xml");
68 02e9880e Ermal
			} else {
69 9d3d8d00 Vinicius Coque
				echo "\n" . gettext("Invalid password entered.  Please try again.") . "\n";
70 12df7edc Erik
			}
71
		}
72
	}
73
}
74
75
/****f* config/parse_config
76
 * NAME
77
 *   parse_config - Read in config.cache or config.xml if needed and return $config array
78
 * INPUTS
79
 *   $parse       - boolean to force parse_config() to read config.xml and generate config.cache
80
 * RESULT
81
 *   $config      - array containing all configuration variables
82
 ******/
83 1295e769 Scott Ullrich
function parse_config($parse = false) {
84 4e9a3392 Scott Ullrich
	global $g, $config_parsed, $config_extra;
85 02e9880e Ermal
86 12df7edc Erik
	$lockkey = lock('config');
87 0af381c2 Scott Ullrich
	$config_parsed = false;
88 02e9880e Ermal
89 12df7edc Erik
	if (!file_exists("{$g['conf_path']}/config.xml") || filesize("{$g['conf_path']}/config.xml") == 0) {
90
		$last_backup = discover_last_backup();
91 1e0b1727 Phil Davis
		if ($last_backup) {
92 4e038d31 Carlos Eduardo Ramos
			log_error(gettext("No config.xml found, attempting last known config restore."));
93
			file_notice("config.xml", gettext("No config.xml found, attempting last known config restore."), "pfSenseConfigurator", "");
94 12df7edc Erik
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
95
		} else {
96
			unlock($lockkey);
97 4e038d31 Carlos Eduardo Ramos
			die(gettext("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup."));
98 12df7edc Erik
		}
99
	}
100 02e9880e Ermal
101 086cf944 Phil Davis
	if (platform_booting(true)) {
102 02e9880e Ermal
		echo ".";
103 086cf944 Phil Davis
	}
104 02e9880e Ermal
105 12df7edc Erik
	// Check for encrypted config.xml
106
	encrypted_configxml();
107 02e9880e Ermal
108 1e0b1727 Phil Davis
	if (!$parse) {
109 02e9880e Ermal
		if (file_exists($g['tmp_path'] . '/config.cache')) {
110 12df7edc Erik
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
111 adb6925e Chris Buechler
			if (!is_array($config)) {
112 02e9880e Ermal
				$parse = true;
113 1e0b1727 Phil Davis
			}
114
		} else {
115 02e9880e Ermal
			$parse = true;
116 1e0b1727 Phil Davis
		}
117 02e9880e Ermal
	}
118
	if ($parse == true) {
119 1e0b1727 Phil Davis
		if (!file_exists($g['conf_path'] . "/config.xml")) {
120
			if (platform_booting(true)) {
121 02e9880e Ermal
				echo ".";
122 1e0b1727 Phil Davis
			}
123 12df7edc Erik
			log_error("No config.xml found, attempting last known config restore.");
124
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
125
			$last_backup = discover_last_backup();
126 1e0b1727 Phil Davis
			if ($last_backup) {
127 12df7edc Erik
				restore_backup("/cf/conf/backup/{$last_backup}");
128 1e0b1727 Phil Davis
			} else {
129 4e038d31 Carlos Eduardo Ramos
				log_error(gettext("Could not restore config.xml."));
130 50cafcf3 Ermal
				unlock($lockkey);
131 4816e5ca Renato Botelho
				die(gettext("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup."));
132 50cafcf3 Ermal
			}
133 12df7edc Erik
		}
134 990d7c03 Erik Fonnesbeck
		$config = parse_xml_config($g['conf_path'] . '/config.xml', array($g['xml_rootobj'], 'pfsense'));
135 1e0b1727 Phil Davis
		if ($config == -1) {
136 12df7edc Erik
			$last_backup = discover_last_backup();
137 1e0b1727 Phil Davis
			if ($last_backup) {
138 12df7edc Erik
				restore_backup("/cf/conf/backup/{$last_backup}");
139 1e0b1727 Phil Davis
			} else {
140 12df7edc Erik
				log_error(gettext("Could not restore config.xml."));
141 50cafcf3 Ermal
				unlock($lockkey);
142
				die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
143
			}
144 12df7edc Erik
		}
145
		generate_config_cache($config);
146
	}
147 02e9880e Ermal
148 1e0b1727 Phil Davis
	if (platform_booting(true)) {
149 02e9880e Ermal
		echo ".";
150 1e0b1727 Phil Davis
	}
151 02e9880e Ermal
152 12df7edc Erik
	$config_parsed = true;
153
	unlock($lockkey);
154
155 dbc1b8ee jim-p
	alias_make_table();
156 02e9880e Ermal
157 12df7edc Erik
	return $config;
158
}
159
160
/****f* config/generate_config_cache
161
 * NAME
162
 *   generate_config_cache - Write serialized configuration to cache.
163
 * INPUTS
164
 *   $config	- array containing current firewall configuration
165
 * RESULT
166
 *   boolean	- true on completion
167
 ******/
168
function generate_config_cache($config) {
169 4e9a3392 Scott Ullrich
	global $g, $config_extra;
170 12df7edc Erik
171
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
172
	fwrite($configcache, serialize($config));
173
	fclose($configcache);
174 c5663bf5 Renato Botelho
	//pfSense_fsync("{$g['tmp_path']}/config.cache");
175 6990ad35 Phil Davis
176 4e9a3392 Scott Ullrich
	unset($configcache);
177
	/* Used for config.extra.xml */
178 1e0b1727 Phil Davis
	if (file_exists($g['tmp_path'] . '/config.extra.cache') && $config_extra) {
179 4e9a3392 Scott Ullrich
		$configcacheextra = fopen($g['tmp_path'] . '/config.extra.cache', "w");
180
		fwrite($configcacheextra, serialize($config_extra));
181 1e0b1727 Phil Davis
		fclose($configcacheextra);
182 c5663bf5 Renato Botelho
		//pfSense_fsync("{$g['tmp_path']}/config.extra.cache");
183 4e9a3392 Scott Ullrich
		unset($configcacheextra);
184
	}
185 12df7edc Erik
}
186
187
function discover_last_backup() {
188 40159e4f Viktor G
	global $g;
189
190 692c21fd Renato Botelho
	$backups = glob('/cf/conf/backup/*.xml');
191 40159e4f Viktor G
	foreach (array_reverse($backups) as $backup) {
192
		/* checking multiple backups when detecting invalid configuration
193
		 * https://redmine.pfsense.org/issues/11748 */
194
		if (filesize($backup) != 0) {
195
			$testconfig = parse_xml_config($backup, $g['xml_rootobj']);
196
			if ($testconfig != -1) {
197
				return basename($backup);
198
			}
199
		} 
200 692c21fd Renato Botelho
	}
201 12df7edc Erik
202 40159e4f Viktor G
	return false;
203 12df7edc Erik
}
204
205
function restore_backup($file) {
206
	global $g;
207
208
	if (file_exists($file)) {
209 b3cc5117 Viktor G
		/* restore rrddata/xmldata and clear appropriate data,
210
		 * see https://redmine.pfsense.org/issues/11050 */
211
		$data = file_get_contents("$file");
212
		$conf = parse_xml_config("$file", $g['xml_rootobj']);
213
		if ($conf['rrddata']) {
214
			restore_rrddata($conf);
215
			$data = clear_tagdata("rrd", $data);
216
		}
217 dc22e511 Viktor G
		if ($conf['sshdata']) {
218
			restore_sshdata($conf);
219
			$data = clear_tagdata("ssh", $data);
220
		}
221 b3cc5117 Viktor G
		foreach ($g['backuppath'] as $bk => $path) {
222
			if (!empty($conf[$bk][$bk.'data'])) {
223
				restore_xmldatafile($bk, $conf);
224
				$data = clear_tagdata($bk, $data);
225
			}
226
		}
227
		file_put_contents($file, $data);
228 12df7edc Erik
		unlink_if_exists("{$g['tmp_path']}/config.cache");
229 086cf944 Phil Davis
		copy("$file", "/cf/conf/config.xml");
230 c5663bf5 Renato Botelho
		//pfSense_fsync("/cf/conf/config.xml");
231
		//pfSense_fsync($g['conf_path']);
232 0f806eca Erik Fonnesbeck
		disable_security_checks();
233 573ec19d Renato Botelho do Couto
		log_error(sprintf(gettext('%1$s is restoring the configuration %2$s'), $g['product_label'], $file));
234
		file_notice("config.xml", sprintf(gettext('%1$s is restoring the configuration %2$s'), $g['product_label'], $file), "pfSenseConfigurator", "");
235 12df7edc Erik
	}
236
}
237
238 b3cc5117 Viktor G
/*
239
 *	Backup RRD/XML Data
240
 */
241
242
/* If the config on disk had rrddata/xmldata tags already, remove that section first.
243
 * See https://redmine.pfsense.org/issues/8994,
244
 *     https://redmine.pfsense.org/issues/10508, 
245
 *     https://redmine.pfsense.org/issues/11050 */
246
function clear_tagdata($tag = "rrd", $data) {
247
	$data = preg_replace("/[[:blank:]]*<{$tag}data>.*<\\/{$tag}data>[[:blank:]]*\n*/s", "", $data);
248
	$data = preg_replace("/[[:blank:]]*<{$tag}data\\/>[[:blank:]]*\n*/", "", $data);
249
250
	return $data;
251
}
252
253
function restore_xmldatafile($type='voucher', $conf = false) {
254
	global $config, $g;
255
256
	if (!$conf) {
257
		$conf = & $config;
258
	}
259
260
	foreach ($conf[$type]["{$type}data"]["xmldatafile"] as $file) {
261
		$basename = basename($file['filename']);
262
		$dirname = dirname($g['backuppath'][$type]);
263
		$xmldata_file = "{$dirname}/{$basename}";
264
		if (file_put_contents($xmldata_file, gzinflate(base64_decode($file['data']))) === false) {
265
			log_error(sprintf(gettext("Cannot write %s"), $xmldata_file));
266
			continue;
267
		}
268
	}
269
}
270
271
function restore_rrddata($conf = false) {
272
	global $config, $g, $rrdtool, $input_errors;
273
274
	if (!$conf) {
275
		$conf = & $config;
276
	}
277
278
	foreach ($conf['rrddata']['rrddatafile'] as $rrd) {
279
		if ($rrd['xmldata']) {
280
			$rrd_file = "{$g['vardb_path']}/rrd/{$rrd['filename']}";
281
			$xml_file = preg_replace('/\.rrd$/', ".xml", $rrd_file);
282
			if (file_put_contents($xml_file, gzinflate(base64_decode($rrd['xmldata']))) === false) {
283
				log_error(sprintf(gettext("Cannot write %s"), $xml_file));
284
				continue;
285
			}
286
			$output = array();
287
			$status = null;
288
			exec("$rrdtool restore -f '{$xml_file}' '{$rrd_file}'", $output, $status);
289
			if ($status) {
290
				log_error("rrdtool restore -f '{$xml_file}' '{$rrd_file}' failed returning {$status}.");
291
				continue;
292
			}
293
			unlink($xml_file);
294
		} else if ($rrd['data']) {
295
			$rrd_file = "{$g['vardb_path']}/rrd/{$rrd['filename']}";
296
			$rrd_fd = fopen($rrd_file, "w");
297
			if (!$rrd_fd) {
298
				log_error(sprintf(gettext("Cannot write %s"), $rrd_file));
299
				continue;
300
			}
301
			$data = base64_decode($rrd['data']);
302
			/* Try to decompress the data. */
303
			$dcomp = @gzinflate($data);
304
			if ($dcomp) {
305
				/* If the decompression worked, write the decompressed data */
306
				if (fwrite($rrd_fd, $dcomp) === false) {
307
					log_error(sprintf(gettext("fwrite %s failed"), $rrd_file));
308
					continue;
309
				}
310
			} else {
311
				/* If the decompression failed, it wasn't compressed, so write raw data */
312
				if (fwrite($rrd_fd, $data) === false) {
313
					log_error(sprintf(gettext("fwrite %s failed"), $rrd_file));
314
					continue;
315
				}
316
			}
317
			if (fclose($rrd_fd) === false) {
318
				log_error(sprintf(gettext("fclose %s failed"), $rrd_file));
319
				continue;
320
			}
321
		}
322
	}
323
}
324
325 dc22e511 Viktor G
function restore_sshdata($conf = false) {
326
	global $config, $sshConfigDir;
327
328
	if (!$conf) {
329
		$conf = & $config;
330
	}
331
332 49eba660 Viktor G
	$oldmask = umask();
333 dc22e511 Viktor G
	foreach ($conf["sshdata"]["sshkeyfile"] as $sshkey) {
334
		$keypath = "{$sshConfigDir}/{$sshkey['filename']}";
335 49eba660 Viktor G
		if (strstr($sshkey['filename'], 'pub')) {
336
			umask(0133);
337
		} else {
338
			umask(0177);
339
		}
340 dc22e511 Viktor G
		if (file_put_contents($keypath, gzinflate(base64_decode($sshkey['xmldata']))) === false) {
341
			log_error(sprintf(gettext("Cannot write %s"), $sshkey['filename']));
342
			continue;
343
		}
344
	}
345 49eba660 Viktor G
	umask($oldmask);
346 dc22e511 Viktor G
}
347
348 12df7edc Erik
/****f* config/parse_config_bootup
349
 * NAME
350
 *   parse_config_bootup - Bootup-specific configuration checks.
351
 * RESULT
352
 *   null
353
 ******/
354
function parse_config_bootup() {
355 50cafcf3 Ermal
	global $config, $g;
356 12df7edc Erik
357 1e0b1727 Phil Davis
	if (platform_booting()) {
358 02e9880e Ermal
		echo ".";
359 1e0b1727 Phil Davis
	}
360 12df7edc Erik
361
	$lockkey = lock('config');
362 50cafcf3 Ermal
	if (!file_exists("{$g['conf_path']}/config.xml")) {
363 285ef132 Ermal LUÇI
		if (platform_booting()) {
364 60f164f3 Renato Botelho
			$last_backup = discover_last_backup();
365
			if ($last_backup) {
366
				log_error("No config.xml found, attempting last known config restore.");
367
				file_notice("config.xml", gettext("No config.xml found, attempting last known config restore."), "pfSenseConfigurator", "");
368
				restore_backup("/cf/conf/backup/{$last_backup}");
369
			}
370
			if (!file_exists("{$g['conf_path']}/config.xml")) {
371 573ec19d Renato Botelho do Couto
				echo sprintf(gettext("XML configuration file not found.  %s cannot continue booting."), $g['product_label']) . "\n";
372 60f164f3 Renato Botelho
				unlock($lockkey);
373 5fff62d9 Viktor G
				die(gettext("Could not find a usable configuration file or it's backup! Exiting...."));
374 658b4b7f Viktor G
			} else {
375
				log_error("Last known config found and restored.  Please double check the configuration file for accuracy.");
376
				file_notice("config.xml", gettext("Last known config found and restored.  Please double check the configuration file for accuracy."), "pfSenseConfigurator", "");
377 12df7edc Erik
			}
378 50cafcf3 Ermal
		} else {
379
			unlock($lockkey);
380 b5e8282d Ermal
			log_error(gettext("Could not find a usable configuration file! Exiting...."));
381 50cafcf3 Ermal
			exit(0);
382 12df7edc Erik
		}
383
	}
384 50cafcf3 Ermal
385 12df7edc Erik
	if (filesize("{$g['conf_path']}/config.xml") == 0) {
386
		$last_backup = discover_last_backup();
387 1e0b1727 Phil Davis
		if ($last_backup) {
388 4e038d31 Carlos Eduardo Ramos
			log_error(gettext("No config.xml found, attempting last known config restore."));
389
			file_notice("config.xml", gettext("No config.xml found, attempting last known config restore."), "pfSenseConfigurator", "");
390 12df7edc Erik
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
391
		} else {
392
			unlock($lockkey);
393 4e038d31 Carlos Eduardo Ramos
			die(gettext("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup."));
394 12df7edc Erik
		}
395
	}
396
	unlock($lockkey);
397
398 89adb2f3 Ermal
	$config = parse_config(true);
399
400 12df7edc Erik
	if ((float)$config['version'] > (float)$g['latest_config']) {
401
		echo <<<EOD
402
403
404
*******************************************************************************
405
* WARNING!                                                                    *
406 573ec19d Renato Botelho do Couto
* The current configuration has been created with a newer version of {$g['product_label']}  *
407 12df7edc Erik
* than this one! This can lead to serious misbehavior and even security       *
408 573ec19d Renato Botelho do Couto
* holes! You are urged to either upgrade to a newer version of {$g['product_label']} or     *
409 12df7edc Erik
* revert to the default configuration immediately!                            *
410
*******************************************************************************
411
412
413
EOD;
414
		}
415
416
	/* make alias table (for faster lookups) */
417 dbc1b8ee jim-p
	alias_make_table();
418 12df7edc Erik
}
419
420 632f0dbf Renato Botelho
/****f* config/conf_mount_rw
421
 * NAME
422
 *   conf_mount_rw - Mount filesystems read/write.
423
 * RESULT
424
 *   null
425
 ******/
426
/* mount flash card read/write */
427
function conf_mount_rw() {
428 f3f98e97 Phil Davis
	/* Obsoleted. Keep it here until all calls are removed */
429 632f0dbf Renato Botelho
	return;
430
}
431
432
/****f* config/conf_mount_ro
433
 * NAME
434
 *   conf_mount_ro - Mount filesystems readonly.
435
 * RESULT
436
 *   null
437
 ******/
438
function conf_mount_ro() {
439 f3f98e97 Phil Davis
	/* Obsoleted. Keep it here until all calls are removed */
440 632f0dbf Renato Botelho
	return;
441
}
442
443 12df7edc Erik
/****f* config/convert_config
444
 * NAME
445
 *   convert_config - Attempt to update config.xml.
446
 * DESCRIPTION
447
 *   convert_config() reads the current global configuration
448
 *   and attempts to convert it to conform to the latest
449
 *   config.xml version. This allows major formatting changes
450
 *   to be made with a minimum of breakage.
451
 * RESULT
452
 *   null
453
 ******/
454
/* convert configuration, if necessary */
455
function convert_config() {
456
	global $config, $g;
457
	$now = date("H:i:s");
458 4e038d31 Carlos Eduardo Ramos
	log_error(sprintf(gettext("Start Configuration upgrade at %s, set execution timeout to 15 minutes"), $now));
459 59cfe65d Ermal
	//ini_set("max_execution_time", "900");
460 12df7edc Erik
461
	/* special case upgrades */
462
	/* fix every minute crontab bogons entry */
463 32a9eb18 Ermal
	if (is_array($config['cron'])) {
464
		$cron_item_count = count($config['cron']['item']);
465 086cf944 Phil Davis
		for ($x = 0; $x < $cron_item_count; $x++) {
466 1e0b1727 Phil Davis
			if (stristr($config['cron']['item'][$x]['command'], "rc.update_bogons.sh")) {
467 086cf944 Phil Davis
				if ($config['cron']['item'][$x]['hour'] == "*") {
468 1e0b1727 Phil Davis
					$config['cron']['item'][$x]['hour'] = "3";
469 32a9eb18 Ermal
					write_config(gettext("Updated bogon update frequency to 3am"));
470
					log_error(gettext("Updated bogon update frequency to 3am"));
471 1e0b1727 Phil Davis
				}
472 32a9eb18 Ermal
			}
473 12df7edc Erik
		}
474
	}
475
476
	// Save off config version
477
	$prev_version = $config['version'];
478 1e0b1727 Phil Davis
479 b96cad97 Seth Mos
	include_once('auth.inc');
480 12df7edc Erik
	include_once('upgrade_config.inc');
481 1e0b1727 Phil Davis
	if (file_exists("/etc/inc/upgrade_config_custom.inc")) {
482 e58da189 Ermal
		include_once("upgrade_config_custom.inc");
483 1e0b1727 Phil Davis
	}
484 acaafa7f Renato Botelho
485 f6b65ad8 Renato Botelho
	if ($config['version'] == $g['latest_config']) {
486
		additional_config_upgrade();
487
		return;		/* already at latest version */
488
	}
489
490 acaafa7f Renato Botelho
	if (!is_array($config['system']['already_run_config_upgrade'])) {
491
		$config['system']['already_run_config_upgrade'] = array();
492
	}
493 866e537d Renato Botelho
	$already_run = $config['system']['already_run_config_upgrade'];
494 acaafa7f Renato Botelho
495 12df7edc Erik
	/* Loop and run upgrade_VER_to_VER() until we're at current version */
496
	while ($config['version'] < $g['latest_config']) {
497
		$cur = $config['version'] * 10;
498
		$next = $cur + 1;
499 acaafa7f Renato Botelho
		$migration_function = sprintf('upgrade_%03d_to_%03d', $cur,
500
		    $next);
501
502
		foreach (array("", "_custom") as $suffix) {
503
			$migration_function .= $suffix;
504
			if (!function_exists($migration_function)) {
505
				continue;
506
			}
507
			if (isset($already_run[$migration_function])) {
508
				/* Already executed, skip now */
509 866e537d Renato Botelho
				unset($config['system']
510
				    ['already_run_config_upgrade']
511
				    [$migration_function]);
512 acaafa7f Renato Botelho
			} else {
513
				$migration_function();
514
			}
515 1e0b1727 Phil Davis
		}
516 12df7edc Erik
		$config['version'] = sprintf('%.1f', $next / 10);
517 1e0b1727 Phil Davis
		if (platform_booting()) {
518 92cf9fcd sullrich
			echo ".";
519 1e0b1727 Phil Davis
		}
520 12df7edc Erik
	}
521
522 1e0b1727 Phil Davis
	if ($prev_version != $config['version']) {
523 f6b65ad8 Renato Botelho
		$now = date("H:i:s");
524
		log_error(sprintf(gettext("Ended Configuration upgrade at %s"), $now));
525
526 addc0439 Renato Botelho
		write_config(sprintf(gettext('Upgraded config version level from %1$s to %2$s'), $prev_version, $config['version']));
527 1e0b1727 Phil Davis
	}
528 f6b65ad8 Renato Botelho
529
	additional_config_upgrade();
530 12df7edc Erik
}
531
532 ddd42db3 Ermal Lu?i
/****f* config/safe_write_file
533
 * NAME
534
 *   safe_write_file - Write a file out atomically
535
 * DESCRIPTION
536
 *   safe_write_file() Writes a file out atomically by first writing to a
537
 *   temporary file of the same name but ending with the pid of the current
538
 *   process, them renaming the temporary file over the original.
539
 * INPUTS
540
 *   $filename  - string containing the filename of the file to write
541 406ced77 Renato Botelho
 *   $content   - string or array containing the file content to write to file
542 ddd42db3 Ermal Lu?i
 *   $force_binary      - boolean denoting whether we should force binary
543
 *   mode writing.
544
 * RESULT
545
 *   boolean - true if successful, false if not
546
 ******/
547 e717f161 Renato Botelho
function safe_write_file($file, $content, $force_binary = false) {
548 628d1548 Ermal
	$tmp_file = $file . "." . getmypid();
549
	$write_mode = $force_binary ? "wb" : "w";
550 ddd42db3 Ermal Lu?i
551 628d1548 Ermal
	$fd = fopen($tmp_file, $write_mode);
552
	if (!$fd) {
553
		// Unable to open temporary file for writing
554
		return false;
555 1e0b1727 Phil Davis
	}
556 406ced77 Renato Botelho
	if (is_array($content)) {
557
		foreach ($content as $line) {
558
			if (!fwrite($fd, $line . "\n")) {
559
				// Unable to write to temporary file
560
				fclose($fd);
561
				return false;
562
			}
563
		}
564
	} elseif (!fwrite($fd, $content)) {
565 628d1548 Ermal
		// Unable to write to temporary file
566 00bc5bcc Scott Ullrich
		fclose($fd);
567 628d1548 Ermal
		return false;
568
	}
569
	fflush($fd);
570
	fclose($fd);
571 ddd42db3 Ermal Lu?i
572 c03dc57f Renato Botelho
	/* XXX Re-add pfSense_fsync() call here after it's fixed */
573
	// if (!pfSense_fsync($tmp_file) || !rename($tmp_file, $file)) {
574
	if (!rename($tmp_file, $file)) {
575 628d1548 Ermal
		// Unable to move temporary file to original
576
		@unlink($tmp_file);
577
		return false;
578
	}
579 00bc5bcc Scott Ullrich
580 628d1548 Ermal
	// Sync file before returning
581 c5663bf5 Renato Botelho
	//return pfSense_fsync($file);
582
	return true;
583 ddd42db3 Ermal Lu?i
}
584
585 12df7edc Erik
/****f* config/write_config
586
 * NAME
587
 *   write_config - Backup and write the firewall configuration.
588
 * DESCRIPTION
589
 *   write_config() handles backing up the current configuration,
590
 *   applying changes, and regenerating the configuration cache.
591
 * INPUTS
592
 *   $desc	- string containing the a description of configuration changes
593
 *   $backup	- boolean: do not back up current configuration if false.
594 f5315ac1 NOYB
 *   $write_config_only	- boolean: do not sync or reload anything; just save the configuration if true.
595 12df7edc Erik
 * RESULT
596
 *   null
597
 ******/
598
/* save the system configuration */
599 429e0911 NOYB
function write_config($desc="Unknown", $backup = true, $write_config_only = false) {
600 12df7edc Erik
	global $config, $g;
601
602 6f6299a3 Steve Beaver
	// Certain strings may be embedded in the $desc (reason) parameter to trigger certain behavior.
603 f3f98e97 Phil Davis
	// If detected, those strings are removed and a variable set.
604 6f6299a3 Steve Beaver
	$doacb = true;
605
	$manual_acb = false;
606
	$rcnt = 0;
607
608
	$desc = str_replace("-MaNuAlBaCkUp", "", $desc, $rcnt);
609
	if ($rcnt > 0) {
610
		$manual_acb = true; // Manual backups require special processing on the server
611
	}
612
613
	$rcnt = 0;
614
	$desc = str_replace("-NoReMoTeBaCkUp", "", $desc, $rcnt);
615
	if ($rcnt > 0) {
616
		$doacb = false; // No ACB will be performed if this string is detected
617
	}
618
619
	/*
620
	* Syncing vouchers happens every minute and sometimes multiple times. We don't
621
	* want to fill up our db with a lot of the same config so just ignore that case.
622
	*/
623
	if((strpos($desc, 'Syncing vouchers') !== false ||
624
		strpos($desc, 'Captive Portal Voucher database synchronized') !== false) ) {
625
		$doacb = false;
626
	}
627
628 a74260cb jim-p
	if (!empty($_SERVER['REMOTE_ADDR'])) {
629 82cd6022 PiBa-NL
		@phpsession_begin();
630 cf0dae69 Ermal
		if (!empty($_SESSION['Username']) && ($_SESSION['Username'] != "admin")) {
631
			$user = getUserEntry($_SESSION['Username']);
632
			if (is_array($user) && userHasPrivilege($user, "user-config-readonly")) {
633 d629601a jim-p
				syslog(LOG_AUTHPRIV, sprintf(gettext("Save config permission denied by the 'User - Config: Deny Config Write' permission for user '%s'."), get_config_user()));
634 82cd6022 PiBa-NL
				phpsession_end(true);
635 cf0dae69 Ermal
				return false;
636
			}
637 4111fcf5 Ermal
		}
638 82cd6022 PiBa-NL
		if (!isset($argc)) {
639
			phpsession_end(true);
640
		}
641 170cb2bc jim-p
	}
642 4111fcf5 Ermal
643 3dcaae88 Phil Davis
	if (isset($config['reset_factory_defaults'])) {
644
		/*
645
		   We have put a default config.xml on disk and are about to reboot
646
		   or reload it. Do not let any system or package code try to save
647
		   state to config because that would overwrite the default config
648
		   with the running config.
649
		*/
650
		return false;
651
	}
652 4111fcf5 Ermal
653 1e0b1727 Phil Davis
	if ($backup) {
654 12df7edc Erik
		backup_config();
655 1e0b1727 Phil Davis
	}
656 12df7edc Erik
657 b704b6ef Renato Botelho do Couto
	if ($desc == "Unknown") {
658
		file_notice("config.xml", gettext(
659
		    'WARNING: write_config() was called without description'));
660
	}
661 ba1d9714 jim-p
	$config['revision'] = make_config_revision_entry($desc);
662 12df7edc Erik
663 b6c34bfc Ermal
	$lockkey = lock('config', LOCK_EX);
664 12df7edc Erik
665
	/* generate configuration XML */
666
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
667
668 41bf8e8e Scott Ullrich
	/* write new configuration */
669 e717f161 Renato Botelho
	if (!safe_write_file("{$g['cf_conf_path']}/config.xml", $xmlconfig)) {
670 89a8d28e Chris Buechler
		log_error(gettext("WARNING: Config contents could not be saved. Could not open file!"));
671 12df7edc Erik
		unlock($lockkey);
672 1579e70f Phil Davis
		file_notice("config.xml", sprintf(gettext('Unable to open %1$s/config.xml for writing in write_config()%2$s'), $g['cf_conf_path'], "\n"));
673 541989d5 Ermal
		return -1;
674 e5977136 Scott Ullrich
	}
675 1e0b1727 Phil Davis
676 8d51efb6 jim-p
	init_config_arr('syslog');
677
	if ($config['syslog']['logconfigchanges'] != "disabled") {
678
		log_error(gettext("Configuration Change") . ": {$config['revision']['description']}");
679
	}
680
681 e1ebe9e2 jim-p
	cleanup_backupcache(true);
682 12df7edc Erik
683
	/* re-read configuration */
684 541989d5 Ermal
	/* NOTE: We assume that the file can be parsed since we wrote it. */
685 12df7edc Erik
	$config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
686 e490f995 Ermal
	if ($config == -1) {
687 557300a7 jim-p
		copy("{$g['conf_path']}/config.xml", "{$g['conf_path']}/config.xml.bad");
688 e490f995 Ermal
		$last_backup = discover_last_backup();
689 557300a7 jim-p
		if ($last_backup) {
690 e490f995 Ermal
			restore_backup("/cf/conf/backup/{$last_backup}");
691 557300a7 jim-p
			$config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
692 285ef132 Ermal LUÇI
			if (platform_booting()) {
693 557300a7 jim-p
				echo "\n\n ************** WARNING **************";
694 6177fd92 jim-p
				echo "\n\n Configuration could not be validated. A previous configuration was restored. \n";
695 05d5503b Ermal
				echo "\n The failed configuration file has been saved as {$g['conf_path']}/config.xml.bad \n\n";
696 557300a7 jim-p
			}
697 1e0b1727 Phil Davis
		} else {
698 e490f995 Ermal
			log_error(gettext("Could not restore config.xml."));
699 1e0b1727 Phil Davis
		}
700
	} else {
701 e490f995 Ermal
		generate_config_cache($config);
702 1e0b1727 Phil Davis
	}
703 12df7edc Erik
704
	unlock($lockkey);
705
706 429e0911 NOYB
	if ($write_config_only) {
707
		return $config;
708
	}
709
710 12df7edc Erik
	unlink_if_exists("/usr/local/pkg/pf/carp_sync_client.php");
711 16b96ea6 Scott Ullrich
712 12df7edc Erik
	/* sync carp entries to other firewalls */
713 16b96ea6 Scott Ullrich
	carp_sync_client();
714 12df7edc Erik
715 1e0b1727 Phil Davis
	if (is_dir("/usr/local/pkg/write_config")) {
716 12df7edc Erik
		/* process packager manager custom rules */
717
		run_plugins("/usr/local/pkg/write_config/");
718
	}
719
720 587315d5 Steve Beaver
	// Try the core AutoConfigBackup system
721 a1aa91de Steve Beaver
	if (is_array($config['system']['acb']) && $config['system']['acb']['enable'] == "yes" &&
722
	    (!isset($config['system']['acb']['frequency']) || $config['system']['acb']['frequency'] == "every") || file_exists("/tmp/forceacb")) {
723 6f6299a3 Steve Beaver
	    if ($doacb) {
724
			require_once("acb.inc");
725
			upload_config($manual_acb);
726
		}
727
728 a1aa91de Steve Beaver
		if (file_exists("/tmp/forceacb")) {
729
			unlink("/tmp/forceacb");
730
		}
731 587315d5 Steve Beaver
	}
732
733 12df7edc Erik
	return $config;
734
}
735
736
/****f* config/reset_factory_defaults
737
 * NAME
738
 *   reset_factory_defaults - Reset the system to its default configuration.
739
 * RESULT
740
 *   integer	- indicates completion
741
 ******/
742 7d7da5e5 Phil Davis
function reset_factory_defaults($lock = false, $reboot_required = true) {
743 3dcaae88 Phil Davis
	global $config, $g;
744 12df7edc Erik
745 961884ae Renato Botelho
	/* Remove all additional packages */
746 5e8c3fa0 Renato Botelho
	mwexec("/bin/sh /usr/local/sbin/{$g['product_name']}-upgrade " .
747 1220cb90 Renato Botelho
	    "-r ALL_PACKAGES -f");
748 7222324e Renato Botelho
749 1e0b1727 Phil Davis
	if (!$lock) {
750 b6c34bfc Ermal
		$lockkey = lock('config', LOCK_EX);
751 1e0b1727 Phil Davis
	}
752 12df7edc Erik
753
	/* create conf directory, if necessary */
754 5e8c3fa0 Renato Botelho
	safe_mkdir($g['cf_conf_path']);
755 12df7edc Erik
756
	/* clear out /conf */
757
	$dh = opendir($g['conf_path']);
758
	while ($filename = readdir($dh)) {
759 5e8c3fa0 Renato Botelho
		if (($filename != ".") && ($filename != "..") &&
760
		    (!is_dir($g['conf_path'] . "/" . $filename))) {
761 8e2de557 Luiz Otavio O Souza
			if ($filename == "enableserial_force")
762
				continue;
763 12df7edc Erik
			unlink_if_exists($g['conf_path'] . "/" . $filename);
764
		}
765
	}
766
	closedir($dh);
767 63dd9f08 Ermal
	unlink_if_exists($g['tmp_path'] . "/config.cache");
768 12df7edc Erik
769
	/* copy default configuration */
770 5e8c3fa0 Renato Botelho
	copy("{$g['conf_default_path']}/config.xml",
771
	    "{$g['cf_conf_path']}/config.xml");
772 12df7edc Erik
773 0f806eca Erik Fonnesbeck
	disable_security_checks();
774
775 3dcaae88 Phil Davis
	/*
776
	   Let write_config know that we are awaiting reload of the current config
777
	   to factory defaults. Either the system is about to reboot, throwing away
778
	   the current in-memory config as it shuts down, or the in-memory config
779
	   is about to be reloaded on-the-fly by parse_config.
780
781
	   In both cases, we want to ensure that write_config does not flush the
782
	   in-memory config back to disk.
783
	*/
784
	$config['reset_factory_defaults'] = true;
785
786 12df7edc Erik
	/* call the wizard */
787 7d7da5e5 Phil Davis
	if ($reboot_required) {
788
		// If we need a reboot first then touch a different trigger file.
789
		touch("/conf/trigger_initial_wizard_after_reboot");
790
	} else {
791
		touch("/conf/trigger_initial_wizard");
792
	}
793 1e0b1727 Phil Davis
	if (!$lock) {
794 12df7edc Erik
		unlock($lockkey);
795 1e0b1727 Phil Davis
	}
796 749dfdb7 Luiz Souza
	console_configure();
797 12df7edc Erik
	return 0;
798
}
799
800
function config_restore($conffile) {
801
	global $config, $g;
802
803 1e0b1727 Phil Davis
	if (!file_exists($conffile)) {
804 12df7edc Erik
		return 1;
805 1e0b1727 Phil Davis
	}
806 12df7edc Erik
807
	backup_config();
808
809 1e0b1727 Phil Davis
810 b6c34bfc Ermal
	$lockkey = lock('config', LOCK_EX);
811 12df7edc Erik
812
	unlink_if_exists("{$g['tmp_path']}/config.cache");
813 e490f995 Ermal
	copy($conffile, "{$g['cf_conf_path']}/config.xml");
814 12df7edc Erik
815 0f806eca Erik Fonnesbeck
	disable_security_checks();
816
817 12df7edc Erik
	unlock($lockkey);
818
819
	$config = parse_config(true);
820
821
822 d18f3f6e Phil Davis
	write_config(sprintf(gettext("Reverted to %s."), array_pop(explode("/", $conffile))), false);
823 e296b183 Ermal Lu?i
824 12df7edc Erik
	return 0;
825
}
826
827
function config_install($conffile) {
828
	global $config, $g;
829
830 1e0b1727 Phil Davis
	if (!file_exists($conffile)) {
831 12df7edc Erik
		return 1;
832 1e0b1727 Phil Davis
	}
833 12df7edc Erik
834 1e0b1727 Phil Davis
	if (!config_validate("{$conffile}")) {
835 12df7edc Erik
		return 1;
836 1e0b1727 Phil Davis
	}
837 12df7edc Erik
838 1e0b1727 Phil Davis
	if (platform_booting()) {
839 4e038d31 Carlos Eduardo Ramos
		echo gettext("Installing configuration...") . "\n";
840 1e0b1727 Phil Davis
	} else {
841 4e038d31 Carlos Eduardo Ramos
		log_error(gettext("Installing configuration ...."));
842 1e0b1727 Phil Davis
	}
843 12df7edc Erik
844 b6c34bfc Ermal
	$lockkey = lock('config', LOCK_EX);
845 12df7edc Erik
846
	copy($conffile, "{$g['conf_path']}/config.xml");
847
848 0f806eca Erik Fonnesbeck
	disable_security_checks();
849
850 12df7edc Erik
	/* unlink cache file if it exists */
851 1e0b1727 Phil Davis
	if (file_exists("{$g['tmp_path']}/config.cache")) {
852 12df7edc Erik
		unlink("{$g['tmp_path']}/config.cache");
853 1e0b1727 Phil Davis
	}
854 12df7edc Erik
855
	unlock($lockkey);
856
857 1e0b1727 Phil Davis
	return 0;
858 12df7edc Erik
}
859
860 0f806eca Erik Fonnesbeck
/*
861
 * Disable security checks for DNS rebind and HTTP referrer until next time
862
 * they pass (or reboot), to aid in preventing accidental lockout when
863
 * restoring settings like hostname, domain, IP addresses, and settings
864
 * related to the DNS rebind and HTTP referrer checks.
865
 * Intended for use when restoring a configuration or directly
866
 * modifying config.xml without an unconditional reboot.
867
 */
868
function disable_security_checks() {
869
	global $g;
870
	touch("{$g['tmp_path']}/disable_security_checks");
871
}
872
873
/* Restores security checks.  Should be called after all succeed. */
874
function restore_security_checks() {
875
	global $g;
876
	unlink_if_exists("{$g['tmp_path']}/disable_security_checks");
877
}
878
879
/* Returns status of security check temporary disable. */
880
function security_checks_disabled() {
881
	global $g;
882
	return file_exists("{$g['tmp_path']}/disable_security_checks");
883
}
884
885 12df7edc Erik
function config_validate($conffile) {
886
887
	global $g, $xmlerr;
888
889
	$xml_parser = xml_parser_create();
890
891
	if (!($fp = fopen($conffile, "r"))) {
892 4e038d31 Carlos Eduardo Ramos
		$xmlerr = gettext("XML error: unable to open file");
893 12df7edc Erik
		return false;
894
	}
895
896
	while ($data = fread($fp, 4096)) {
897
		if (!xml_parse($xml_parser, $data, feof($fp))) {
898 addc0439 Renato Botelho
			$xmlerr = sprintf(gettext('%1$s at line %2$d'),
899 12df7edc Erik
						xml_error_string(xml_get_error_code($xml_parser)),
900
						xml_get_current_line_number($xml_parser));
901
			return false;
902
		}
903
	}
904
	xml_parser_free($xml_parser);
905
906
	fclose($fp);
907
908
	return true;
909
}
910
911 e1ebe9e2 jim-p
function cleanup_backupcache($lock = false) {
912 caec0e97 jim-p
	global $config, $g;
913 12df7edc Erik
	$i = false;
914 e1ebe9e2 jim-p
915 01b5410a stilez
	$revisions = intval(is_numericint($config['system']['backupcount']) ? $config['system']['backupcount'] : $g['default_config_backup_count']);
916 e1ebe9e2 jim-p
917 1e0b1727 Phil Davis
	if (!$lock) {
918 12df7edc Erik
		$lockkey = lock('config');
919 1e0b1727 Phil Davis
	}
920 cd25a2b2 jim-p
921
922
	$backups = get_backups();
923
	if ($backups) {
924 12df7edc Erik
		$baktimes = $backups['versions'];
925
		unset($backups['versions']);
926 cd25a2b2 jim-p
	} else {
927
		$backups = array();
928
		$baktimes = array();
929
	}
930
	$newbaks = array();
931
	$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
932
	$tocache = array();
933 12df7edc Erik
934 1e0b1727 Phil Davis
	foreach ($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
935 bfe615ee jim-p
		$backupsize = filesize($backup);
936 1e0b1727 Phil Davis
		if ($backupsize == 0) {
937 cd25a2b2 jim-p
			unlink($backup);
938
			continue;
939
		}
940 b3bbed58 Ermal LUÇI
		$backupexp = explode('-', $backup);
941
		$backupexp = explode('.', array_pop($backupexp));
942
		$tocheck = array_shift($backupexp);
943
		unset($backupexp);
944 1e0b1727 Phil Davis
		if (!in_array($tocheck, $baktimes)) {
945 cd25a2b2 jim-p
			$i = true;
946 1e0b1727 Phil Davis
			if (platform_booting()) {
947 cd25a2b2 jim-p
				echo ".";
948 1e0b1727 Phil Davis
			}
949 6153d668 PiBa-NL
			try {
950
				$newxml = parse_xml_config($backup, array($g['xml_rootobj'], 'pfsense'));
951
			} catch (Exception $exc) {
952
				log_error(sprintf(gettext("The backup cache file %s is corrupted. Parser error message: %s"), $backup, $exc->getMessage()));
953
				$newxml = "-1";
954
			}
955
956 1e0b1727 Phil Davis
			if ($newxml == "-1") {
957 4e038d31 Carlos Eduardo Ramos
				log_error(sprintf(gettext("The backup cache file %s is corrupted.  Unlinking."), $backup));
958 cd25a2b2 jim-p
				unlink($backup);
959
				continue;
960 12df7edc Erik
			}
961 1e0b1727 Phil Davis
			if ($newxml['revision']['description'] == "") {
962 cd25a2b2 jim-p
				$newxml['revision']['description'] = "Unknown";
963 1e0b1727 Phil Davis
			}
964
			if ($newxml['version'] == "") {
965 92420c0a jim-p
				$newxml['version'] = "?";
966 1e0b1727 Phil Davis
			}
967 bfe615ee jim-p
			$tocache[$tocheck] = array('description' => $newxml['revision']['description'], 'version' => $newxml['version'], 'filesize' => $backupsize);
968 12df7edc Erik
		}
969 cd25a2b2 jim-p
	}
970 1e0b1727 Phil Davis
	foreach ($backups as $checkbak) {
971
		if (count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
972 cd25a2b2 jim-p
			$newbaks[] = $checkbak;
973
		} else {
974
			$i = true;
975 285ef132 Ermal LUÇI
			if (platform_booting()) print " " . $tocheck . "r";
976 cd25a2b2 jim-p
		}
977
	}
978 1e0b1727 Phil Davis
	foreach ($newbaks as $todo) {
979
		$tocache[$todo['time']] = array('description' => $todo['description'], 'version' => $todo['version'], 'filesize' => $todo['filesize']);
980
	}
981
	if (is_int($revisions) and (count($tocache) > $revisions)) {
982 cd25a2b2 jim-p
		$toslice = array_slice(array_keys($tocache), 0, $revisions);
983 3057a2ba jim-p
		$newcache = array();
984 1e0b1727 Phil Davis
		foreach ($toslice as $sliced) {
985 cd25a2b2 jim-p
			$newcache[$sliced] = $tocache[$sliced];
986 1e0b1727 Phil Davis
		}
987
		foreach ($tocache as $version => $versioninfo) {
988
			if (!in_array($version, array_keys($newcache))) {
989 cd25a2b2 jim-p
				unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
990 12df7edc Erik
			}
991
		}
992 cd25a2b2 jim-p
		$tocache = $newcache;
993 12df7edc Erik
	}
994 cd25a2b2 jim-p
	$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
995
	fwrite($bakout, serialize($tocache));
996
	fclose($bakout);
997 c5663bf5 Renato Botelho
	//pfSense_fsync("{$g['cf_conf_path']}/backup/backup.cache");
998 cd25a2b2 jim-p
999 1e0b1727 Phil Davis
	if (!$lock) {
1000 12df7edc Erik
		unlock($lockkey);
1001 1e0b1727 Phil Davis
	}
1002 12df7edc Erik
}
1003
1004
function get_backups() {
1005
	global $g;
1006 1e0b1727 Phil Davis
	if (file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
1007 12df7edc Erik
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
1008
		$bakvers = array_keys($confvers);
1009
		$toreturn = array();
1010
		sort($bakvers);
1011
		// 	$bakvers = array_reverse($bakvers);
1012 1e0b1727 Phil Davis
		foreach (array_reverse($bakvers) as $bakver) {
1013 bfe615ee jim-p
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description'], 'version' => $confvers[$bakver]['version'], 'filesize' => $confvers[$bakver]['filesize']);
1014 1e0b1727 Phil Davis
		}
1015 12df7edc Erik
	} else {
1016
		return false;
1017
	}
1018
	$toreturn['versions'] = $bakvers;
1019
	return $toreturn;
1020
}
1021
1022
function backup_config() {
1023
	global $config, $g;
1024
1025
1026
	/* Create backup directory if needed */
1027
	safe_mkdir("{$g['cf_conf_path']}/backup");
1028 1e0b1727 Phil Davis
	if ($config['revision']['time'] == "") {
1029
		$baktime = 0;
1030
	} else {
1031
		$baktime = $config['revision']['time'];
1032
	}
1033 8a811010 Chris Buechler
1034 1e0b1727 Phil Davis
	if ($config['revision']['description'] == "") {
1035
		$bakdesc = "Unknown";
1036
	} else {
1037
		$bakdesc = $config['revision']['description'];
1038
	}
1039 8059f9cb jim-p
1040
	$bakver = ($config['version'] == "") ? "?" : $config['version'];
1041 bfe615ee jim-p
	$bakfilename = $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml';
1042
	copy($g['cf_conf_path'] . '/config.xml', $bakfilename);
1043 8a811010 Chris Buechler
1044 1e0b1727 Phil Davis
	if (file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1045
		$backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
1046
	} else {
1047
		$backupcache = array();
1048
	}
1049 bfe615ee jim-p
	$backupcache[$baktime] = array('description' => $bakdesc, 'version' => $bakver, 'filesize' => filesize($bakfilename));
1050 1e0b1727 Phil Davis
	$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1051
	fwrite($bakout, serialize($backupcache));
1052
	fclose($bakout);
1053 c5663bf5 Renato Botelho
	//pfSense_fsync("{$g['cf_conf_path']}/backup/backup.cache");
1054 12df7edc Erik
1055
1056
	return true;
1057
}
1058
1059 db95baf1 Viktor G
function backup_info($backup_info, $number) {
1060
	if ($backup_info['time'] != 0) {
1061
		$date = date(gettext("n/j/y H:i:s"), $backup_info['time']);
1062
	} else {
1063
		$date = gettext("Unknown");
1064
	}
1065
1066
	list($page, $reason) = explode(": ", $backup_info['description'], 2);
1067
	if (empty($reason)) {
1068
		$reason = $page;
1069
		$page = gettext("Unknown Page");
1070
	}
1071
1072
	$backup_info = sprintf("%02d", $number) . ". {$date}\tv{$backup_info['version']}\t{$page}\n";
1073
	if ($reason) {
1074
		$backup_info .= "    {$reason}\n";
1075
	}
1076
	return $backup_info;
1077
}
1078
1079 12df7edc Erik
function set_device_perms() {
1080
	$devices = array(
1081 6c07db48 Phil Davis
		'pf' => array(
1082
			'user' => 'root',
1083
			'group' => 'proxy',
1084
			'mode' => 0660),
1085 12df7edc Erik
		);
1086
1087
	foreach ($devices as $name => $attr) {
1088
		$path = "/dev/$name";
1089
		if (file_exists($path)) {
1090
			chown($path, $attr['user']);
1091
			chgrp($path, $attr['group']);
1092
			chmod($path, $attr['mode']);
1093
		}
1094
	}
1095
}
1096
1097 ba1d9714 jim-p
function get_config_user() {
1098
	if (empty($_SESSION["Username"])) {
1099 362ec35d Ermal
		$username = getenv("USER");
1100 1e0b1727 Phil Davis
		if (empty($conuser) || $conuser == "root") {
1101 ba1d9714 jim-p
			$username = "(system)";
1102 1e0b1727 Phil Davis
		}
1103
	} else {
1104 ba1d9714 jim-p
		$username = $_SESSION["Username"];
1105 1e0b1727 Phil Davis
	}
1106 ba1d9714 jim-p
1107 1e0b1727 Phil Davis
	if (!empty($_SERVER['REMOTE_ADDR'])) {
1108 d629601a jim-p
		$username .= '@' . get_user_remote_address() . get_user_remote_authsource();
1109 1e0b1727 Phil Davis
	}
1110 ba1d9714 jim-p
1111
	return $username;
1112
}
1113
1114
function make_config_revision_entry($desc = null, $override_user = null) {
1115 1e0b1727 Phil Davis
	if (empty($override_user)) {
1116 ba1d9714 jim-p
		$username = get_config_user();
1117 1e0b1727 Phil Davis
	} else {
1118 ba1d9714 jim-p
		$username = $override_user;
1119 1e0b1727 Phil Davis
	}
1120 ba1d9714 jim-p
1121
	$revision = array();
1122
1123 1e0b1727 Phil Davis
	if (time() > mktime(0, 0, 0, 9, 1, 2004)) {     /* make sure the clock settings are plausible */
1124 ba1d9714 jim-p
		$revision['time'] = time();
1125 1e0b1727 Phil Davis
	}
1126 ba1d9714 jim-p
1127
	/* Log the running script so it's not entirely unlogged what changed */
1128 1e0b1727 Phil Davis
	if ($desc == "Unknown") {
1129 ba1d9714 jim-p
		$desc = sprintf(gettext("%s made unknown change"), $_SERVER['SCRIPT_NAME']);
1130 1e0b1727 Phil Davis
	}
1131
	if (!empty($desc)) {
1132 ba1d9714 jim-p
		$revision['description'] = "{$username}: " . $desc;
1133 1e0b1727 Phil Davis
	}
1134 ba1d9714 jim-p
	$revision['username'] = $username;
1135
	return $revision;
1136
}
1137
1138 00e55088 Ermal
function pfSense_clear_globals() {
1139 100b5040 BBcan177
	global $config, $g, $FilterIfList, $GatewaysList, $filterdns, $aliases, $aliastable;
1140 00e55088 Ermal
1141 be2d7eb7 Chris Buechler
	$error = error_get_last();
1142 1e0b1727 Phil Davis
1143 ff4e29fb stilez
	// Errors generated by user code (diag_commands.php) are identified by path and not added to notices
1144 63cbb655 Renato Botelho
	if ($error !== NULL && !preg_match('|^' . preg_quote($g['tmp_path_user_code']) . '/[^/]{1,16}$|', $error['file'])) {
1145 ae346354 PiBa-NL
		if (in_array($error['type'], array(E_ERROR, E_COMPILE_ERROR, E_CORE_ERROR, E_RECOVERABLE_ERROR))) {
1146 be2d7eb7 Chris Buechler
			$errorstr = "PHP ERROR: Type: {$error['type']}, File: {$error['file']}, Line: {$error['line']}, Message: {$error['message']}";
1147 b3f2f476 PiBa-NL
			print($errorstr);
1148
			log_error($errorstr);
1149 ae346354 PiBa-NL
			file_notice("phperror", $errorstr, 'PHP errors');
1150 6c07db48 Phil Davis
		} else if ($error['type'] != E_NOTICE) {
1151 b3f2f476 PiBa-NL
			$errorstr = "PHP WARNING: Type: {$error['type']}, File: {$error['file']}, Line: {$error['line']}, Message: {$error['message']}";
1152 e8e494f3 Chris Buechler
			// XXX: comment out for now, should re-enable post-2.2
1153
			//print($errorstr);
1154
			//log_error($errorstr);
1155 ae346354 PiBa-NL
			//file_notice("phpwarning", $errorstr, 'PHP warning');
1156 be2d7eb7 Chris Buechler
		}
1157
	}
1158
1159 1e0b1727 Phil Davis
	if (isset($FilterIfList)) {
1160 00e55088 Ermal
		unset($FilterIfList);
1161 1e0b1727 Phil Davis
	}
1162 00e55088 Ermal
1163 1e0b1727 Phil Davis
	if (isset($GatewaysList)) {
1164 00e55088 Ermal
		unset($GatewaysList);
1165 1e0b1727 Phil Davis
	}
1166 00e55088 Ermal
1167
	/* Used for the hostname dns resolver */
1168 1e0b1727 Phil Davis
	if (isset($filterdns)) {
1169 00e55088 Ermal
		unset($filterdns);
1170 1e0b1727 Phil Davis
	}
1171 00e55088 Ermal
1172
	/* Used for aliases and interface macros */
1173 1e0b1727 Phil Davis
	if (isset($aliases)) {
1174 00e55088 Ermal
		unset($aliases);
1175 1e0b1727 Phil Davis
	}
1176
	if (isset($aliastable)) {
1177 00e55088 Ermal
		unset($aliastable);
1178 1e0b1727 Phil Davis
	}
1179 00e55088 Ermal
1180
	unset($config);
1181
}
1182
1183 65b5efa7 jim-p
/* Initialize a config array multiple levels deep only if unset
1184
 * Pass it an array of keys to test and create
1185
 * init_config_arr(array('virtualip', 'vip'));
1186
 */
1187
function init_config_arr($keys) {
1188
	global $config;
1189
	$c = &$config;
1190
	if (!is_array($keys)) {
1191
		return null;
1192
	}
1193
	foreach ($keys as $k) {
1194
		if (!is_array($c[$k])) {
1195
			$c[$k] = array();
1196
		}
1197
		$c = &$c[$k];
1198
	}
1199
}
1200
1201 00e55088 Ermal
register_shutdown_function('pfSense_clear_globals');
1202
1203 09221bc3 Renato Botelho
?>