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 #ifndef __BVFS_H_
21 #define __BVFS_H_ 1
22 
23 
24 /*
25  * This object can be use to browse the catalog
26  *
27  * Bvfs fs;
28  * fs.set_jobid(10);
29  * fs.update_cache();
30  * fs.ch_dir("/");
31  * fs.ls_dirs();
32  * fs.ls_files();
33  */
34 
35 /* Helper for result handler */
36 typedef enum {
37    BVFS_FILE_RECORD  = 'F',
38    BVFS_DIR_RECORD   = 'D',
39    BVFS_FILE_VERSION = 'V',
40    BVFS_VOLUME_LIST  = 'L',
41    BVFS_DELTA_RECORD = 'd'
42 } bvfs_handler_type;
43 
44 typedef enum {
45    BVFS_Type    = 0,            /* Could be D, F, V, L */
46    BVFS_PathId  = 1,
47    BVFS_FilenameId = 2,
48 
49    BVFS_Name    = 3,            /* Can be empty for File version */
50    BVFS_JobId   = 4,
51 
52    BVFS_LStat   = 5,            /* Can be empty for missing directories */
53    BVFS_FileId  = 6,            /* Can be empty for missing directories */
54 
55    /* Only if Path record */
56    BVFS_FileIndex = 7,
57 
58    /* Only if File Version record */
59    BVFS_Md5     = 7,
60    BVFS_VolName = 8,
61    BVFS_VolInchanger = 9,
62 
63    /* Only if Delta record */
64    BVFS_DeltaSeq = 6,
65    BVFS_JobTDate = 7
66 } bvfs_row_index;
67 
68 class Bvfs {
69 
70 public:
71    Bvfs(JCR *j, BDB *mdb);
72    virtual ~Bvfs();
73 
set_compute_delta(bool val)74    void set_compute_delta(bool val) {
75       compute_delta = val;
76    };
77 
78    /* Return the number of jobids after the filter */
79    int set_jobid(JobId_t id);
80    int set_jobids(char *ids);
81 
get_jobids()82    char *get_jobids() {
83       return jobids;
84    }
85 
set_limit(uint32_t max)86    void set_limit(uint32_t max) {
87       limit = max;
88    }
89 
set_offset(uint32_t nb)90    void set_offset(uint32_t nb) {
91       offset = nb;
92    }
93 
set_pattern(char * p)94    void set_pattern(char *p) {
95       uint32_t len = strlen(p);
96       pattern = check_pool_memory_size(pattern, len*2+1);
97       db->bdb_escape_string(jcr, pattern, p, len);
98    }
99 
set_filename(char * p)100    void set_filename(char *p) {
101       uint32_t len = strlen(p);
102       filename = check_pool_memory_size(filename, len*2+1);
103       db->bdb_escape_string(jcr, filename, p, len);
104    }
105 
106    /* Get the root point */
107    DBId_t get_root();
108 
109    /* It's much better to access Path though their PathId, it
110     * avoids mistakes with string encoding
111     */
112    bool ch_dir(DBId_t pathid);
113 
114    /*
115     * Returns true if the directory exists
116     */
117    bool ch_dir(const char *path);
118 
119    bool ls_files();             /* Returns true if we have more files to read */
120    bool ls_dirs();              /* Returns true if we have more dir to read */
121    void ls_special_dirs();      /* get . and .. */
get_all_file_versions(DBId_t pathid,FileId_t fnid,char * client)122    void get_all_file_versions(DBId_t pathid, FileId_t fnid, char *client) {
123       alist clients(1, not_owned_by_alist);
124       clients.append(client);
125       get_all_file_versions(pathid, fnid, &clients);
126    };
127    void get_all_file_versions(DBId_t pathid, FileId_t fnid, alist *clients);
128 
129    void update_cache();
130 
131    /* bfileview */
132    void fv_update_cache();
133 
set_see_all_versions(bool val)134    void set_see_all_versions(bool val) {
135       see_all_versions = val;
136    }
137 
set_see_copies(bool val)138    void set_see_copies(bool val) {
139       see_copies = val;
140    }
141 
142    DBId_t get_dir_filenameid();
143 
144    int filter_jobid();         /* Call after set_username, returns the number of jobids */
145 
set_username(char * user)146    void set_username(char *user) {
147       if (user) {
148          username = bstrdup(user);
149       }
150    };
151 
152    char *escape_list(alist *list);
153 
copy_acl(alist * list)154    bool copy_acl(alist *list) {
155       if (!list ||
156           (list->size() > 0 &&
157            (strcasecmp((char *)list->get(0), "*all*") == 0)))
158       {
159          return false;
160       }
161       return true;
162    };
163 
164    /* Keep a pointer to various ACLs */
set_job_acl(alist * lst)165    void set_job_acl(alist *lst) {
166       job_acl = copy_acl(lst)?lst:NULL;
167       use_acl = true;
168    };
set_fileset_acl(alist * lst)169    void set_fileset_acl(alist *lst) {
170       fileset_acl = copy_acl(lst)?lst:NULL;
171       use_acl = true;
172    };
set_client_acl(alist * lst)173    void set_client_acl(alist *lst) {
174       client_acl = copy_acl(lst)?lst:NULL;
175       use_acl = true;
176    };
set_pool_acl(alist * lst)177    void set_pool_acl(alist *lst) {
178       pool_acl = copy_acl(lst)?lst:NULL;
179       use_acl = true;
180    };
set_handler(DB_RESULT_HANDLER * h,void * ctx)181    void set_handler(DB_RESULT_HANDLER *h, void *ctx) {
182       list_entries = h;
183       user_data = ctx;
184    };
185 
get_pwd()186    DBId_t get_pwd() {
187       return pwd_id;
188    };
189 
get_attr()190    ATTR *get_attr() {
191       return attr;
192    }
193 
get_jcr()194    JCR *get_jcr() {
195       return jcr;
196    }
197 
reset_offset()198    void reset_offset() {
199       offset=0;
200    }
201 
next_offset()202    void next_offset() {
203       offset+=limit;
204    }
205 
206    /* Clear all cache */
207    void clear_cache();
208 
209    /* Compute restore list */
210    bool compute_restore_list(char *fileid, char *dirid, char *hardlink,
211                              char *output_table);
212 
213    /* Drop previous restore list */
214    bool drop_restore_list(char *output_table);
215 
216    /* for internal use */
217    int _handle_path(void *, int, char **);
218 
219    /* Handle Delta parts if any */
220    void insert_missing_delta(char *output_table, int64_t *res);
221 
222    /* Get a list of volumes */
223    void get_volumes(FileId_t fileid);
224 
225    /* Get Delta parts of a file */
226    bool get_delta(FileId_t fileid);
227 
228    /* Check if the parent directories are accessible */
229    bool check_path_access(DBId_t pathid);
230 
231    /* Check if the full path is authorized by the current set of ACLs */
232    bool check_full_path_access(int nb, sellist *sel, db_list_ctx *toexcl);
233 
234    alist *dir_acl;
235 
236    int  check_dirs;             /* When it's 1, we check the against directory_acl */
237    bool can_access(struct stat *st);
238    bool can_access_dir(const char *path);
239 
240 private:
241    Bvfs(const Bvfs &);               /* prohibit pass by value */
242    Bvfs & operator = (const Bvfs &); /* prohibit class assignment */
243 
244    JCR *jcr;
245    BDB *db;
246    POOLMEM *jobids;
247    char *username;              /* Used with Bweb */
248 
249    POOLMEM *prev_dir; /* ls_dirs query returns all versions, take the 1st one */
250    POOLMEM *pattern;
251    POOLMEM *filename;
252 
253    POOLMEM *tmp;
254    POOLMEM *escaped_list;
255 
256    /* Pointer to Console ACL */
257    alist *job_acl;
258    alist *client_acl;
259    alist *fileset_acl;
260    alist *pool_acl;
261    char  *last_dir_acl;
262 
263    ATTR *attr;        /* Can be use by handler to call decode_stat() */
264 
265    uint32_t limit;
266    uint32_t offset;
267    uint32_t nb_record;          /* number of records of the last query */
268    DBId_t pwd_id;               /* Current pathid */
269    DBId_t dir_filenameid;       /* special FilenameId where Name='' */
270 
271    bool see_all_versions;
272    bool see_copies;
273    bool compute_delta;
274 
275    db_list_ctx fileid_to_delete; /* used also by check_path_access */
276    bool need_to_check_permissions();
277    bool use_acl;
278 
279    /* bfileview */
280    void fv_get_big_files(int64_t pathid, int64_t min_size, int32_t limit);
281    void fv_update_size_and_count(int64_t pathid, int64_t size, int64_t count);
282    void fv_compute_size_and_count(int64_t pathid, int64_t *size, int64_t *count);
283    void fv_get_current_size_and_count(int64_t pathid, int64_t *size, int64_t *count);
284    void fv_get_size_and_count(int64_t pathid, int64_t *size, int64_t *count);
285 
286    DB_RESULT_HANDLER *list_entries;
287    void *user_data;
288 };
289 
290 #define bvfs_is_dir(row) ((row)[BVFS_Type][0] == BVFS_DIR_RECORD)
291 #define bvfs_is_file(row) ((row)[BVFS_Type][0] == BVFS_FILE_RECORD)
292 #define bvfs_is_version(row) ((row)[BVFS_Type][0] == BVFS_FILE_VERSION)
293 #define bvfs_is_volume_list(row) ((row)[BVFS_Type][0] == BVFS_VOLUME_LIST)
294 #define bvfs_is_delta_list(row) ((row)[BVFS_Type][0] == BVFS_DELTA_RECORD)
295 
296 void bvfs_update_fv_cache(JCR *jcr, BDB *mdb, char *jobids);
297 int bvfs_update_path_hierarchy_cache(JCR *jcr, BDB *mdb, char *jobids);
298 void bvfs_update_cache(JCR *jcr, BDB *mdb);
299 char *bvfs_parent_dir(char *path);
300 
301 /* Return the basename of the with the trailing /  (update the given string)
302  * TODO: see in the rest of bacula if we don't have
303  * this function already
304  */
305 char *bvfs_basename_dir(char *path);
306 
307 #endif /* __BVFS_H_ */
308