s3-vfs_glusterfs: refuse connection when write-behind xlator is present
authorGünther Deschner <gd@samba.org>
Mon, 2 Nov 2020 11:30:36 +0000 (12:30 +0100)
committerKarolin Seeger <kseeger@samba.org>
Tue, 3 Nov 2020 11:31:29 +0000 (11:31 +0000)
s3-vfs_glusterfs: refuse connection when write-behind xlator is present

Once the new glusterfs api is available we will programmtically disable
the translator, for now we just refuse the connection as there is
a potential for serious data damage.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14486

Guenther

Signed-off-by: Guenther Deschner <gd@samba.org>
Pair-Programmed-With: Sachin Prabhu <sprabhu@redhat.com>
Pair-Programmed-With: Anoop C S <anoopcs@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Mon Nov  2 21:40:33 UTC 2020 on sn-devel-184

(cherry picked from commit 2a49ccbcf5e3ff0f6833bcb7f04b800125f1783f)

source3/modules/vfs_glusterfs.c

index d4b68fba37671892f6634eb283f314568410b746..c5154330ee3cfebc47f73121dd1aa82c7297e8d6 100644 (file)
@@ -264,6 +264,90 @@ out:
 
 /* Disk Operations */
 
+static int check_for_write_behind_translator(TALLOC_CTX *mem_ctx,
+                                            glfs_t *fs,
+                                            const char *volume)
+{
+       char *buf = NULL;
+       char **lines = NULL;
+       int numlines = 0;
+       int i;
+       char *option;
+       bool write_behind_present = false;
+       size_t newlen;
+       int ret;
+
+       ret = glfs_get_volfile(fs, NULL, 0);
+       if (ret == 0) {
+               DBG_ERR("%s: Failed to get volfile for "
+                       "volume (%s): No volfile\n",
+                       volume,
+                       strerror(errno));
+               return -1;
+       }
+       if (ret > 0) {
+               DBG_ERR("%s: Invalid return %d for glfs_get_volfile for "
+                       "volume (%s): No volfile\n",
+                       volume,
+                       ret,
+                       strerror(errno));
+               return -1;
+       }
+
+       newlen = 0 - ret;
+
+       buf = talloc_zero_array(mem_ctx, char, newlen);
+       if (buf == NULL) {
+               return -1;
+       }
+
+       ret = glfs_get_volfile(fs, buf, newlen);
+       if (ret != newlen) {
+               TALLOC_FREE(buf);
+               DBG_ERR("%s: Failed to get volfile for volume (%s)\n",
+                       volume, strerror(errno));
+               return -1;
+       }
+
+       option = talloc_asprintf(mem_ctx, "volume %s-write-behind", volume);
+       if (option == NULL) {
+               TALLOC_FREE(buf);
+               return -1;
+       }
+
+       lines = file_lines_parse(buf,
+                               newlen,
+                               &numlines,
+                               mem_ctx);
+       if (lines == NULL || numlines <= 0) {
+               TALLOC_FREE(option);
+               TALLOC_FREE(buf);
+               return -1;
+       }
+
+       for (i=0; i < numlines; i++) {
+               if (strequal(lines[i], option)) {
+                       write_behind_present = true;
+                       break;
+               }
+       }
+
+       if (write_behind_present) {
+               DBG_ERR("Write behind translator is enabled for "
+                       "volume (%s), refusing to connect! "
+                       "Please check the vfs_glusterfs(8) manpage for "
+                       "further details.\n",
+                       volume);
+               TALLOC_FREE(option);
+               TALLOC_FREE(buf);
+               return -1;
+       }
+
+       TALLOC_FREE(option);
+       TALLOC_FREE(buf);
+       return 0;
+}
+
 static int vfs_gluster_connect(struct vfs_handle_struct *handle,
                               const char *service,
                               const char *user)
@@ -357,6 +441,11 @@ static int vfs_gluster_connect(struct vfs_handle_struct *handle,
                goto done;
        }
 
+       ret = check_for_write_behind_translator(tmp_ctx, fs, volume);
+       if (ret < 0) {
+               goto done;
+       }
+
        ret = glfs_set_preopened(volume, handle->conn->connectpath, fs);
        if (ret < 0) {
                DEBUG(0, ("%s: Failed to register volume (%s)\n",