From: Samuel Cabrero Date: Wed, 8 Oct 2025 11:53:14 +0000 (+0200) Subject: smbd: Refactor reopen_from_fsp(), factor out automounter mountpoint check X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4fce96afa638eba8f301db8997ad034e83d94a8b;p=thirdparty%2Fsamba.git smbd: Refactor reopen_from_fsp(), factor out automounter mountpoint check BUG: https://bugzilla.samba.org/show_bug.cgi?id=15805 Signed-off-by: Samuel Cabrero Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 9751aba0c52..081b85c80ec 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -872,6 +872,30 @@ static NTSTATUS reopen_from_fsp_namebased(struct files_struct *dirfsp, return status; } +static bool fsp_is_automount_mountpoint(struct files_struct *fsp, int old_fd) +{ +#if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H) + struct statfs sbuf = {}; + int ret; + + if (!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) { + return false; + } + + ret = fstatfs(old_fd, &sbuf); + if (ret == -1) { + DBG_ERR("fstatfs failed: %s\n", strerror(errno)); + return false; + } + if (sbuf.f_type == AUTOFS_SUPER_MAGIC) { + return true; + } + return false; +#else + return false; +#endif +} + NTSTATUS reopen_from_fsp(struct files_struct *dirfsp, struct smb_filename *smb_fname, struct files_struct *fsp, @@ -906,33 +930,23 @@ NTSTATUS reopen_from_fsp(struct files_struct *dirfsp, fsp, how); if (new_fd == -1) { -#if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H) - if (S_ISDIR(fsp->fsp_name->st.st_ex_mode) && - (errno == ENOENT)) { - struct statfs sbuf = {}; - int ret = fstatfs(old_fd, &sbuf); - if (ret == -1) { - DBG_ERR("fstatfs failed: %s\n", - strerror(errno)); - } else if (sbuf.f_type == AUTOFS_SUPER_MAGIC) { - /* - * When reopening an as-yet - * unmounted autofs mount - * point we get ENOENT. We - * have to retry pathbased. - */ - return reopen_from_fsp_namebased(dirfsp, - smb_fname, - fsp, - how, - p_file_created); - - } - /* restore ENOENT if changed in the meantime */ - errno = ENOENT; + int saved_errno = errno; + if (saved_errno == ENOENT && + fsp_is_automount_mountpoint(fsp, old_fd)) + { + /* + * When reopening an as-yet unmounted autofs + * mount point we get ENOENT. We have to retry + * pathbased. + */ + return reopen_from_fsp_namebased(dirfsp, + smb_fname, + fsp, + how, + p_file_created); } -#endif - status = map_nt_error_from_unix(errno); + + status = map_nt_error_from_unix(saved_errno); fd_close(fsp); return status; }