Project

General

Profile

Download (23.9 KB) Statistics
| Branch: | Tag: | Revision:
1 12df7edc Erik
<?php
2
/****h* pfSense/config
3
 * NAME
4 032c40c7 Scott Ullrich
 *   config.lib.inc - Functions to manipulate config.xml
5 12df7edc Erik
 * DESCRIPTION
6
 *   This include contains various config.xml specific functions.
7
 * HISTORY
8
 * $Id$
9
 ******
10
11
	config.lib.inc
12
	Ported from config.inc by Erik Kristensen
13 032c40c7 Scott Ullrich
	Copyright (C) 2004-2010 Scott Ullrich
14 12df7edc Erik
	All rights reserved.
15
16
	originally part of m0n0wall (http://m0n0.ch/wall)
17
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
18
	All rights reserved.
19
20
	Redistribution and use in source and binary forms, with or without
21
	modification, are permitted provided that the following conditions are met:
22
23
	1. Redistributions of source code must retain the above copyright notice,
24
	   this list of conditions and the following disclaimer.
25
26
	2. Redistributions in binary form must reproduce the above copyright
27
	   notice, this list of conditions and the following disclaimer in the
28
	   documentation and/or other materials provided with the distribution.
29
30
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
32
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
34
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39
	POSSIBILITY OF SUCH DAMAGE.
40
41
42
	pfSense_BUILDER_BINARIES:	/sbin/mount	/sbin/sysctl	/sbin/umount	/sbin/halt	/sbin/fsck	/bin/sync
43
	pfSense_MODULE:	config
44
*/
45
46
/****f* config/encrypted_configxml
47
 * NAME
48
 *   encrypted_configxml - Checks to see if config.xml is encrypted and if so, prompts to unlock.
49
 * INPUTS
50
 *   None
51
 * RESULT
52
 *   $config 	- rewrites config.xml without encryption
53
 ******/
54
function encrypted_configxml() {
55
	global $g, $config;
56
	if(file_exists($g['conf_path'] . "/config.xml")) {
57
		if($g['booting']) {
58
			$configtxt = file_get_contents($g['conf_path'] . "/config.xml");			
59
			if(tagfile_deformat($configtxt, $configtxt, "config.xml")) {
60
				$fp = fopen('php://stdin', 'r');
61
				$data = "";
62
				echo "\n\n*** Encrypted config.xml detected ***\n";
63
				while($data == "") {
64
					echo "\nEnter the password to decrypt config.xml: ";
65
					$decrypt_password = chop(fgets($fp));
66
					$data = decrypt_data($configtxt, $decrypt_password);
67
					if(!strstr($data, "<pfsense>"))
68
						$data = "";
69
					if($data) {
70 e5977136 Scott Ullrich
						$fd = fopen($g['conf_path'] . "/config.xml.tmp", "w");
71 12df7edc Erik
						fwrite($fd, $data);
72
						fclose($fd);
73 e5977136 Scott Ullrich
						exec("/bin/mv {$g['conf_path']}/config.xml.tmp {$g['conf_path']}/config.xml");
74 12df7edc Erik
						echo "\nConfig.xml unlocked.\n";
75
						fclose($fp);
76
					} else {
77
						echo "\nInvalid password entered.  Please try again.\n";
78
					}
79
				}
80
			}
81
		}
82
	}
83
}
84
85
/****f* config/parse_config
86
 * NAME
87
 *   parse_config - Read in config.cache or config.xml if needed and return $config array
88
 * INPUTS
89
 *   $parse       - boolean to force parse_config() to read config.xml and generate config.cache
90
 * RESULT
91
 *   $config      - array containing all configuration variables
92
 ******/
