From: Michal Rakowski Date: Mon, 18 Oct 2021 21:27:51 +0000 (+0200) Subject: Add 'AllowedRestoreDirectories' directive for the FD X-Git-Tag: Beta-15.0.0~805 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=161d2f06aeb6a94517de76bea701c42244fb70e1;p=thirdparty%2Fbacula.git Add 'AllowedRestoreDirectories' directive for the FD --- diff --git a/bacula/src/filed/filed_conf.c b/bacula/src/filed/filed_conf.c index 01583ea28..f34366a4a 100644 --- a/bacula/src/filed/filed_conf.c +++ b/bacula/src/filed/filed_conf.c @@ -159,6 +159,7 @@ static RES_ITEM dir_items[] = { {"AllowedBackupDirectories", store_alist_str, ITEM(res_dir.allowed_backup_dirs), 0, 0, 0}, {"ExlcudedBackupDirectories", store_alist_str, ITEM(res_dir.excluded_backup_dirs), 0, 0, 0}, {"AllowedScriptDirectories", store_alist_str, ITEM(res_dir.allowed_script_dirs), 0, 0, 0}, + {"AllowedRestoreDirectories", store_alist_str, ITEM(res_dir.allowed_restore_dirs), 0, 0, 0}, {NULL, NULL, {0}, 0, 0, 0} }; @@ -548,6 +549,9 @@ void free_resource(RES *sres, int type) if (res->res_dir.allowed_script_dirs) { delete res->res_dir.allowed_script_dirs; } + if (res->res_dir.allowed_restore_dirs) { + delete res->res_dir.allowed_restore_dirs; + } break; case R_CONSOLE: if (res->res_cons.dirinfo.password) { @@ -791,6 +795,7 @@ bool save_resource(CONFIG *config, int type, RES_ITEM *items, int pass) res->res_dir.allowed_backup_dirs = res_all.res_dir.allowed_backup_dirs; res->res_dir.excluded_backup_dirs = res_all.res_dir.excluded_backup_dirs; res->res_dir.allowed_script_dirs = res_all.res_dir.allowed_script_dirs; + res->res_dir.allowed_restore_dirs = res_all.res_dir.allowed_restore_dirs; res->res_dir.console = res_all.res_dir.console; res->res_dir.schedule = res_all.res_dir.schedule; break; diff --git a/bacula/src/filed/filed_conf.h b/bacula/src/filed/filed_conf.h index 413d37abf..0a04872f2 100644 --- a/bacula/src/filed/filed_conf.h +++ b/bacula/src/filed/filed_conf.h @@ -120,6 +120,7 @@ struct DIRRES { alist *allowed_backup_dirs; /* Allowed to-be-backed-up directory list */ alist *excluded_backup_dirs; /* Excluded to-be-backed-up directory list */ alist *allowed_script_dirs; /* Allowed directory list to run scripts/programs from */ + alist *allowed_restore_dirs; /* Allowed directory list to restore to */ }; struct CLIENT { diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 13f5dc3fe..1776fd1cb 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -190,6 +190,7 @@ static char setbandwidth[]= "setbandwidth=%lld Job=%127s"; static char errmsg[] = "2999 Invalid command\n"; static char no_auth[] = "2998 No Authorization\n"; static char invalid_cmd[] = "2997 Invalid command for a Director with Monitor directive enabled.\n"; +static char not_allowed_restore_path[] = "2996 Restore path out of allowed directories.\n"; static char OKBandwidth[] = "2000 OK Bandwidth\n"; static char OKinc[] = "2000 OK include\n"; static char OKest[] = "2000 OK estimate files=%s bytes=%s\n"; @@ -3227,6 +3228,8 @@ static int restore_cmd(JCR *jcr) bool scan_ok = true; int files; int ret = 0; + bool allowed = false; /* Are we going to restore to allowed location */ + char *directory; /** * Scan WHERE (base directory for restore) from command @@ -3300,6 +3303,25 @@ static int restore_cmd(JCR *jcr) Dmsg2(150, "Got replace %c, where=%s\n", replace, args); unbash_spaces(args); + if (jcr->director->allowed_restore_dirs) { + /* Go through the list of allowed directories to restore */ + foreach_alist(directory, jcr->director->allowed_restore_dirs) { + if (fnmatch(directory, args, FNM_LEADING_DIR) == 0) { + allowed = true; + break; + } + } + } else { + /* Directive was not configured at all */ + allowed = true; + } + + if (!allowed) { + Jmsg(jcr, M_FATAL, 0, _("Path not allowed for restore: \"%s\"\n"), args); + dir->fsend(not_allowed_restore_path); + goto free_mempool; + } + /* Keep track of newly created directories to apply them correct attributes */ if (replace == REPLACE_NEVER || replace == REPLACE_IFNEWER) { jcr->keep_path_list = true;