]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
BEE Backport bacula/src/cats/bvfs.h
authorEric Bollengier <eric@baculasystems.com>
Mon, 11 May 2020 15:03:04 +0000 (17:03 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 29 Apr 2021 08:44:17 +0000 (10:44 +0200)
This commit is the result of the squash of the following main commits:

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Wed Aug 14 14:23:03 2019 +0200

    Move acl/permission BEEF code to bee_XXX.c/h files

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Tue Jun 4 17:44:25 2019 +0200

    bvfs: Fix Client ACL SQL translation

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Tue May 28 10:38:58 2019 +0200

    bvfs: Use ClientACL+RestoreClientACL in bvfs queries

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Mon Nov 20 16:53:02 2017 +0100

    bvfs: Fix hardlink selection issue with subdirectories

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Sat Nov 11 14:54:26 2017 +0100

    bvfs: Add function bvfs_delete_filed for plugins that requires to delete a catalog entry

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Mon Oct 31 19:44:35 2016 +0100

    Allow to use glob in directoryACL from BVFS

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Tue Oct 18 18:07:24 2016 +0200

    Add DirectoryACL and UserIdACL directives to the Console resource

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Fri Oct 23 12:21:49 2015 +0200

    Fix #1343 about a problem with BVFS queries with deleted directories

    We now use JobTDate to find the last entry (instead of JobId) and we
    check FileIndex=0 that indicates if a file or a directory was deleted.

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Tue Aug 11 15:24:55 2015 +0200

    Add bvfs interface to access DeltaSeq file attribute

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Mon Aug 26 13:57:34 2013 +0200

    Merge Filename table to File

bacula/src/cats/bvfs.h

index a9ec9c85f05890bdfe4de43a15dd8fc7de9586c2..73808402227c75bb266c132bb82677d249e9cd52 100644 (file)
@@ -17,6 +17,7 @@
    Bacula(R) is a registered trademark of Kern Sibbald.
 */
 
+
 #ifndef __BVFS_H_
 #define __BVFS_H_ 1
 
@@ -38,27 +39,27 @@ typedef enum {
    BVFS_DIR_RECORD   = 'D',
    BVFS_FILE_VERSION = 'V',
    BVFS_VOLUME_LIST  = 'L',
-   BVFS_DELTA_RECORD = 'd'
+   BVFS_DELTA_RECORD = 'd',
 } bvfs_handler_type;
 
 typedef enum {
    BVFS_Type    = 0,            /* Could be D, F, V, L */
    BVFS_PathId  = 1,
-   BVFS_FilenameId = 2,
+   BVFS_FilenameId = 5,         /* No longer in use, use fileid instead */
 
-   BVFS_Name    = 3,            /* Can be empty for File version */
-   BVFS_JobId   = 4,
+   BVFS_Name    = 2,
+   BVFS_JobId   = 3,
 
-   BVFS_LStat   = 5,            /* Can be empty for missing directories */
-   BVFS_FileId  = 6,            /* Can be empty for missing directories */
+   BVFS_LStat   = 4,            /* Can be empty for missing directories */
+   BVFS_FileId  = 5,            /* Can be empty for missing directories */
 
    /* Only if Path record */
-   BVFS_FileIndex = 7,
+   BVFS_FileIndex = 6,
 
    /* Only if File Version record */
-   BVFS_Md5     = 7,
-   BVFS_VolName = 8,
-   BVFS_VolInchanger = 9,
+   BVFS_Md5     = 6,
+   BVFS_VolName = 7,
+   BVFS_VolInchanger = 8,
 
    /* Only if Delta record */
    BVFS_DeltaSeq = 6,
@@ -139,8 +140,6 @@ public:
       see_copies = val;
    }
 
-   DBId_t get_dir_filenameid();
-
    int filter_jobid();         /* Call after set_username, returns the number of jobids */
 
    void set_username(char *user) {
@@ -170,8 +169,43 @@ public:
       fileset_acl = copy_acl(lst)?lst:NULL;
       use_acl = true;
    };
-   void set_client_acl(alist *lst) {
-      client_acl = copy_acl(lst)?lst:NULL;
+   /* For client, we copy ACL from ClientACL and RestoreClientACL 
+    * (bvfs is handling only Restore)
+    */
+   void set_client_acl(alist *client, alist *restore) {
+      client_acl = New(alist(10, not_owned_by_alist));
+
+      /* Everything is authorized */
+      if (client && client->size() == 1
+          && strcasecmp((char*)client->get(0), "*all*") == 0)
+      {
+         /* nothing to do */
+
+      /* Everything is authorized */
+      } else if (restore && restore->size() == 1
+                 && strcasecmp((char*)restore->get(0), "*all*") == 0)
+      {
+         /* nothing to do */
+
+      } else {
+         /* We copy one by one */
+         char *elt;
+         if (client) {
+            foreach_alist(elt, client) {
+               client_acl->append(elt);
+            }
+         }
+         if (restore) {
+            foreach_alist(elt, restore) {
+               client_acl->append(elt);
+            }
+         }
+      }
+      /* Nothing in the list, we can keep an empty one */
+      if (client_acl->size() == 0) {
+         delete client_acl;
+         client_acl = NULL;
+      }
       use_acl = true;
    };
    void set_pool_acl(alist *lst) {
@@ -207,8 +241,7 @@ public:
    void clear_cache();
 
    /* Compute restore list */
-   bool compute_restore_list(char *fileid, char *dirid, char *hardlink,
-                             char *output_table);
+   bool compute_restore_list(char *fileid, char *dirid, char *output_table);
 
    /* Drop previous restore list */
    bool drop_restore_list(char *output_table);
@@ -219,24 +252,50 @@ public:
    /* Handle Delta parts if any */
    void insert_missing_delta(char *output_table, int64_t *res);
 
+   /* Handle hardlinks if any */
+   bool insert_hardlinks(char *output_table);
+
    /* Get a list of volumes */
    void get_volumes(FileId_t fileid);
 
    /* Get Delta parts of a file */
    bool get_delta(FileId_t fileid);
 
+   /* Query handler to check UID of the file with the current uid/gid */
+   int checkuid_cb(int fields, char **row);
+
+   /* Query handler to check hardlinks */
+   int checkhardlinks_cb(int fields, char **row);
+
    /* Check if the parent directories are accessible */
    bool check_path_access(DBId_t pathid);
 
    /* Check if the full path is authorized by the current set of ACLs */
    bool check_full_path_access(int nb, sellist *sel, db_list_ctx *toexcl);
 
+   void set_uid(uid_t u, gid_t g) {
+      if (u == 0) {
+         return;
+      }
+      if (!uid_acl) {
+         uid_acl = New(alist(5, not_owned_by_alist));
+         gid_acl = New(alist(5, not_owned_by_alist));
+      }
+      uid_acl->append((void*)(intptr_t)u);
+      gid_acl->append((void*)(intptr_t)g);
+      use_acl = true;
+   };
+   alist *uid_acl;
+   alist *gid_acl;
    alist *dir_acl;
 
    int  check_dirs;             /* When it's 1, we check the against directory_acl */
    bool can_access(struct stat *st);
    bool can_access_dir(const char *path);
+   bool check_permissions(char *output_table);
 
+   bool delete_fileid(char *fileids);
+   
 private:
    Bvfs(const Bvfs &);               /* prohibit pass by value */
    Bvfs & operator = (const Bvfs &); /* prohibit class assignment */
@@ -256,22 +315,26 @@ private:
    /* Pointer to Console ACL */
    alist *job_acl;
    alist *client_acl;
+   alist *restoreclient_acl;
    alist *fileset_acl;
    alist *pool_acl;
    char  *last_dir_acl;
 
-   ATTR *attr;        /* Can be use by handler to call decode_stat() */
+   htable *hardlinks;           /* Check if we already saw a given hardlink */
+   alist  *missing_hardlinks;   /* list with all the missing jobid/fileindex1 */
+
+   ATTR *attr;                /* Can be use by handler to call decode_stat() */
 
    uint32_t limit;
    uint32_t offset;
    uint32_t nb_record;          /* number of records of the last query */
    DBId_t pwd_id;               /* Current pathid */
-   DBId_t dir_filenameid;       /* special FilenameId where Name='' */
 
    bool see_all_versions;
    bool see_copies;
    bool compute_delta;
 
+   /* Restrict the ouput with some uid/gid */
    db_list_ctx fileid_to_delete; /* used also by check_path_access */
    bool need_to_check_permissions();
    bool use_acl;