93 1295e769 Scott Ullrich
function parse_config($parse = false) {
94 4e9a3392 Scott Ullrich
	global $g, $config_parsed, $config_extra;
95 12df7edc Erik
	
96
	$lockkey = lock('config');
97 0af381c2 Scott Ullrich
	$config_parsed = false;
98 12df7edc Erik
	if (!file_exists("{$g['conf_path']}/config.xml") || filesize("{$g['conf_path']}/config.xml") == 0) {
99
		$last_backup = discover_last_backup();
100
		if($last_backup) {
101
			log_error("No config.xml found, attempting last known config restore.");
102
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
103
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
104
		} else {
105
			unlock($lockkey);
106
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
107
		}
108
	}
109
	if($g['booting']) echo ".";
110
	// Check for encrypted config.xml
111
	encrypted_configxml();
112
	if(!$parse) {
113
		if(file_exists($g['tmp_path'] . '/config.cache')) {
114
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
115
			if(is_null($config)) {
116
				unlock($lockkey);
117
				parse_config(true);
118
				$lockkey = lock('config');
119
			}
120
		} else {
121
			if(!file_exists($g['conf_path'] . "/config.xml")) {
122
				log_error("No config.xml found, attempting last known config restore.");
123
				file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
124
				$last_backup = discover_last_backup();
125
				if ($last_backup)
126
					restore_backup("/cf/conf/backup/{$last_backup}");
127
				else
128
					log_error("Could not restore config.xml.");
129
			}
130
			unlock($lockkey);
131
			$config = parse_config(true);
132
			$lockkey = lock('config');
133
		}
134
	} else {
135
		if(!file_exists($g['conf_path'] . "/config.xml")) {
136
			if($g['booting']) echo ".";
137
			log_error("No config.xml found, attempting last known config restore.");
138
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
139
			$last_backup = discover_last_backup();
140
			if ($last_backup)
141
				restore_backup("/cf/conf/backup/{$last_backup}");
142
			else
143
				log_error("Could not restore config.xml.");
144
		}
145
		$config = parse_xml_config($g['conf_path'] . '/config.xml', $g['xml_rootobj']);
146
		if($config == "-1") {
147
			$last_backup = discover_last_backup();
148
			if ($last_backup)
149
				restore_backup("/cf/conf/backup/{$last_backup}");
150
			else
151
				log_error(gettext("Could not restore config.xml."));
152
		}
153
		generate_config_cache($config);
154
	}
155
	if($g['booting']) echo ".";
156
	alias_make_table($config);
157
	$config_parsed = true;
158
	unlock($lockkey);
159
160
	return $config;
161
}
162
163
/****f* config/generate_config_cache
164
 * NAME
165
 *   generate_config_cache - Write serialized configuration to cache.
166
 * INPUTS
167
 *   $config	- array containing current firewall configuration
168
 * RESULT
169
 *   boolean	- true on completion
170
 ******/
171
function generate_config_cache($config) {
172 4e9a3392 Scott Ullrich
	global $g, $config_extra;
173 12df7edc Erik
174
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
175
	fwrite($configcache, serialize($config));
176
	fclose($configcache);
177 4e9a3392 Scott Ullrich
	unset($configcache);
178
	/* Used for config.extra.xml */
179
	if(file_exists($g['tmp_path'] . '/config.extra.cache') && $config_extra) {
180
		$configcacheextra = fopen($g['tmp_path'] . '/config.extra.cache', "w");
181
		fwrite($configcacheextra, serialize($config_extra));
182
		fclose($configcacheextra);		
183
		unset($configcacheextra);
184
	}
185 12df7edc Erik
}
186
187
function discover_last_backup() {
188
        $backups = split("\n", `cd /cf/conf/backup && ls -ltr *.xml | awk '{print \$9}'`);
189
	$last_backup = "";
190
        foreach($backups as $backup)
191
        	if($backup)
192
	        	$last_backup = $backup;
193
194
        return $last_backup;
195
}
196
197
function restore_backup($file) {
198
	global $g;
199
200
	if (file_exists($file)) {
201
		conf_mount_rw();
202
		unlink_if_exists("{$g['tmp_path']}/config.cache");
203 e490f995 Ermal
		copy("$file","/cf/conf/config.xml");
204 12df7edc Erik
		log_error("{$g['product_name']} is restoring the configuration $file");
205
		file_notice("config.xml", "{$g['product_name']} is restoring the configuration $file", "pfSenseConfigurator", "");
206
		conf_mount_ro();
207
	}
208
}
209
210
/****f* config/parse_config_bootup
211
 * NAME
212
 *   parse_config_bootup - Bootup-specific configuration checks.
213
 * RESULT
214
 *   null
215
 ******/
