{"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}
};
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) {
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;
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 {
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";
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
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;