From: Anoop C S Date: Mon, 24 Feb 2025 08:30:56 +0000 (+0530) Subject: vfs_ceph_new: Handle absolute path in vfs_ceph_ll_walk X-Git-Tag: tevent-0.17.0~582 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9341d7fb466c95ea5aa0643049ce2a1f4183b9d0;p=thirdparty%2Fsamba.git vfs_ceph_new: Handle absolute path in vfs_ceph_ll_walk 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 Reviewed-by: Guenther Deschner --- diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index de55449da24..e8da512273a 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -816,10 +816,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); @@ -1854,21 +1875,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,