216
function parse_config_bootup() {
217
	global $config, $g, $noparseconfig;
218
219
	if($g['booting']) echo ".";
220
221
	$lockkey = lock('config');
222
	if (!$noparseconfig) {
223
		if (!file_exists("{$g['conf_path']}/config.xml")) {
224
			if ($g['booting']) {
225
				if (strstr($g['platform'], "cdrom")) {
226
					/* try copying the default config. to the floppy */
227
					echo "Resetting factory defaults...\n";
228
					reset_factory_defaults(true);
229
					if (file_exists("{$g['conf_path']}/config.xml")) {
230
						/* do nothing, we have a file. */
231
					} else {
232
						echo "No XML configuration file found - using factory defaults.\n";
233
						echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
234
						echo "file is inserted. If it isn't, your configuration changes will be lost\n";
235
						echo "on reboot.\n";
236
					}
237
				} else {
238
					$last_backup = discover_last_backup();
239
					if($last_backup) {
240
						log_error("No config.xml found, attempting last known config restore.");
241
						file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
242
						restore_backup("/cf/conf/backup/{$last_backup}");
243
					}
244
					if(!file_exists("{$g['conf_path']}/config.xml")) {
245
						echo "XML configuration file not found.  {$g['product_name']} cannot continue booting.\n";
246
						mwexec("/sbin/halt");
247
						exit;
248
					}
249
					log_error("Last known config found and restored.  Please double check your configuration file for accuracy.");
250
					file_notice("config.xml", "Last known config found and restored.  Please double check your configuration file for accuracy.", "pfSenseConfigurator", "");
251
				}
252
			} else {
253
				unlock($lockkey);
254
				exit(0);
255
			}
256
		}
257
	}
258
	if (filesize("{$g['conf_path']}/config.xml") == 0) {
259
		$last_backup = discover_last_backup();
260
		if($last_backup) {
261
			log_error("No config.xml found, attempting last known config restore.");
262
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
263
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
264
		} else {
265
			unlock($lockkey);
266
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
267
		}
268
	}
269
	unlock($lockkey);
270
	parse_config(true);
271
272
	if ((float)$config['version'] > (float)$g['latest_config']) {
273
		echo <<<EOD
274
275
276
*******************************************************************************
277
* WARNING!                                                                    *
278
* The current configuration has been created with a newer version of {$g['product_name']}  *
279
* than this one! This can lead to serious misbehavior and even security       *
280
* holes! You are urged to either upgrade to a newer version of {$g['product_name']} or     *
281
* revert to the default configuration immediately!                            *
282
*******************************************************************************
283
284
285
EOD;
286
		}
287
288
	/* make alias table (for faster lookups) */
289
	alias_make_table($config);
290
}
291
292
/****f* config/conf_mount_rw
293
 * NAME
294
 *   conf_mount_rw - Mount filesystems read/write.
295
 * RESULT
296
 *   null
297
 ******/
298
/* mount flash card read/write */
299
function conf_mount_rw() {
300
	global $g;
301
302
	/* do not mount on cdrom platform */
303
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
304
		return;
305 a45e27ba Ermal
306
	if (refcount_reference(1000) > 1)
307 12df7edc Erik
		return;
308
309
	$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
310
	if($status <> 0) {
311
		if($g['booting'])
312
			echo "Disk is dirty.  Running fsck -y\n";
313
		mwexec("/sbin/fsck -y {$g['cf_path']}");
314
		$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
315
	}
316
317
	/*    if the platform is soekris or wrap or pfSense, lets mount the
318
	 *    compact flash cards root.
319
         */
320 a45e27ba Ermal
	$status = mwexec("/sbin/mount -u -w /");
321
	/* we could not mount this correctly.  kick off fsck */
322
	if($status <> 0) {
323
		log_error("File system is dirty.  Launching FSCK for /");
324
		mwexec("/sbin/fsck -y /");
325 12df7edc Erik
		$status = mwexec("/sbin/mount -u -w /");
326
	}
327
	
328
	mark_subsystem_dirty('mount');
329
}
330
331
/****f* config/conf_mount_ro
332
 * NAME
333
 *   conf_mount_ro - Mount filesystems readonly.
334
 * RESULT
335
 *   null
336
 ******/
