From: Volker Lendecke Date: Sat, 4 Oct 2025 16:55:42 +0000 (+0200) Subject: vfs_fake_acls: Call fake_acls_fstatat() from fake_acls_[l]stat() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cfc1c0afcc820e6171cf0b206743cd7613d71327;p=thirdparty%2Fsamba.git vfs_fake_acls: Call fake_acls_fstatat() from fake_acls_[l]stat() Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Fri Oct 10 09:26:47 UTC 2025 on atb-devel-224 --- diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c index 52ddaa7add3..dd4bd19bd59 100644 --- a/source3/modules/vfs_fake_acls.c +++ b/source3/modules/vfs_fake_acls.c @@ -229,157 +229,36 @@ static int fake_acls_fstatat(struct vfs_handle_struct *handle, static int fake_acls_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int ret = -1; - struct in_pathref_data *prd = NULL; - struct smb_filename *smb_fname_cp = NULL; - struct files_struct *fsp = NULL; - NTSTATUS status; - - SMB_VFS_HANDLE_GET_DATA(handle, - prd, - struct in_pathref_data, - return -1); - - ret = SMB_VFS_NEXT_STAT(handle, smb_fname); - if (ret != 0) { - return ret; - } - - if (smb_fname->fsp != NULL) { - ret = fake_acls_fuidgid(handle, - metadata_fsp(smb_fname->fsp), - &smb_fname->st.st_ex_uid, - &smb_fname->st.st_ex_gid); - return ret; - } - - /* - * Ensure openat_pathref_fsp() can't recurse into - * fake_acls_stat(). openat_pathref_fsp() doesn't care about - * the uid/gid values, it only wants a valid/invalid stat - * answer and we know smb_fname exists as the - * SMB_VFS_NEXT_STAT() returned zero above. - */ - if (prd->calling_pathref_fsp) { - return 0; - } - - if (fsp_get_pathref_fd(handle->conn->cwd_fsp) == -1) { - /* - * No tcon around, fail as if we don't have the EAs - */ - return 0; - } + struct stat_ex st = {}; + int ret; - /* - * openat_pathref_fsp() expects a talloc'ed smb_filename. stat - * can be passed a struct from the stack. Make a talloc'ed - * copy so openat_pathref_fsp() can add its destructor. - */ - smb_fname_cp = cp_smb_filename(talloc_tos(), smb_fname); - if (smb_fname_cp == NULL) { - errno = ENOMEM; + ret = fake_acls_fstatat( + handle, handle->conn->cwd_fsp, smb_fname, &st, 0); + if (ret == -1) { return -1; } - /* Recursion guard. */ - prd->calling_pathref_fsp = true; - - status = openat_pathref_fsp(handle->conn->cwd_fsp, smb_fname_cp); - - /* End recursion guard. */ - prd->calling_pathref_fsp = false; - - if (!NT_STATUS_IS_OK(status)) { - /* - * Ignore errors here. We know the path exists (the - * SMB_VFS_NEXT_STAT() above succeeded. So being - * unable to open a pathref fsp can be due to a range - * of errors (startup path beginning with '/' for - * example, path = ".." when enumerating a - * directory. Just treat this the same way as the path - * not having the FAKE_UID or FAKE_GID EA's - * present. For the test purposes of this module (fake - * NT ACLs from windows clients) this is close enough. - * Just report for debugging purposes. - */ - DBG_DEBUG("Unable to get pathref fsp on %s. " - "Error %s\n", - smb_fname_str_dbg(smb_fname_cp), - nt_errstr(status)); - TALLOC_FREE(smb_fname_cp); - return 0; - } - fsp = smb_fname_cp->fsp; - - ret = fake_acls_fuidgid(handle, - fsp, - &smb_fname->st.st_ex_uid, - &smb_fname->st.st_ex_gid); - TALLOC_FREE(smb_fname_cp); - return ret; + smb_fname->st = st; + return 0; } static int fake_acls_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) { - int ret = -1; - struct in_pathref_data *prd = NULL; - struct smb_filename *smb_fname_base = NULL; - SMB_STRUCT_STAT sbuf = {0}; - NTSTATUS status; - - SMB_VFS_HANDLE_GET_DATA(handle, - prd, - struct in_pathref_data, - return -1); - - ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname); - if (ret != 0) { - return ret; - } - - /* - * Ensure synthetic_pathref() can't recurse into - * fake_acls_lstat(). synthetic_pathref() doesn't care about - * the uid/gid values, it only wants a valid/invalid stat - * answer and we know smb_fname exists as the - * SMB_VFS_NEXT_LSTAT() returned zero above. - */ - if (prd->calling_pathref_fsp) { - return 0; - } + struct stat_ex st = {}; + int ret; - /* Recursion guard. */ - prd->calling_pathref_fsp = true; - status = synthetic_pathref(talloc_tos(), - handle->conn->cwd_fsp, - smb_fname->base_name, - NULL, - &sbuf, - smb_fname->twrp, - 0, /* we want stat, not lstat. */ - &smb_fname_base); - /* End recursion guard. */ - prd->calling_pathref_fsp = false; - if (NT_STATUS_IS_OK(status)) { - /* - * This isn't quite right (calling fgetxattr not - * lgetxattr), but for the test purposes of this - * module (fake NT ACLs from windows clients), it is - * close enough. We removed the l*xattr functions - * because linux doesn't support using them, but we - * could fake them in xattr_tdb if we really wanted - * to. We ignore errors because the link might not - * point anywhere */ - fake_acls_fuidgid(handle, - smb_fname_base->fsp, - &smb_fname->st.st_ex_uid, - &smb_fname->st.st_ex_gid); + ret = fake_acls_fstatat(handle, + handle->conn->cwd_fsp, + smb_fname, + &st, + AT_SYMLINK_NOFOLLOW); + if (ret == -1) { + return -1; } - TALLOC_FREE(smb_fname_base); - return ret; + smb_fname->st = st; + return 0; } static int fake_acls_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)