]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix #9968 Adapt restore menu and add RBCLIENT/BCLIENT in some ACL SQL checking
authorEric Bollengier <eric@baculasystems.com>
Tue, 21 Mar 2023 10:17:21 +0000 (11:17 +0100)
committerEric Bollengier <eric@baculasystems.com>
Tue, 2 May 2023 07:07:18 +0000 (09:07 +0200)
 - menu 9
 - menu 8
 - menu 12
 - menu 13

bacula/src/cats/sql_cmds.c
bacula/src/cats/sql_get.c
bacula/src/cats/sql_list.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_dotcmds.c
bacula/src/dird/ua_restore.c
bacula/src/dird/ua_select.c

index af0e203eb13587b397fbe5d0b33b685c51a37c55..ad558484eba939d696bd2dfe5385d3f18509a1d8 100644 (file)
@@ -121,16 +121,14 @@ const char *uar_del_temp1 = "DROP TABLE IF EXISTS temp1";
 
 const char *uar_last_full =
    "INSERT INTO temp1(JobId,JobTDate) SELECT Job.JobId,JobTdate "
-   "FROM Client,Job,JobMedia,Media,FileSet WHERE Client.ClientId=%s "
-   "AND Job.ClientId=%s "
+   "FROM Client JOIN Job USING (ClientId) JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) JOIN FileSet USING (FileSetId) "
+   "WHERE Client.ClientId=%s "
    "AND Job.StartTime < '%s' "
    "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' "
-   "AND JobMedia.JobId=Job.JobId "
    "AND Media.Enabled=1 "
-   "AND JobMedia.MediaId=Media.MediaId "
-   "AND Job.FileSetId=FileSet.FileSetId "
    "AND FileSet.FileSet='%s' "
-   "%s"
+   " %s "                       // Pool select
+   " %s "                       // ACL restriction
    "ORDER BY Job.JobTDate DESC LIMIT 1";
 
 const char *uar_full =
@@ -151,16 +149,14 @@ const char *uar_dif =
    "Job.Level,Job.JobFiles,Job.JobBytes,"
    "Job.StartTime,Media.VolumeName,JobMedia.StartFile,"
    "Job.VolSessionId,Job.VolSessionTime "
-   "FROM Job,JobMedia,Media,FileSet "
+   "FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) JOIN FileSet USING (FileSetId) %s "
    "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' "
    "AND Job.ClientId=%s "
-   "AND JobMedia.JobId=Job.JobId "
    "AND Media.Enabled=1 "
-   "AND JobMedia.MediaId=Media.MediaId "
    "AND Job.Level='D' AND JobStatus IN ('T','W') AND Type='B' "
-   "AND Job.FileSetId=FileSet.FileSetId "
    "AND FileSet.FileSet='%s' "
-   "%s"
+   " %s "                       // POOL select
+   " %s "                       // ACL restriction
    "ORDER BY Job.JobTDate DESC LIMIT 1";
 
 const char *uar_inc =
@@ -169,16 +165,15 @@ const char *uar_inc =
    "Job.Level,Job.JobFiles,Job.JobBytes,"
    "Job.StartTime,Media.VolumeName,JobMedia.StartFile,"
    "Job.VolSessionId,Job.VolSessionTime "
-   "FROM Job,JobMedia,Media,FileSet "
+   "FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) JOIN FileSet USING (FileSetId) %s "
    "WHERE Job.JobTDate>%s AND Job.StartTime<'%s' "
    "AND Job.ClientId=%s "
    "AND Media.Enabled=1 "
-   "AND JobMedia.JobId=Job.JobId "
-   "AND JobMedia.MediaId=Media.MediaId "
    "AND Job.Level='I' AND JobStatus IN ('T','W') AND Type='B' "
-   "AND Job.FileSetId=FileSet.FileSetId "
    "AND FileSet.FileSet='%s' "
-   "%s";
+   " %s "                       // Pool select
+   " %s "                       // ACL
+   ;
 
 const char *uar_list_temp =
    "SELECT DISTINCT JobId,Level,JobFiles,JobBytes,StartTime,VolumeName"
@@ -197,9 +192,8 @@ const char *uar_sel_all_temp = "SELECT * FROM temp";
 
 /* Select FileSet names for this Client */
 const char *uar_sel_fileset =