337
function conf_mount_ro() {
338
	global $g;
339
340 23f0ca50 Ermal Lu?i
	/* do not umount on cdrom or pfSense platforms */
341
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
342
		return;
343
344 a45e27ba Ermal
	if (refcount_unreference(1000) > 0)
345 12df7edc Erik
		return;
346
347
	clear_subsystem_dirty('mount');
348
	/* sync data, then force a remount of /cf */
349 b6c34bfc Ermal
	mwexec("/bin/sync; /bin/sync");
350 12df7edc Erik
	mwexec("/sbin/mount -u -r -f {$g['cf_path']}");
351
	mwexec("/sbin/mount -u -r -f /");
352
}
353
354
/****f* config/convert_config
355
 * NAME
356
 *   convert_config - Attempt to update config.xml.
357
 * DESCRIPTION
358
 *   convert_config() reads the current global configuration
359
 *   and attempts to convert it to conform to the latest
360
 *   config.xml version. This allows major formatting changes
361
 *   to be made with a minimum of breakage.
362
 * RESULT
363
 *   null
364
 ******/
365
/* convert configuration, if necessary */
366
function convert_config() {
367
	global $config, $g;
368
	$now = date("H:i:s");
369
	log_error("Start Configuration upgrade at $now, set execution timeout to 15 minutes");
370 59cfe65d Ermal
	//ini_set("max_execution_time", "900");
371 12df7edc Erik
372
	/* special case upgrades */
373
	/* fix every minute crontab bogons entry */
374
	$cron_item_count = count($config['cron']['item']);
375
	for($x=0; $x<$cron_item_count; $x++) {
376
		if(stristr($config['cron']['item'][$x]['command'], "rc.update_bogons.sh")) {
377
			if($config['cron']['item'][$x]['hour'] == "*" ) {
378
		        $config['cron']['item'][$x]['hour'] = "3";
379
		 		write_config("Updated bogon update frequency to 3am");
380
		 		log_error("Updated bogon update frequency to 3am");
381
		 	}       
382
		}
383
	}
384
	if ($config['version'] == $g['latest_config'])
385
		return;		/* already at latest version */
386
387
	// Save off config version
388
	$prev_version = $config['version'];
389
	
390 b96cad97 Seth Mos
	include_once('auth.inc');
391 12df7edc Erik
	include_once('upgrade_config.inc');
392
	/* Loop and run upgrade_VER_to_VER() until we're at current version */
393
	while ($config['version'] < $g['latest_config']) {
394
		$cur = $config['version'] * 10;
395
		$next = $cur + 1;
396
		$migration_function = sprintf('upgrade_%03d_to_%03d', $cur, $next);
397
		$migration_function();
398
		$config['version'] = sprintf('%.1f', $next / 10);
399 92cf9fcd sullrich
		if($g['booting'])
400
			echo ".";
401 12df7edc Erik
	}
402
403
	$now = date("H:i:s");
404
	log_error("Ended Configuration upgrade at $now");
405
406
	if ($prev_version != $config['version'])
407
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
408 92cf9fcd sullrich
409
	if($g['booting'])
410
		echo "Loading new configuration...";
411 12df7edc Erik
}
412
413 ddd42db3 Ermal Lu?i
/****f* config/safe_write_file
414
 * NAME
415
 *   safe_write_file - Write a file out atomically
416
 * DESCRIPTION
417
 *   safe_write_file() Writes a file out atomically by first writing to a
418
 *   temporary file of the same name but ending with the pid of the current
419
 *   process, them renaming the temporary file over the original.
420
 * INPUTS
421
 *   $filename  - string containing the filename of the file to write
422
 *   $content   - string containing the file content to write to file
423
 *   $force_binary      - boolean denoting whether we should force binary
424
 *   mode writing.
425
 * RESULT
426
 *   boolean - true if successful, false if not
427
 ******/
