Skip to content

Commit

Permalink
Backup/Restore fixes for dup SSH/RRD. Issue #13132
Browse files Browse the repository at this point in the history
Fixes for multiple SSHDATA or RRDDATA sections in config.xml

* On backup, strip out any existing SSH and RRD data sections before
  adding new ones.
* On restore, remove any empty data sections and if there is more than
  one section, remove all but the most recent one before restoring.
  • Loading branch information
jim-p committed Nov 14, 2022
1 parent 0e6c4d6 commit 6600b09
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions src/usr/local/pfSense/include/www/backup.inc
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,19 @@ function execPost($post, $postfiles, $ui = true) {
}
}

/* If the config on disk contains any rrddata/sshdata tags, remove them to
* avoid forming invalid XML in the resulting backup.
* See Redmine issues:
* https://redmine.pfsense.org/issues/8994
* https://redmine.pfsense.org/issues/10508
* https://redmine.pfsense.org/issues/13132
*/
foreach (array('rrd', 'ssh') as $tag) {
/* Match across multiple lines for the tags and data within to remove */
$data = preg_replace("/[[:blank:]]*<{$tag}data>.*<\\/{$tag}data>[[:blank:]]*\n*/s", "", $data);
$data = preg_replace("/[[:blank:]]*<{$tag}data\\/>[[:blank:]]*\n*/", "", $data);
}

if (($post['backuparea'] != "rrddata") && !$post['donotbackuprrd']) {
$rrd_data_xml = rrd_data_xml();
$closing_tag = "</" . $g['xml_rootobj'] . ">";
Expand Down Expand Up @@ -252,13 +265,28 @@ function execPost($post, $postfiles, $ui = true) {
}
}

/* If the config on disk had empty rrddata/sshdata tags, remove them to
* avoid an XML parsing error.
* See https://redmine.pfsense.org/issues/8994
* and https://redmine.pfsense.org/issues/13132 */
/* If the config on disk contains duplicate or empty rrddata/sshdata
* tags, remove them to avoid XML parsing errors.
* See Redmine issues
* https://redmine.pfsense.org/issues/8994
* https://redmine.pfsense.org/issues/10508
* https://redmine.pfsense.org/issues/13132
*/
foreach (array('rrd', 'ssh') as $tag) {
/* Look for empty tags (no data) */
$data = preg_replace("/<{$tag}data><\\/{$tag}data>/", "", $data);
$data = preg_replace("/<{$tag}data\\/>/", "", $data);
/* Match across multiple lines for the tags and data within to remove,
* but use an ungreedy match and a limit to ensure only the most
* recent entry is retained.
*/
$data_pattern = "/[[:blank:]]*<{$tag}data>.*<\\/{$tag}data>[[:blank:]]*\n*/sU";
$dmatch = [];
preg_match_all($data_pattern, $data, $dmatch);
/* More than one match, so remove all but one. */
if (count($dmatch[0]) > 1) {
$data = preg_replace($data_pattern, "", $data, (count($dmatch[0]) - 1));
}
}

if ($post['restorearea'] && !$input_errors) {
Expand Down

0 comments on commit 6600b09

Please sign in to comment.