-   "SELECT DISTINCT FileSet.FileSet FROM Job,"
-   "Client,FileSet WHERE Job.FileSetId=FileSet.FileSetId "
-   "AND Job.ClientId=%s AND Client.ClientId=%s "
+   "SELECT DISTINCT FileSet.FileSet FROM Job JOIN Client USING (ClientId) JOIN FileSet USING (FileSetId) "
+   "WHERE Client.ClientId=%s %s "
    "ORDER BY FileSet.FileSet";
 
 /* Select all different FileSet for this client
@@ -218,27 +212,25 @@ const char *uar_sel_filesetid =
  *  for use when inserting individual files into the tree.
  */
 const char *uar_jobid_fileindex =
-   "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Client "
-   "WHERE Job.JobId=File.JobId "
-   "AND Job.StartTime<='%s' "
+   "SELECT Job.JobId,File.FileIndex "
+   "FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) JOIN Client USING (ClientId) "
+   "WHERE Job.StartTime<='%s' "
    "AND Path.Path='%s' "
    "AND File.Filename='%s' "
    "AND Client.Name='%s' "
-   "AND Job.ClientId=Client.ClientId "
-   "AND Path.PathId=File.PathId "
    "AND JobStatus IN ('T','W') AND Type='B' "
+   " %s "                       // ACL
    "ORDER BY Job.StartTime DESC LIMIT 1";
 
 const char *uar_jobids_fileindex =
-   "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Client "
+   "SELECT Job.JobId,File.FileIndex "
+   "FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) JOIN Client USING (ClientId) "
    "WHERE Job.JobId IN (%s) "
-   "AND Job.JobId=File.JobId "
    "AND Job.StartTime<='%s' "
    "AND Path.Path='%s' "
    "AND File.Filename='%s' "
    "AND Client.Name='%s' "
-   "AND Job.ClientId=Client.ClientId "
-   "AND Path.PathId=File.PathId "
+   " %s " // ACL
    "ORDER BY Job.StartTime DESC LIMIT 1";
 
 /* Query to get list of files from table -- presuably built by an external program
@@ -621,32 +613,27 @@ const char *uar_create_temp1[] =
 const char *uar_jobid_fileindex_from_dir[] =
 {
    /* MySQL */
-   "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Client "
+   "SELECT Job.JobId,File.FileIndex FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) JOIN Client USING (ClientId) "
    "WHERE Job.JobId IN (%s) "
-   "AND Job.JobId=File.JobId "
    "AND Path.Path='%s' "
    "AND Client.Name='%s' "
-   "AND Job.ClientId=Client.ClientId "
-   "AND Path.PathId=File.Pathid "
+   " %s "
    "GROUP BY File.FileIndex ORDER BY Job.StartTime",
  
    /* PostgreSQL */
-   "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Client "
+   "SELECT Job.JobId,File.FileIndex FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) JOIN Client USING (ClientId) "
    "WHERE Job.JobId IN (%s) "
-   "AND Job.JobId=File.JobId "
    "AND Path.Path='%s' "
    "AND Client.Name='%s' "
-   "AND Job.ClientId=Client.ClientId "
-   "AND Path.PathId=File.Pathid ORDER BY Job.StartTime ",
+   " %s "
+   "ORDER BY Job.StartTime ",
  
    /* SQLite */
-   "SELECT Job.JobId,File.FileIndex FROM Job,File,Path,Client "
+   "SELECT Job.JobId,File.FileIndex FROM Job JOIN File USING (JobId) JOIN Path USING (PathId) JOIN Client USING (ClientId) "
    "WHERE Job.JobId IN (%s) "
-   "AND Job.JobId=File.JobId "
    "AND Path.Path='%s' "
    "AND Client.Name='%s' "
-   "AND Job.ClientId=Client.ClientId "
-   "AND Path.PathId=File.Pathid "
+   " %s "
    "GROUP BY File.FileIndex ORDER BY Job.StartTime "
 }; 
  
index aa58906535baefff72dc18e302f371d62271595c..64b75217d910dbc4989474c3b3abe6ba66ebd069 100644 (file)
@@ -2001,7 +2001,7 @@ bool BDB::bdb_get_client_pool(JCR *jcr, alist *results)
    bdb_lock();
 
    /* Build the WHERE part with the current ACLs if any */
