]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_fake_acls: Call fake_acls_fstatat() from fake_acls_[l]stat()
authorVolker Lendecke <vl@samba.org>
Sat, 4 Oct 2025 16:55:42 +0000 (18:55 +0200)
committerRalph Boehme <slow@samba.org>
Fri, 10 Oct 2025 09:26:46 +0000 (09:26 +0000)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Fri Oct 10 09:26:47 UTC 2025 on atb-devel-224

source3/modules/vfs_fake_acls.c

index 52ddaa7add3f996a271600753b4ba20573c4a6e1..dd4bd19bd59d65ea9c15513ac28eeaab9bfbfd4d 100644 (file)
@@ -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)