From: Eric Bollengier Date: Tue, 21 Mar 2023 10:17:21 +0000 (+0100) Subject: Fix #9968 Adapt restore menu and add RBCLIENT/BCLIENT in some ACL SQL checking X-Git-Tag: Release-13.0.3~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f388ed028614269ed1b77da9093bdd8cffc51a5a;p=thirdparty%2Fbacula.git Fix #9968 Adapt restore menu and add RBCLIENT/BCLIENT in some ACL SQL checking - menu 9 - menu 8 - menu 12 - menu 13 --- diff --git a/bacula/src/cats/sql_cmds.c b/bacula/src/cats/sql_cmds.c index af0e203eb..ad558484e 100644 --- a/bacula/src/cats/sql_cmds.c +++ b/bacula/src/cats/sql_cmds.c @@ -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 " }; diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index aa5890653..64b75217d 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -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)); diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index cb74f1e2c..ce111abeb 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -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)); } diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 8d5c9d638..a5bcbedb7 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -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; diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index 9a4080806..012b63971 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -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; diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c index 926264184..177ac6cde 100644 --- a/bacula/src/dird/ua_restore.c +++ b/bacula/src/dird/ua_restore.c @@ -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; } diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 219f33557..027c8a1ae 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -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) {