-   pm_strcpy(where, get_acls(DB_ACL_BIT(DB_ACL_CLIENT)  |
+   pm_strcpy(where, get_acls(DB_ACL_BIT(DB_ACL_CLIENT)  | // TODO: See if we let Backup Client here (for pruning)
                              DB_ACL_BIT(DB_ACL_JOB)     |
                              DB_ACL_BIT(DB_ACL_POOL),
                              true));
index cb74f1e2cc643e0979cdc4ac065a45f965e0a4c7..ce111abebcc477bf1b59c6d790834c12a13eb576 100644 (file)
@@ -112,10 +112,10 @@ void BDB::bdb_list_client_records(JCR *jcr, DB_LIST_HANDLER *sendit, void *ctx,
    if (type == VERT_LIST || type == JSON_LIST) {
       Mmsg(cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,"
          "JobRetention "
-           "FROM Client %s ORDER BY ClientId", get_acl(DB_ACL_BCLIENT, true));
+           "FROM Client %s ORDER BY ClientId", get_acls(DB_ACL_BIT(DB_ACL_RBCLIENT), true));
    } else {
       Mmsg(cmd, "SELECT ClientId,Name,FileRetention,JobRetention "
-           "FROM Client %s ORDER BY ClientId", get_acl(DB_ACL_BCLIENT, true));
+           "FROM Client %s ORDER BY ClientId", get_acls(DB_ACL_BIT(DB_ACL_RBCLIENT), true));
    }
    if (!QueryDB(jcr, cmd)) {
       bdb_unlock();
@@ -649,14 +649,13 @@ void BDB::bdb_list_joblog_records(JCR *jcr, uint32_t JobId,
 
    const char *where = get_acls(DB_ACL_BIT(DB_ACL_JOB)     |
                                 DB_ACL_BIT(DB_ACL_FILESET) |
-                                DB_ACL_BIT(DB_ACL_BCLIENT) |
-                                DB_ACL_BIT(DB_ACL_RCLIENT)
+                                DB_ACL_BIT(DB_ACL_RBCLIENT) 
                                 , false);
 
    const char *join = *where ? get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB)     |
                                                    DB_ACL_BIT(DB_ACL_FILESET) |
-                                                   DB_ACL_BIT(DB_ACL_CLIENT)) : "";
-
+                                                   DB_ACL_BIT(DB_ACL_RBCLIENT)) : "";
+   
    if (type == VERT_LIST || type == JSON_LIST) {
       Mmsg(cmd, "SELECT Time,LogText FROM Log %s "
            "WHERE Log.JobId=%s %s ORDER BY LogId ASC",
@@ -774,7 +773,7 @@ alist *BDB::bdb_list_job_records(JCR *jcr, JOB_DBR *jr, DB_LIST_HANDLER *sendit,
    pm_strcat(where, where_tmp);
 
    if (*where_tmp) {
-      join = get_acl_join_filter(DB_ACL_BIT(DB_ACL_BCLIENT)  |
+      join = get_acl_join_filter(DB_ACL_BIT(DB_ACL_RBCLIENT)  |
                                  DB_ACL_BIT(DB_ACL_FILESET));
    }
 
index 8d5c9d638efd738314eb07c5fad818d513c4e325..a5bcbedb7865d22e0957edaf6d4ad2c21ceb41ed 100644 (file)
@@ -2239,6 +2239,7 @@ static int delete_a_volume(UAContext *ua, MEDIA_DBR *mr)
 
    /* If not purged, do it */
    if (strcmp(mr->VolStatus, "Purged") != 0) {
+      /* We don't filter here because we need to know the complete jobid list as well */
       if (!db_get_volume_jobids(ua->jcr, ua->db, mr, &lst)) {
          ua->error_msg(_("Can't list jobs on this volume\n"));
          return 1;
index 9a4080806b2730cc24af949329e2063c36a178eb..012b6397165fcd066d3c07c2c67d3f5c6d5b34ad 100644 (file)
@@ -1536,6 +1536,7 @@ static bool dot_bvfs_get_jobids(UAContext *ua, const char *cmd)
       edit_int64(jr.ClientId, ed1);
       Mmsg(query, uar_sel_filesetid, ed1);
       db_get_query_dbids(ua->jcr, ua->db, query, ids);
+
    } else {
       ids.num_ids = 1;
       ids.DBId[0] = jr.FileSetId;
index 92626418414addf3c605489071c8a93c97558890..177ac6cde9508482b8e0e0032b056f3672caeadd 100644 (file)
@@ -573,22 +573,12 @@ static int select_files_from_plugin_obj(UAContext *ua, OBJECT_DBR *obj_r, RESTOR
    }
 
    if (!acl_access_ok(ua, Job_ACL, jr.Name)) {
-      ua->error_msg(_("Access to JobId=%d (Job \"%s\") not authorized.\n"),
-            jr.JobId, jr.Name);
+      ua->error_msg(_("Access to Job \"%s\" not authorized.\n"), jr.Name);
       return 0;
    }
 
-   CLIENT_DBR cr;
-   cr.ClientId = jr.ClientId;
-   if (!db_get_client_record(ua->jcr, ua->db, &cr)) {
-      ua->error_msg(_("Unable to get Job record for JobId=%s: ERR=%s\n"),
-                    ua->cmd, db_strerror(ua->db));
-      return 0;
-   }
-
-   if (!acl_access_ok(ua, Client_ACL, cr.Name)) {
-      ua->error_msg(_("Access to ClientId=%d not authorized.\n"),
-            jr.ClientId);
+   if (!acl_access_ok(ua, Client_ACL, jr.Client)) {
+      ua->error_msg(_("Access to Client not authorized.\n"));
       return 0;
    }
 
@@ -1036,13 +1026,18 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
                           ua->cmd, db_strerror(ua->db));
             return 0;
          }
-         ua->send_msg(_("Selecting jobs to build the Full state at %s\n"),
-                      jr.cStartTime);
          jr.JobLevel = L_INCREMENTAL; /* Take Full+Diff+Incr */
          if (!db_get_accurate_jobids(ua->jcr, ua->db, &jr, &jobids)) {
             return 0;
          }
-         pm_strcpy(rx->JobIds, jobids.list);
+         /* Apply ACL filters to the JobId list we got */
+         db_get_jobids(ua->jcr, ua->db, jobids.list, &rx->JobIds, false);
+         if(*rx->JobIds == 0) {
+            ua->error_msg(_("Unable to get Job record for JobId=%s\n"), ua->cmd);
+            return 0;
+         }
+         ua->send_msg(_("Selecting jobs to build the Full state at %s\n"),
+                      jr.cStartTime);
          Dmsg1(30, "Item 12: jobids = %s\n", rx->JobIds);
          break;
 
@@ -1080,20 +1075,32 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
             POOL_MEM esc_cat, esc_type;
             char *cat = (char*)types[0].get(idx);
             char *type = (char*)types[1].get(idx);
+            const char *join, *where;
             esc_cat.check_size(strlen(cat)*2+1);
             esc_type.check_size(strlen(type)*2+1);
 
-            /* TODO: Check if we need db_lock() */
+            db_lock(ua->db);
             db_escape_string(ua->jcr, ua->db, esc_cat.c_str(), cat, strlen(cat));
             db_escape_string(ua->jcr, ua->db, esc_type.c_str(), type, strlen(type));
 
-            Mmsg(query, "SELECT DISTINCT ObjectName FROM Object WHERE ObjectCategory='%s' AND ObjectType='%s' ORDER BY ObjectName ASC",
-                 esc_cat.c_str(), esc_type.c_str());
+            /* Get optional filters for the SQL query */
+            where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+                                     DB_ACL_BIT(DB_ACL_BCLIENT) |
+                                     DB_ACL_BIT(DB_ACL_FILESET), false);
+
+            join = *where ? ua->db->get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) |
+                                                        DB_ACL_BIT(DB_ACL_BCLIENT)  |
+                                                        DB_ACL_BIT(DB_ACL_FILESET)) : "";
+
+            Mmsg(query, "SELECT DISTINCT ObjectName FROM Object %s WHERE ObjectCategory='%s' AND ObjectType='%s' %s ORDER BY ObjectName ASC",
+                 join, esc_cat.c_str(), esc_type.c_str(), where);
 
             if (!db_sql_query(ua->db, query.c_str(), db_string_list_handler, &alist_ptr)) {
                ua->error_msg(_("SQL Query failed: %s\n"), db_strerror(ua->db));
+               db_unlock(ua->db);
                return 0;
             }
+            db_unlock(ua->db);
 
             Mmsg(tmp, "List of the %s %s Objects:\n", types[1].get(idx), types[0].get(idx));
             start_prompt(ua, tmp.c_str());
@@ -1108,20 +1115,33 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
 
             ua->info_msg(_("Objects available:\n"));
             esc.check_size(strlen((char*)object_list.get(idx))*2+1);
+
+            db_lock(ua->db);
+
+            /* Get optional filters for the SQL query */
+            where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+                                     DB_ACL_BIT(DB_ACL_BCLIENT) |
+                                     DB_ACL_BIT(DB_ACL_FILESET), false);
+
+            join = *where ? ua->db->get_acl_join_filter(DB_ACL_BIT(DB_ACL_FILESET)) : "";
+
             db_escape_string(ua->jcr, ua->db, esc.c_str(),
                              (char*)object_list.get(idx), strlen((char*)object_list.get(idx)));
+
             Mmsg(query, "SELECT Object.ObjectId AS ObjectId, Object.ObjectName AS ObjectName, Client.Name as Client, "
                                 "Object.ObjectSource AS ObjectSource, "
                                "Job.StartTime AS StartTime, Object.ObjectSize AS ObjectSize "
                         "FROM Object JOIN Job USING (JobId) "
-                        "JOIN Client ON (Job.ClientId = Client.ClientId) "
-                        "WHERE Object.ObjectName='%s' AND Object.ObjectCategory='%s' AND Object.ObjectType='%s'",
-                 esc.c_str(), esc_cat.c_str(), esc_type.c_str());
+                        "JOIN Client ON (Job.ClientId = Client.ClientId) %s "
+                        "WHERE Object.ObjectName='%s' AND Object.ObjectCategory='%s' AND Object.ObjectType='%s' %s",
+                 join, esc.c_str(), esc_cat.c_str(), esc_type.c_str(), where);
 
             if (!db_list_sql_query(ua->jcr, ua->db, "object", query.c_str(), prtit, ua, 0, HORZ_LIST)) {
                ua->error_msg(_("SQL Query failed: %s\n"), db_strerror(ua->db));
+               db_unlock(ua->db);
                return 0;
             }
