]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add 'AllowedRestoreDirectories' directive for the FD
authorMichal Rakowski <michal.rakowski@baculasystems.com>
Mon, 18 Oct 2021 21:27:51 +0000 (23:27 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 14 Sep 2023 11:56:56 +0000 (13:56 +0200)
bacula/src/filed/filed_conf.c
bacula/src/filed/filed_conf.h
bacula/src/filed/job.c

index 01583ea28f42a30163e9dd907981bdf337128996..f34366a4ad1751da31cb3eff1d5a09d5f1333354 100644 (file)
@@ -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;
index 413d37abfc31a2728b023e8a6f2838311d4eb9a4..0a04872f242aa219ede222b4c9262c72109458dc 100644 (file)
@@ -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 {
index 13f5dc3fe177eb78baa5def4e91e27f7a8424dba..1776fd1cbcbc1c58cb230858927cec8cf9d45f3c 100644 (file)
@@ -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;