FreeBSD Bugzilla – Attachment 256497 Details for
Bug 277878
net/samba419: Function not implemented facl(ACE_GETACLCNT, filename) with vfs_zfsacl
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to fix pathref handling in Samba 4.19
freebsd_pathref_zfsacl_max.patch (text/plain), 11.59 KB, created by
Peter Eriksson
on 2025-01-07 09:18:21 UTC
(
hide
)
Description:
Patch to fix pathref handling in Samba 4.19
Filename:
MIME Type:
Creator:
Peter Eriksson
Created:
2025-01-07 09:18:21 UTC
Size:
11.59 KB
patch
obsolete
>--- samba-4.18.3-orig/source3/smbd/open.c 2023-04-19 12:18:56.254875400 +0200 >+++ samba-4.18.3/source3/smbd/open.c 2023-06-20 08:29:06.210298000 +0200 >@@ -1204,9 +1204,6 @@ > int new_fd; > NTSTATUS status; > >- if (!fsp->fsp_flags.have_proc_fds) { >- return NT_STATUS_MORE_PROCESSING_REQUIRED; >- } > > old_fd = fsp_get_pathref_fd(fsp); > if (old_fd == -1) { >@@ -1222,22 +1219,28 @@ > return NT_STATUS_INVALID_HANDLE; > } > >- p = sys_proc_fd_path(old_fd, buf, sizeof(buf)); >- if (p == NULL) { >- return NT_STATUS_NO_MEMORY; >- } >+ >+ if (sys_open_real_fd_from_pathref_fd(old_fd, &new_fd, flags) != 0) { >+ if (!fsp->fsp_flags.have_proc_fds) { >+ return NT_STATUS_MORE_PROCESSING_REQUIRED; >+ } > >- proc_fname = (struct smb_filename) { >- .base_name = discard_const_p(char, p), >- }; >+ p = sys_proc_fd_path(old_fd, buf, sizeof(buf)); >+ if (p == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } > >- fsp->fsp_flags.is_pathref = false; >+ proc_fname = (struct smb_filename) { >+ .base_name = discard_const_p(char, p), >+ }; > >- new_fd = SMB_VFS_OPENAT(fsp->conn, >- fsp->conn->cwd_fsp, >- &proc_fname, >- fsp, >- &how); >+ new_fd = SMB_VFS_OPENAT(fsp->conn, >+ fsp->conn->cwd_fsp, >+ &proc_fname, >+ fsp, >+ &how); >+ } >+ > if (new_fd == -1) { > status = map_nt_error_from_unix(errno); > fd_close(fsp); >@@ -1250,6 +1260,8 @@ > } > > fsp_set_fd(fsp, new_fd); >+ fsp->fsp_flags.is_pathref = false; >+ > return NT_STATUS_OK; > } > >--- samba-4.18.3-orig/source3/lib/system.c 2023-01-18 16:32:24.174553200 +0100 >+++ samba-4.18.3/source3/lib/system.c 2023-06-19 23:35:30.132465000 +0200 >@@ -1022,6 +1022,8 @@ > } proc_fd_patterns[] = { > /* Linux */ > { "/proc/self/fd/%d", "/proc/self/fd/0" }, >+ /* FreeBSD */ >+ { "/compat/linux/dev/fd/%d", "/compat/linux/dev/fd/0" }, > { NULL, NULL }, > }; > >@@ -1077,4 +1079,27 @@ > } > > return buf; >+} >+ >+ >+/* Helper function that opens a usable fd for accessing data >+ (metadata & content) from a pathref fd */ >+int sys_open_real_fd_from_pathref_fd(int fd, >+ int *rfd, >+ int flags) { >+ int tfd; >+ >+#if defined(HAVE_OPENAT) && defined(O_EMPTY_PATH) >+ /* This works for FreeBSD 13+ atleast */ >+ >+ tfd = openat(fd, "", O_EMPTY_PATH|flags); >+ if (tfd < 0) { >+ return errno; >+ } >+ >+ *rfd = tfd; >+ return 0; >+#else >+ return ENOSYS; >+#endif > } >--- samba-4.18.3-orig/source3/modules/vfs_default.c 2023-05-31 18:06:44.154299500 +0200 >+++ samba-4.18.3/source3/modules/vfs_default.c 2023-06-19 23:23:58.116903000 +0200 >@@ -2721,7 +2721,7 @@ > > static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) > { >- int result; >+ int result, fd, real_fd; > > START_PROFILE(syscall_fchmod); > >@@ -2731,8 +2731,9 @@ > return result; > } > >+ fd = fsp_get_pathref_fd(fsp); >+ > if (fsp->fsp_flags.have_proc_fds) { >- int fd = fsp_get_pathref_fd(fsp); > const char *p = NULL; > char buf[PATH_MAX]; > >@@ -2746,6 +2747,17 @@ > return result; > } > >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno; >+ >+ result = fchmod(real_fd, mode); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ END_PROFILE(syscall_fchmod); >+ return result; >+ } >+ > /* > * This is no longer a handle based call. > */ >@@ -2758,7 +2770,7 @@ > static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid) > { > #ifdef HAVE_FCHOWN >- int result; >+ int result, fd, real_fd; > > START_PROFILE(syscall_fchown); > if (!fsp->fsp_flags.is_pathref) { >@@ -2767,8 +2779,9 @@ > return result; > } > >+ fd = fsp_get_pathref_fd(fsp); >+ > if (fsp->fsp_flags.have_proc_fds) { >- int fd = fsp_get_pathref_fd(fsp); > const char *p = NULL; > char buf[PATH_MAX]; > >@@ -2782,6 +2795,17 @@ > return result; > } > >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno; >+ >+ result = fchown(real_fd, uid, gid); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ END_PROFILE(syscall_fchown); >+ return result; >+ } >+ > /* > * This is no longer a handle based call. > */ >@@ -2855,7 +2879,7 @@ > files_struct *fsp, > struct smb_file_time *ft) > { >- int result = -1; >+ int result = -1, fd, real_fd; > struct timespec ts[2]; > struct timespec *times = NULL; > >@@ -2900,8 +2924,9 @@ > goto out; > } > >+ fd = fsp_get_pathref_fd(fsp); >+ > if (fsp->fsp_flags.have_proc_fds) { >- int fd = fsp_get_pathref_fd(fsp); > const char *p = NULL; > char buf[PATH_MAX]; > >@@ -2919,6 +2944,16 @@ > goto out; > } > >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno; >+ >+ result = futimens(real_fd, times); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ goto out; >+ } >+ > /* > * The fd is a pathref (opened with O_PATH) and there isn't fd to > * path translation mechanism. Fallback to path based call. >@@ -3322,6 +3357,7 @@ > { > #ifdef HAVE_FCHFLAGS > int fd = fsp_get_pathref_fd(fsp); >+ int real_fd; > > SMB_ASSERT(!fsp_is_alternate_stream(fsp)); > >@@ -3341,6 +3377,16 @@ > return chflags(p, flags); > } > >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno, result; >+ >+ result = fchflags(real_fd, flags); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ return result; >+ } >+ > /* > * This is no longer a handle based call. > */ >@@ -3569,6 +3615,7 @@ > size_t size) > { > int fd = fsp_get_pathref_fd(fsp); >+ int real_fd; > > SMB_ASSERT(!fsp_is_alternate_stream(fsp)); > >@@ -3588,6 +3635,16 @@ > return getxattr(p, name, value, size); > } > >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno, result; >+ >+ result = fgetxattr(real_fd, name, value, size); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ return result; >+ } >+ > /* > * This is no longer a handle based call. > */ >@@ -3895,6 +3952,7 @@ > static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size) > { > int fd = fsp_get_pathref_fd(fsp); >+ int real_fd; > > SMB_ASSERT(!fsp_is_alternate_stream(fsp)); > >@@ -3914,6 +3972,16 @@ > return listxattr(p, list, size); > } > >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno, result; >+ >+ result = flistxattr(real_fd, list, size); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ return result; >+ } >+ > /* > * This is no longer a handle based call. > */ >@@ -3923,6 +3991,7 @@ > static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name) > { > int fd = fsp_get_pathref_fd(fsp); >+ int real_fd; > > SMB_ASSERT(!fsp_is_alternate_stream(fsp)); > >@@ -3942,6 +4011,16 @@ > return removexattr(p, name); > } > >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno, result; >+ >+ result = fremovexattr(real_fd, name); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ return result; >+ } >+ > /* > * This is no longer a handle based call. > */ >@@ -3951,6 +4030,7 @@ > static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags) > { > int fd = fsp_get_pathref_fd(fsp); >+ int real_fd; > > SMB_ASSERT(!fsp_is_alternate_stream(fsp)); > >@@ -3968,6 +4048,16 @@ > } > > return setxattr(p, name, value, size, flags); >+ } >+ >+ if (sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ int saved_errno, result; >+ >+ result = fsetxattr(real_fd, name, value, size, flags); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ return result; > } > > /* >--- samba-4.18.3-orig/source3/modules/vfs_zfsacl.c 2023-01-18 16:32:24.210553400 +0100 >+++ samba-4.18.3/source3/modules/vfs_zfsacl.c 2023-06-20 08:51:53.077953000 +0200 >@@ -234,13 +234,39 @@ > > SMB_ASSERT(i == naces); > >- /* store acl */ >- fd = fsp_get_pathref_fd(fsp); >- if (fd == -1) { >- errno = EBADF; >- return false; >+ if (!fsp->fsp_flags.is_pathref) { >+ rv = facl(fsp_get_io_fd(fsp), ACE_SETACL, naces, acebuf); >+ } else { >+ const char *procfd_p = NULL; >+ char buf[PATH_MAX]; >+ >+ fd = fsp_get_pathref_fd(fsp); >+ if (fsp->fsp_flags.have_proc_fds && (procfd_p = sys_proc_fd_path(fd, buf, sizeof(buf)))) { >+ rv = acl(procfd_p, ACE_SETACL, naces, acebuf); >+ } else { >+ int real_fd; >+ >+ fd = fsp_get_pathref_fd(fsp); >+ >+ /* First try this for versions of FreeBSD 13+ that allows facl() on O_PATH fd's */ >+ rv = facl(fd, ACE_SETACL, naces, acebuf); >+ >+ if (rv < 0 && errno == EBADF && >+ sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ /* Works on FreeBSD 13+ */ >+ int saved_errno; >+ >+ rv = facl(real_fd, ACE_SETACL, naces, acebuf); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ } else { >+ /* Last ditch fallback */ >+ rv = acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf); >+ } >+ } > } >- rv = facl(fd, ACE_SETACL, naces, acebuf); >+ > if (rv != 0) { > if(errno == ENOSYS) { > DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not " >@@ -284,14 +310,39 @@ > { > int naces, rv; > ace_t *acebuf = NULL; >- int fd; >+ int fd = -1; >+ const char *procfd_p = NULL; >+ char buf[PATH_MAX]; > >- fd = fsp_get_pathref_fd(fsp); >- if (fd == -1) { >- errno = EBADF; >- return -1; >+ if (!fsp->fsp_flags.is_pathref) { >+ naces = facl(fsp_get_io_fd(fsp), ACE_GETACLCNT, 0, NULL); >+ } else { >+ fd = fsp_get_pathref_fd(fsp); >+ >+ if (fsp->fsp_flags.have_proc_fds && (procfd_p = sys_proc_fd_path(fd, buf, sizeof(buf)))) { >+ /* If we have procfd support, try this first */ >+ naces = acl(procfd_p, ACE_GETACLCNT, 0, NULL); >+ } else { >+ int real_fd; >+ >+ /* First try this for versions of FreeBSD 13+ that allows facl() on O_PATH fd's */ >+ naces = facl(fd, ACE_GETACLCNT, 0, NULL); >+ if (naces < 0 && errno == EBADF && >+ sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ /* Works on FreeBSD 13+ */ >+ int saved_errno; >+ >+ naces = facl(real_fd, ACE_GETACLCNT, 0, NULL); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ } else { >+ /* Last ditch fallback */ >+ naces = acl(fsp->fsp_name->base_name, ACE_GETACLCNT, 0, NULL); >+ } >+ } > } >- naces = facl(fd, ACE_GETACLCNT, 0, NULL); >+ > if (naces == -1) { > int dbg_level = 10; > >@@ -309,7 +360,32 @@ > return -1; > } > >- rv = facl(fd, ACE_GETACL, naces, acebuf); >+ if (!fsp->fsp_flags.is_pathref) { >+ rv = facl(fsp_get_io_fd(fsp), ACE_GETACL, naces, acebuf); >+ } else { >+ if (procfd_p) { >+ rv = acl(procfd_p, ACE_GETACL, naces, acebuf); >+ } else { >+ int real_fd; >+ >+ /* First try this for versions of FreeBSD that allows facl() on O_PATH fd's */ >+ rv = facl(fd, ACE_GETACL, naces, acebuf); >+ if (rv < 0 && errno == EBADF && >+ sys_open_real_fd_from_pathref_fd(fd, &real_fd, O_RDONLY|O_NONBLOCK) == 0) { >+ /* Works on FreeBSD 13+ */ >+ int saved_errno; >+ >+ rv = facl(real_fd, ACE_GETACL, naces, acebuf); >+ saved_errno = errno; >+ close(real_fd); >+ errno = saved_errno; >+ } else { >+ /* Last ditch fallback */ >+ rv = acl(fsp->fsp_name->base_name, ACE_GETACL, naces, acebuf); >+ } >+ } >+ } >+ > if (rv == -1) { > DBG_DEBUG("acl(ACE_GETACL, %s): %s ", > fsp_str_dbg(fsp), strerror(errno)); >--- samba-4.18.3-orig/source3/include/proto.h 2023-05-31 18:06:44.142299400 +0200 >+++ samba-4.18.3/source3/include/proto.h 2023-06-19 23:23:58.115127000 +0200 >@@ -211,6 +211,10 @@ > bool sys_have_proc_fds(void); > const char *sys_proc_fd_path(int fd, char *buf, size_t bufsize); > >+int sys_open_real_fd_from_pathref_fd(int fd, >+ int *mfd, >+ int flags); >+ > struct stat; > void init_stat_ex_from_stat (struct stat_ex *dst, > const struct stat *src,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 277878
:
249703
|
249849
| 256497 |
256506
|
256507