Project

General

Profile

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