+            db_unlock(ua->db);
 
             //TODO Validation if id entered matches one from list above would be nice...
             if (!get_pint(ua, _("Enter ID of Object to be restored: "))) {
@@ -1282,12 +1302,16 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f
 {
    strip_trailing_newline(file);
    split_path_and_filename(ua, rx, file);
+
+   db_lock(ua->db);
+   /* Client is fixed */
+   const char *where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB), false);
    if (*rx->JobIds == 0) {
       Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname,
-           rx->ClientName);
+           rx->ClientName, where);
    } else {
       Mmsg(rx->query, uar_jobids_fileindex, rx->JobIds, date,
-           rx->path, rx->fname, rx->ClientName);
+           rx->path, rx->fname, rx->ClientName, where);
       /*
        * Note: we have just edited the JobIds into the query, so
        *  we need to clear JobIds, or they will be added
@@ -1303,9 +1327,9 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f
       ua->error_msg(_("Query failed: %s. ERR=%s\n"),
          rx->query, db_strerror(ua->db));
    }
+   db_unlock(ua->db);
    if (!rx->found) {
       ua->error_msg(_("No database record found\n"));
-//    ua->error_msg("Query=%s\n", rx->query);
       return false;
    }
    return true;
@@ -1318,13 +1342,19 @@ static bool insert_file_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *f
 static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *dir,
                                         char *date)
 {
+   int ret = false;
    strip_trailing_junk(dir);
    if (*rx->JobIds == 0) {
       ua->error_msg(_("No JobId specified cannot continue.\n"));
       return false;
-   } else {
-      Mmsg(rx->query, uar_jobid_fileindex_from_dir[db_get_type_index(ua->db)], rx->JobIds, dir, rx->ClientName);
    }
+
+   db_lock(ua->db);
+   /* Client is fixed */
+   const char *where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB), false);
+
+   Mmsg(rx->query, uar_jobid_fileindex_from_dir[db_get_type_index(ua->db)],
+        rx->JobIds, dir, rx->ClientName, where);
    rx->found = false;
 
    /* Find and insert jobid and File Index */