428
function safe_write_file($file, $content, $force_binary) {
429
        $tmp_file = $file . "." . getmypid();
430
        $write_mode = $force_binary ? "wb" : "w";
431
432
        $fd = fopen($tmp_file, $write_mode);
433
        if (!$fd) {
434
                // Unable to open temporary file for writing
435
                return false;
436
        }
437
        if (!fwrite($fd, $content)) {
438
                // Unable to write to temporary file
439
                fclose($fd);
440
                return false;
441
        }
442
        fclose($fd);
443
444
        if (!rename($tmp_file, $file)) {
445
                // Unable to move temporary file to original
446
                unlink($tmp_file);
447
                return false;
448
        }
449
        return true;
450
}
451
452 12df7edc Erik
/****f* config/write_config
453
 * NAME
454
 *   write_config - Backup and write the firewall configuration.
455
 * DESCRIPTION
456
 *   write_config() handles backing up the current configuration,
457
 *   applying changes, and regenerating the configuration cache.
458
 * INPUTS
459
 *   $desc	- string containing the a description of configuration changes
460
 *   $backup	- boolean: do not back up current configuration if false.
461
 * RESULT
462
 *   null
463
 ******/
464
/* save the system configuration */
465
function write_config($desc="Unknown", $backup = true) {
466
	global $config, $g;
467
468 027b8057 Erik Fonnesbeck
	/* TODO: Not sure what this was added for; commenting out
469
	 *       for now, since it was preventing config saving. */
470
	// $config = parse_config(true, false, false);
471 4e9a3392 Scott Ullrich
	
472 12df7edc Erik
	if($g['bootup']) 
473
		log_error("WARNING! Configuration written on bootup.  This can cause stray openvpn and load balancing items in config.xml");
474
475
	if($backup)
476
		backup_config();
477
478
	if (time() > mktime(0, 0, 0, 9, 1, 2004))       /* make sure the clock settings are plausible */
479 541989d5 Ermal
		$config['revision']['time'] = time();
480 12df7edc Erik
481
	/* Log the running script so it's not entirely unlogged what changed */
482 42739c1c Ermal Lu?i
	if ($desc == "Unknown")
483 4d52a9b9 jim-p
		$desc = "{$_SERVER['SCRIPT_NAME']} made unknown change";
484 12df7edc Erik
485 4d52a9b9 jim-p
	$config['revision']['description'] = "{$_SESSION['Username']}: " . $desc;
486 362b8147 jim-p
	$config['revision']['username'] = $_SESSION["Username"];
487 12df7edc Erik
488 b6c34bfc Ermal
	conf_mount_rw();
489
	$lockkey = lock('config', LOCK_EX);
490 12df7edc Erik
491
	/* generate configuration XML */
492
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
493
494 41bf8e8e Scott Ullrich
	/* write new configuration */
495
	if (!safe_write_file("{$g['cf_conf_path']}/config.xml", $xmlconfig, false)) {
496 12df7edc Erik
		log_error("WARNING: Config contents could not be save. Could not open file!");
497
		unlock($lockkey);
498 07f1ca1d Ermal
		file_notice("config.xml", "Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
499 541989d5 Ermal
		return -1;
500 e5977136 Scott Ullrich
	}
501 41bf8e8e Scott Ullrich
	
502 12df7edc Erik
	if($g['platform'] == "embedded" or $g['platform'] == "nanobsd") {
503
		cleanup_backupcache(5, true);
504
	} else {
505
		cleanup_backupcache(30, true);
506
	}
507
508
	/* re-read configuration */
509 541989d5 Ermal
	/* NOTE: We assume that the file can be parsed since we wrote it. */
510 12df7edc Erik
	$config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
511 e490f995 Ermal
	if ($config == -1) {
512
		$last_backup = discover_last_backup();
513
		if ($last_backup)
514
			restore_backup("/cf/conf/backup/{$last_backup}");
515
		else
516
			log_error(gettext("Could not restore config.xml."));
517
	} else
518
		generate_config_cache($config);
519 12df7edc Erik
520
	unlock($lockkey);
521
522
	unlink_if_exists("/usr/local/pkg/pf/carp_sync_client.php");
523 16b96ea6 Scott Ullrich
524 b6c34bfc Ermal
	/* tell kernel to sync fs data */
525
	conf_mount_ro();
526
527 12df7edc Erik
	/* sync carp entries to other firewalls */
528 16b96ea6 Scott Ullrich
	carp_sync_client();
529 12df7edc Erik
530
	if(is_dir("/usr/local/pkg/write_config")) {
531
		/* process packager manager custom rules */
532
		run_plugins("/usr/local/pkg/write_config/");
533
	}
534
535
	return $config;
536
}
537
538
/****f* config/reset_factory_defaults
539
 * NAME
540
 *   reset_factory_defaults - Reset the system to its default configuration.
541
 * RESULT
542
 *   integer	- indicates completion
543
 ******/
544
function reset_factory_defaults($lock = false) {
545
	global $g;
546
547
	conf_mount_rw();
548 b6c34bfc Ermal
	if (!$lock)
549
		$lockkey = lock('config', LOCK_EX);
550 12df7edc Erik
551
	/* create conf directory, if necessary */
552
	safe_mkdir("{$g['cf_conf_path']}");
553
554
	/* clear out /conf */
555
	$dh = opendir($g['conf_path']);
556
	while ($filename = readdir($dh)) {
557
		if (($filename != ".") && ($filename != "..")) {
558
			unlink_if_exists($g['conf_path'] . "/" . $filename);
559
		}
560
	}
561
	closedir($dh);
562
563
	/* copy default configuration */
564
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
565
566
	/* call the wizard */
567
	touch("/conf/trigger_initial_wizard");
568
	if (!$lock)
569
		unlock($lockkey);
570 b6c34bfc Ermal
	conf_mount_ro();
571 12df7edc Erik
572
	return 0;
573
}
574
575
function config_restore($conffile) {
576
	global $config, $g;
577
578
	if (!file_exists($conffile))
579
		return 1;
580
581
	backup_config();
582
583 f2087c85 Scott Ullrich
	conf_mount_rw();
584
	
585 b6c34bfc Ermal
	$lockkey = lock('config', LOCK_EX);
586 12df7edc Erik
587
	unlink_if_exists("{$g['tmp_path']}/config.cache");
588 e490f995 Ermal
	copy($conffile, "{$g['cf_conf_path']}/config.xml");
589 12df7edc Erik
590
	unlock($lockkey);
591
592
	$config = parse_config(true);
593
594
	conf_mount_ro();
595
596 e296b183 Ermal Lu?i
	write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
597
598 12df7edc Erik
	return 0;
599
}
600
601
function config_install($conffile) {
602
	global $config, $g;
603
604
	if (!file_exists($conffile))
605
		return 1;
606
607
	if (!config_validate("{$conffile}"))
608
		return 1;
609
610
	if($g['booting'] == true)
611
		echo "Installing configuration...\n";
612
	else
613
		log_error("Installing configuration ....");
614
615
	conf_mount_rw();
616 b6c34bfc Ermal
	$lockkey = lock('config', LOCK_EX);
617 12df7edc Erik
618
	copy($conffile, "{$g['conf_path']}/config.xml");
619
620
	/* unlink cache file if it exists */
621
	if(file_exists("{$g['tmp_path']}/config.cache"))
622
		unlink("{$g['tmp_path']}/config.cache");
623
624
	unlock($lockkey);
625
	conf_mount_ro();
626
627
    return 0;
628
}
629
630
function config_validate($conffile) {
631
632
	global $g, $xmlerr;
633
634
	$xml_parser = xml_parser_create();
635
636
	if (!($fp = fopen($conffile, "r"))) {
637
		$xmlerr = "XML error: unable to open file";
638
		return false;
639
	}
640
641
	while ($data = fread($fp, 4096)) {
642
		if (!xml_parse($xml_parser, $data, feof($fp))) {
643
			$xmlerr = sprintf("%s at line %d",
644
						xml_error_string(xml_get_error_code($xml_parser)),
645
						xml_get_current_line_number($xml_parser));
646
			return false;
647
		}
648
	}
649
	xml_parser_free($xml_parser);
650
651
	fclose($fp);
652
653
	return true;
654
}
655
656
function cleanup_backupcache($revisions = 30, $lock = false) {
657
	global $g;
658
	$i = false;
659
	
660
	if (!$lock)
661
		$lockkey = lock('config');
662 cd25a2b2 jim-p
663
	conf_mount_rw();
664
665
	$backups = get_backups();
666
	if ($backups) {
667 12df7edc Erik
		$baktimes = $backups['versions'];
668
		unset($backups['versions']);
669 cd25a2b2 jim-p
	} else {
670
		$backups = array();
671
		$baktimes = array();
672
	}
673
	$newbaks = array();
674
	$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
675
	$tocache = array();
676 12df7edc Erik
677 cd25a2b2 jim-p
	foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
678
		if(filesize($backup) == 0) {
679
			unlink($backup);
680
			continue;
681
		}
682
		$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));
