1 /* 2 Bacula(R) - The Network Backup Solution 3 4 Copyright (C) 2000-2020 Kern Sibbald 5 6 The original author of Bacula is Kern Sibbald, with contributions 7 from many others, a complete list can be found in the file AUTHORS. 8 9 You may use this file and others of this release according to the 10 license defined in the LICENSE file, which includes the Affero General 11 Public License, v3.0 ("AGPLv3") and some additional permissions and 12 terms pursuant to its AGPLv3 Section 7. 13 14 This notice must be preserved when any source code is 15 conveyed and/or propagated. 16 17 Bacula(R) is a registered trademark of Kern Sibbald. 18 */ 19 20 21 #ifndef __BVFS_H_ 22 #define __BVFS_H_ 1 23 24 25 /* 26 * This object can be use to browse the catalog 27 * 28 * Bvfs fs; 29 * fs.set_jobid(10); 30 * fs.update_cache(); 31 * fs.ch_dir("/"); 32 * fs.ls_dirs(); 33 * fs.ls_files(); 34 */ 35 36 /* Helper for result handler */ 37 typedef enum { 38 BVFS_FILE_RECORD = 'F', 39 BVFS_DIR_RECORD = 'D', 40 BVFS_FILE_VERSION = 'V', 41 BVFS_VOLUME_LIST = 'L', 42 BVFS_DELTA_RECORD = 'd', 43 } bvfs_handler_type; 44 45 typedef enum { 46 BVFS_Type = 0, /* Could be D, F, V, L */ 47 BVFS_PathId = 1, 48 BVFS_FilenameId = 5, /* No longer in use, use fileid instead */ 49 50 BVFS_Name = 2, 51 BVFS_JobId = 3, 52 53 BVFS_LStat = 4, /* Can be empty for missing directories */ 54 BVFS_FileId = 5, /* Can be empty for missing directories */ 55 56 /* Only if Path record */ 57 BVFS_FileIndex = 6, 58 59 /* Only if File Version record */ 60 BVFS_Md5 = 6, 61 BVFS_VolName = 7, 62 BVFS_VolInchanger = 8, 63 64 /* Only if Delta record */ 65 BVFS_DeltaSeq = 6, 66 BVFS_JobTDate = 7 67 } bvfs_row_index; 68 69 class Bvfs { 70 71 public: 72 Bvfs(JCR *j, BDB *mdb); 73 virtual ~Bvfs(); 74 set_compute_delta(bool val)75 void set_compute_delta(bool val) { 76 compute_delta = val; 77 }; 78 79 /* Return the number of jobids after the filter */ 80 int set_jobid(JobId_t id); 81 int set_jobids(char *ids); 82 get_jobids()83 char *get_jobids() { 84 return jobids; 85 } 86 set_limit(uint32_t max)87 void set_limit(uint32_t max) { 88 limit = max; 89 } 90 set_offset(uint32_t nb)91 void set_offset(uint32_t nb) { 92 offset = nb; 93 } 94 set_pattern(char * p)95 void set_pattern(char *p) { 96 uint32_t len = strlen(p); 97 pattern = check_pool_memory_size(pattern, len*2+1); 98 db->bdb_escape_string(jcr, pattern, p, len); 99 } 100 set_filename(char * p)101 void set_filename(char *p) { 102 uint32_t len = strlen(p); 103 filename = check_pool_memory_size(filename, len*2+1); 104 db->bdb_escape_string(jcr, filename, p, len); 105 } 106 107 /* Get the root point */ 108 DBId_t get_root(); 109 110 /* It's much better to access Path though their PathId, it 111 * avoids mistakes with string encoding 112 */ 113 bool ch_dir(DBId_t pathid); 114 115 /* 116 * Returns true if the directory exists 117 */ 118 bool ch_dir(const char *path); 119 120 bool ls_files(); /* Returns true if we have more files to read */ 121 bool ls_dirs(); /* Returns true if we have more dir to read */ 122 void ls_special_dirs(); /* get . and .. */ get_all_file_versions(DBId_t pathid,FileId_t fnid,char * client)123 void get_all_file_versions(DBId_t pathid, FileId_t fnid, char *client) { 124 alist clients(1, not_owned_by_alist); 125 clients.append(client); 126 get_all_file_versions(pathid, fnid, &clients); 127 }; 128 void get_all_file_versions(DBId_t pathid, FileId_t fnid, alist *clients); 129 130 void update_cache(); 131 132 /* bfileview */ 133 void fv_update_cache(); 134 set_see_all_versions(bool val)135 void set_see_all_versions(bool val) { 136 see_all_versions = val; 137 } 138 set_see_copies(bool val)139 void set_see_copies(bool val) { 140 see_copies = val; 141 } 142 143 int filter_jobid(); /* Call after set_username, returns the number of jobids */ 144 set_username(char * user)145 void set_username(char *user) { 146 if (user) { 147 username = bstrdup(user); 148 } 149 }; 150 151 char *escape_list(alist *list); 152 copy_acl(alist * list)153 bool copy_acl(alist *list) { 154 if (!list || 155 (list->size() > 0 && 156 (strcasecmp((char *)list->get(0), "*all*") == 0))) 157 { 158 return false; 159 } 160 return true; 161 }; 162 163 /* Keep a pointer to various ACLs */ set_job_acl(alist * lst)164 void set_job_acl(alist *lst) { 165 job_acl = copy_acl(lst)?lst:NULL; 166 use_acl = true; 167 }; set_fileset_acl(alist * lst)168 void set_fileset_acl(alist *lst) { 169 fileset_acl = copy_acl(lst)?lst:NULL; 170 use_acl = true; 171 }; 172 /* For client, we copy ACL from ClientACL and RestoreClientACL 173 * (bvfs is handling only Restore) 174 */ set_client_acl(alist * client,alist * restore)175 void set_client_acl(alist *client, alist *restore) { 176 client_acl = New(alist(10, not_owned_by_alist)); 177 178 /* Everything is authorized */ 179 if (client && client->size() == 1 180 && strcasecmp((char*)client->get(0), "*all*") == 0) 181 { 182 /* nothing to do */ 183 184 /* Everything is authorized */ 185 } else if (restore && restore->size() == 1 186 && strcasecmp((char*)restore->get(0), "*all*") == 0) 187 { 188 /* nothing to do */ 189 190 } else { 191 /* We copy one by one */ 192 char *elt; 193 if (client) { 194 foreach_alist(elt, client) { 195 client_acl->append(elt); 196 } 197 } 198 if (restore) { 199 foreach_alist(elt, restore) { 200 client_acl->append(elt); 201 } 202 } 203 } 204 /* Nothing in the list, we can keep an empty one */ 205 if (client_acl->size() == 0) { 206 delete client_acl; 207 client_acl = NULL; 208 } 209 use_acl = true; 210 }; set_pool_acl(alist * lst)211 void set_pool_acl(alist *lst) { 212 pool_acl = copy_acl(lst)?lst:NULL; 213 use_acl = true; 214 }; set_handler(DB_RESULT_HANDLER * h,void * ctx)215 void set_handler(DB_RESULT_HANDLER *h, void *ctx) { 216 list_entries = h; 217 user_data = ctx; 218 }; 219 get_pwd()220 DBId_t get_pwd() { 221 return pwd_id; 222 }; 223 get_attr()224 ATTR *get_attr() { 225 return attr; 226 } 227 get_jcr()228 JCR *get_jcr() { 229 return jcr; 230 } 231 reset_offset()232 void reset_offset() { 233 offset=0; 234 } 235 next_offset()236 void next_offset() { 237 offset+=limit; 238 } 239 240 /* Clear all cache */ 241 void clear_cache(); 242 243 /* Compute restore list */ 244 bool compute_restore_list(char *fileid, char *dirid, char *output_table); 245 246 /* Drop previous restore list */ 247 bool drop_restore_list(char *output_table); 248 249 /* for internal use */ 250 int _handle_path(void *, int, char **); 251 252 /* Handle Delta parts if any */ 253 void insert_missing_delta(char *output_table, int64_t *res); 254 255 /* Handle hardlinks if any */ 256 bool insert_hardlinks(char *output_table); 257 258 /* Handle hardlinks if any */ 259 bool insert_hardlinks_fast(char *output_table); 260 261 /* Check if this function can be used */ 262 bool can_use_insert_hardlinks_fast(); 263 264 /* Get a list of volumes */ 265 void get_volumes(FileId_t fileid); 266 267 /* Get Delta parts of a file */ 268 bool get_delta(FileId_t fileid); 269 270 /* Query handler to check UID of the file with the current uid/gid */ 271 int checkuid_cb(int fields, char **row); 272 273 /* Query handler to check hardlinks */ 274 int checkhardlinks_cb(int fields, char **row); 275 276 /* Check if the parent directories are accessible */ 277 bool check_path_access(DBId_t pathid); 278 279 /* Check if the full path is authorized by the current set of ACLs */ 280 bool check_full_path_access(int nb, sellist *sel, db_list_ctx *toexcl); 281 set_uid(uid_t u,gid_t g)282 void set_uid(uid_t u, gid_t g) { 283 if (u == 0) { 284 return; 285 } 286 if (!uid_acl) { 287 uid_acl = New(alist(5, not_owned_by_alist)); 288 gid_acl = New(alist(5, not_owned_by_alist)); 289 } 290 uid_acl->append((void*)(intptr_t)u); 291 gid_acl->append((void*)(intptr_t)g); 292 use_acl = true; 293 }; 294 alist *uid_acl; 295 alist *gid_acl; 296 alist *dir_acl; 297 298 int check_dirs; /* When it's 1, we check the against directory_acl */ 299 bool can_access(struct stat *st); 300 bool can_access_dir(const char *path); 301 bool check_permissions(char *output_table); 302 303 bool delete_fileid(char *fileids); 304 305 private: 306 Bvfs(const Bvfs &); /* prohibit pass by value */ 307 Bvfs & operator = (const Bvfs &); /* prohibit class assignment */ 308 309 JCR *jcr; 310 BDB *db; 311 POOLMEM *jobids; 312 char *username; /* Used with Bweb */ 313 314 POOLMEM *prev_dir; /* ls_dirs query returns all versions, take the 1st one */ 315 POOLMEM *pattern; 316 POOLMEM *filename; 317 318 POOLMEM *tmp; 319 POOLMEM *escaped_list; 320 321 /* Pointer to Console ACL */ 322 alist *job_acl; 323 alist *client_acl; 324 alist *restoreclient_acl; 325 alist *fileset_acl; 326 alist *pool_acl; 327 char *last_dir_acl; 328 329 htable *hardlinks; /* Check if we already saw a given hardlink */ 330 alist *missing_hardlinks; /* list with all the missing jobid/fileindex1 */ 331 332 ATTR *attr; /* Can be use by handler to call decode_stat() */ 333 334 uint32_t limit; 335 uint32_t offset; 336 uint32_t nb_record; /* number of records of the last query */ 337 DBId_t pwd_id; /* Current pathid */ 338 339 bool see_all_versions; 340 bool see_copies; 341 bool compute_delta; 342 343 /* Restrict the ouput with some uid/gid */ 344 db_list_ctx fileid_to_delete; /* used also by check_path_access */ 345 bool need_to_check_permissions(); 346 bool use_acl; 347 348 /* bfileview */ 349 void fv_get_big_files(int64_t pathid, int64_t min_size, int32_t limit); 350 void fv_update_size_and_count(int64_t pathid, int64_t size, int64_t count); 351 void fv_compute_size_and_count(int64_t pathid, int64_t *size, int64_t *count); 352 void fv_get_current_size_and_count(int64_t pathid, int64_t *size, int64_t *count); 353 void fv_get_size_and_count(int64_t pathid, int64_t *size, int64_t *count); 354 355 DB_RESULT_HANDLER *list_entries; 356 void *user_data; 357 }; 358 359 #define bvfs_is_dir(row) ((row)[BVFS_Type][0] == BVFS_DIR_RECORD) 360 #define bvfs_is_file(row) ((row)[BVFS_Type][0] == BVFS_FILE_RECORD) 361 #define bvfs_is_version(row) ((row)[BVFS_Type][0] == BVFS_FILE_VERSION) 362 #define bvfs_is_volume_list(row) ((row)[BVFS_Type][0] == BVFS_VOLUME_LIST) 363 #define bvfs_is_delta_list(row) ((row)[BVFS_Type][0] == BVFS_DELTA_RECORD) 364 365 void bvfs_update_fv_cache(JCR *jcr, BDB *mdb, char *jobids); 366 int bvfs_update_path_hierarchy_cache(JCR *jcr, BDB *mdb, char *jobids); 367 void bvfs_update_cache(JCR *jcr, BDB *mdb); 368 char *bvfs_parent_dir(char *path); 369 370 /* Return the basename of the with the trailing / (update the given string) 371 * TODO: see in the rest of bacula if we don't have 372 * this function already 373 */ 374 char *bvfs_basename_dir(char *path); 375 376 #endif /* __BVFS_H_ */ 377