@@ -1334,9 +1364,12 @@ static bool insert_dir_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *di
    }
    if (!rx->found) {
       ua->error_msg(_("No database record found\n"));
-      return false;
+
+   } else {
+      ret = true;
    }
-   return true;
+   db_unlock(ua->db);
+   return ret;
 }
 
 struct component_file_ctx
@@ -1370,11 +1403,11 @@ bool insert_table_into_findex_list(UAContext *ua, RESTORE_CTX *rx, char *table)
    {
       /* Get optional filters for the SQL query */
       const char *where = ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB) |
-                                           DB_ACL_BIT(DB_ACL_CLIENT) |
+                                           DB_ACL_BIT(DB_ACL_BCLIENT) |
                                            DB_ACL_BIT(DB_ACL_FILESET), true);
 
       const char *join = *where ? ua->db->get_acl_join_filter(DB_ACL_BIT(DB_ACL_JOB) |
-                                                              DB_ACL_BIT(DB_ACL_CLIENT)  |
+                                                              DB_ACL_BIT(DB_ACL_BCLIENT)  |
                                                               DB_ACL_BIT(DB_ACL_FILESET)) : "";
 
       Mmsg(rx->query, uar_jobid_fileindex_from_table, table, join, where);
@@ -1755,25 +1788,15 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
    char fileset_name[MAX_NAME_LENGTH];
    char ed1[50], ed2[50];
    char pool_select[MAX_NAME_LENGTH];