683
		if(!in_array($tocheck, $baktimes)) {
684
			$i = true;
685
			if($g['booting'])
686
				echo ".";
687
			$newxml = parse_xml_config($backup, $g['xml_rootobj']);
688
			if($newxml == "-1") {
689
				log_error("The backup cache file $backup is corrupted.  Unlinking.");
690
				unlink($backup);
691
				log_error("The backup cache file $backup is corrupted.  Unlinking.");
692
				continue;
693 12df7edc Erik
			}
694 cd25a2b2 jim-p
			if($newxml['revision']['description'] == "")
695
				$newxml['revision']['description'] = "Unknown";
696
			$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
697 12df7edc Erik
		}
698 cd25a2b2 jim-p
	}
699
	foreach($backups as $checkbak) {
700
		if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
701
			$newbaks[] = $checkbak;
702
		} else {
703
			$i = true;
704
			if($g['booting']) print " " . $tocheck . "r";
705
		}
706
	}
707
	foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);
708
	if(is_int($revisions) and (count($tocache) > $revisions)) {
709
		$toslice = array_slice(array_keys($tocache), 0, $revisions);
710
		foreach($toslice as $sliced)
711
			$newcache[$sliced] = $tocache[$sliced];
712
		foreach($tocache as $version => $versioninfo) {
713
			if(!in_array($version, array_keys($newcache))) {
714
				unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
715
				if($g['booting']) print " " . $tocheck . "d";
716 12df7edc Erik
			}
717
		}
718 cd25a2b2 jim-p
		$tocache = $newcache;
719 12df7edc Erik
	}
