]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_ceph_new: Handle absolute path in vfs_ceph_ll_walk
authorAnoop C S <anoopcs@samba.org>
Mon, 24 Feb 2025 08:30:56 +0000 (14:00 +0530)
committerJule Anger <janger@samba.org>
Thu, 13 Mar 2025 16:03:20 +0000 (16:03 +0000)
It can very well be the case that the incoming path is absolute in
nature which breaks the assumption inside vfs_ceph_ll_walk that it
is within the current working directory. Instead perform a check to
see whether the path includes current working directory path in its
components and accordingly trim it to make it relative in nature.

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

Signed-off-by: Anoop C S <anoopcs@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 9341d7fb466c95ea5aa0643049ce2a1f4183b9d0)

source3/modules/vfs_ceph_new.c

index 97065fc41c630a8d3075d5881090de940d48b731..8f84a83ed02a38e5e1247a1413d95cca0e5e302b 100644 (file)
@@ -822,10 +822,31 @@ static int vfs_ceph_ll_walk(const struct vfs_handle_struct *handle,
        struct UserPerm *uperm = NULL;
        int ret = -1;
        struct vfs_ceph_config *config = NULL;
+       const char *cwd = NULL;
+       size_t cwdlen;
 
        SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config,
                                return -ENOMEM);
 
+       cwd = config->ceph_getcwd_fn(config->mount);
+       cwdlen = strlen(cwd);
+
+       /*
+        * ceph_ll_walk() always operate on "name" relative to current working
+        * directory even if it starts with a '/' i.e, absolute path is never
+        * honoured. But why?? For now stick to the current behaviour and ensure
+        * that the "name" is always relative when it contains current working
+        * directory path with an exception to "/".
+        */
+       if ((strcmp(cwd, "/") != 0) &&
+           (strncmp(name, cwd, cwdlen) == 0)) {
+               if (name[cwdlen] == '/') {
+                       name += cwdlen + 1;
+               } else if (name[cwdlen] == '\0') {
+                       name = ".";
+               }
+       }
+
        DBG_DEBUG("[CEPH] ceph_ll_walk: name=%s\n", name);
 
        uperm = vfs_ceph_userperm_new(config, handle->conn);
@@ -1860,21 +1881,7 @@ static int vfs_ceph_iget_by_fname(const struct vfs_handle_struct *handle,
                                  const struct smb_filename *smb_fname,
                                  struct vfs_ceph_iref *iref)
 {
-       const char *name = smb_fname->base_name;
-       const char *cwd = NULL;
-       int ret = -1;
-       struct vfs_ceph_config *config = NULL;
-
-       SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config,
-                               return -ENOMEM);
-
-       cwd = config->ceph_getcwd_fn(config->mount);
-       if (!strcmp(name, cwd)) {
-               ret = vfs_ceph_iget(handle, 0, "./", 0, iref);
-       } else {
-               ret = vfs_ceph_iget(handle, 0, name, 0, iref);
-       }
-       return ret;
+       return vfs_ceph_iget(handle, 0, smb_fname->base_name, 0, iref);
 }
 
 static int vfs_ceph_igetl(const struct vfs_handle_struct *handle,