+   POOL_MEM where, join;
    int i;
 
-   /* Create temp tables */
-   db_sql_query(ua->db, uar_del_temp, NULL, NULL);
-   db_sql_query(ua->db, uar_del_temp1, NULL, NULL);
-   if (!db_sql_query(ua->db, uar_create_temp[db_get_type_index(ua->db)], NULL, NULL)) {
-      ua->error_msg("%s\n", db_strerror(ua->db));
-      goto bail_out;
-   }
-   if (!db_sql_query(ua->db, uar_create_temp1[db_get_type_index(ua->db)], NULL, NULL)) {
-      ua->error_msg("%s\n", db_strerror(ua->db));
-      goto bail_out;
-   }
    /*
     * Select Client from the Catalog
     */
    memset(&cr, 0, sizeof(cr));
    if (!get_client_dbr(ua, &cr, JT_BACKUP_RESTORE)) {
-      goto bail_out;
+      return false;
    }
    bstrncpy(rx->ClientName, cr.Name, sizeof(rx->ClientName));
 
@@ -1784,6 +1807,9 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
    i = find_arg_with_value(ua, "FileSet");
 
    if (i >= 0 && is_name_valid(ua->argv[i], &ua->errmsg)) {
+      if (!acl_access_ok(ua, FileSet_ACL, ua->argv[i])) {
+         return false;
+      }
       bstrncpy(fsr.FileSet, ua->argv[i], sizeof(fsr.FileSet));
       if (!db_get_fileset_record(ua->jcr, ua->db, &fsr)) {
          ua->error_msg(_("Error getting FileSet \"%s\": ERR=%s\n"), fsr.FileSet,
@@ -1792,14 +1818,27 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
       }
    } else if (i >= 0) {         /* name is invalid */
       ua->error_msg(_("FileSet argument: %s\n"), ua->errmsg);
-      goto bail_out;
+      return false;
    }
 
+   /* ACL checks, keep a local copy to not hold the lock too much */
+   db_lock(ua->db);
+   {
+      pm_strcpy(where, ua->db->get_acls(DB_ACL_BIT(DB_ACL_JOB) |
+                                        DB_ACL_BIT(DB_ACL_BCLIENT) |
+                                        DB_ACL_BIT(DB_ACL_FILESET), false));
+
+      if (*where.c_str()) {
+         pm_strcpy(join, ua->db->get_acl_join_filter(DB_ACL_BIT(DB_ACL_BCLIENT)));
+      }
+   }
+   db_unlock(ua->db);
+
    if (i < 0) {                       /* fileset not found */
       edit_int64(cr.ClientId, ed1);
-      Mmsg(rx->query, uar_sel_fileset, ed1, ed1);
+      Mmsg(rx->query, uar_sel_fileset, ed1, where.c_str());
       start_prompt(ua, _("The defined FileSet resources are:\n"));
-      if (!db_sql_query(ua->db, rx->query, fileset_handler, (void *)ua)) {
+      if (!db_sql_query(ua->db, rx->query, fileset_handler, (void *)ua)) { // ACL checked
          ua->error_msg("%s\n", db_strerror(ua->db));
          goto bail_out;
       }
@@ -1819,7 +1858,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
 
    /* If Pool specified, add PoolId specification */
    pool_select[0] = 0;
-   if (rx->pool) {
+   if (rx->pool) {              // PoolACL is checked with where/join
       POOL_DBR pr;
       bmemset(&pr, 0, sizeof(pr));
       bstrncpy(pr.Name, rx->pool->name(), sizeof(pr.Name));
@@ -1831,10 +1870,25 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
       }
    }
 
+   db_lock(ua->db);
+   /* Cleanup any orphan temp table */
+   db_sql_query(ua->db, uar_del_temp, NULL, NULL);
+   db_sql_query(ua->db, uar_del_temp1, NULL, NULL);
+
+   /* Create temp tables */
+   if (!db_sql_query(ua->db, uar_create_temp[db_get_type_index(ua->db)], NULL, NULL)) {
+      ua->error_msg("%s\n", db_strerror(ua->db));
+      goto bail_out;
+   }
+   if (!db_sql_query(ua->db, uar_create_temp1[db_get_type_index(ua->db)], NULL, NULL)) {
+      ua->error_msg("%s\n", db_strerror(ua->db));
+      goto bail_out;
+   }
+
    /* Find JobId of last Full backup for this client, fileset */
    edit_int64(cr.ClientId, ed1);
-   Mmsg(rx->query, uar_last_full, ed1, ed1, date, fsr.FileSet,
-         pool_select);
+   Mmsg(rx->query, uar_last_full, ed1, date, fsr.FileSet,
+        pool_select, where.c_str());
    if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
       ua->error_msg("%s\n", db_strerror(ua->db));
       goto bail_out;
@@ -1859,8 +1913,8 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
    }
 
    /* Now find most recent Differental Job after Full save, if any */
-   Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date,
-        edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
+   Mmsg(rx->query, uar_dif, join.c_str(), edit_uint64(rx->JobTDate, ed1), date,
+        edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select, where.c_str());
    if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
       ua->warning_msg("%s\n", db_strerror(ua->db));
    }
@@ -1875,8 +1929,8 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
    }
 
    /* Now find all Incremental Jobs after Full/dif save */