720 cd25a2b2 jim-p
	$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
721
	fwrite($bakout, serialize($tocache));
722
	fclose($bakout);
723
	conf_mount_ro();
724
725 12df7edc Erik
	if($g['booting'] && $i)
726
		print "done.\n";
727
	if (!$lock)
728
		unlock($lockkey);
729
}
730
731
function get_backups() {
732
	global $g;
733
	if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
734
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
735
		$bakvers = array_keys($confvers);
736
		$toreturn = array();
737
		sort($bakvers);
738
		// 	$bakvers = array_reverse($bakvers);
739
		foreach(array_reverse($bakvers) as $bakver)
740
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description']);
741
	} else {
742
		return false;
743
	}
744
	$toreturn['versions'] = $bakvers;
745
	return $toreturn;
746
}
747
748
function backup_config() {
749
	global $config, $g;
750
751
	if($g['platform'] == "cdrom")
752
		return;
753
754
	conf_mount_rw();
755
756
	/* Create backup directory if needed */
757
	safe_mkdir("{$g['cf_conf_path']}/backup");
758
759
    if($config['revision']['time'] == "") {
760
            $baktime = 0;
761
    } else {
762
            $baktime = $config['revision']['time'];
763
    }
764
    if($config['revision']['description'] == "") {
765
            $bakdesc = "Unknown";
766
    } else {
767
            $bakdesc = $config['revision']['description'];
768
    }
769
    copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
770
    if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
771
            $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
772
    } else {
773
            $backupcache = array();
774
    }
775
    $backupcache[$baktime] = array('description' => $bakdesc);
776
    $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
777
    fwrite($bakout, serialize($backupcache));
778
    fclose($bakout);
779
780
	conf_mount_ro();
781
782
	return true;
783
}
784
785
function set_device_perms() {
786
	$devices = array(
787 573c9548 Ermal
		'pf'	=> array(	'user'	=> 'root',
788 12df7edc Erik
					'group'	=> 'proxy',
789
					'mode'	=> 0660),
790
		);
791
792
	foreach ($devices as $name => $attr) {
793
		$path = "/dev/$name";
794
		if (file_exists($path)) {
795
			chown($path, $attr['user']);
796
			chgrp($path, $attr['group']);
797
			chmod($path, $attr['mode']);
798
		}
799
	}
800
}
801
802 4e9a3392 Scott Ullrich
?>