-   Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date,
-        edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
+   Mmsg(rx->query, uar_inc, join.c_str(), edit_uint64(rx->JobTDate, ed1), date,
+        edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select, where.c_str());
    if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
       ua->warning_msg("%s\n", db_strerror(ua->db));
    }
@@ -1899,6 +1953,7 @@ static bool select_backups_before_date(UAContext *ua, RESTORE_CTX *rx, char *dat
 bail_out:
   db_sql_query(ua->db, uar_del_temp, NULL, NULL);
   db_sql_query(ua->db, uar_del_temp1, NULL, NULL);
+  db_unlock(ua->db);
    return ok;
 }
 
@@ -1978,9 +2033,12 @@ static int last_full_handler(void *ctx, int num_fields, char **row)
  */
 static int fileset_handler(void *ctx, int num_fields, char **row)
 {
+   UAContext *ua = (UAContext *) ctx;
    /* row[0] = FileSet (name) */
    if (row[0]) {
-      add_prompt((UAContext *)ctx, row[0]);
+      if (acl_access_ok(ua, FileSet_ACL, row[0])) {
+         add_prompt((UAContext *)ctx, row[0]);
+      }
    }
    return 0;
 }
index 219f33557b6e951d18e3dd70ffb4ec581f435d7a..027c8a1ae09838bdd377a6d965def0c4900264b3 100644 (file)
@@ -1399,6 +1399,7 @@ int select_running_jobs(UAContext *ua, alist *jcrs, const char *reason)
          }
          foreach_sellist(JobId, &sl) {
             jcr = get_jcr_by_id(JobId);
+            /* TODO: check for client? */
             if (jcr && jcr->job && acl_access_ok(ua, Job_ACL, jcr->job->name())) {
                jcrs->append(jcr);
             } else if (jcr) {