diff --git a/net/samba419/Makefile b/net/samba419/Makefile --- a/net/samba419/Makefile +++ b/net/samba419/Makefile @@ -1,6 +1,6 @@ PORTNAME= ${SAMBA4_BASENAME}419 PORTVERSION= ${SAMBA4_VERSION} -PORTREVISION= 2 +PORTREVISION= 3 CATEGORIES?= net MASTER_SITES= SAMBA/samba/stable SAMBA/samba/rc DISTNAME= ${SAMBA4_DISTNAME} diff --git a/net/samba419/files/0100-Fix-pathref-handling-for-FreeBSD-13plus.patch b/net/samba419/files/0100-Fix-pathref-handling-for-FreeBSD-13plus.patch --- a/net/samba419/files/0100-Fix-pathref-handling-for-FreeBSD-13plus.patch +++ b/net/samba419/files/0100-Fix-pathref-handling-for-FreeBSD-13plus.patch @@ -1,68 +1,5 @@ https://bugzilla.samba.org/show_bug.cgi?id=15376 ---- source3/smbd/open.c 2023-04-19 12:18:56.254875400 +0200 -+++ 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; - } - --- source3/lib/system.c 2023-01-18 16:32:24.174553200 +0100 +++ source3/lib/system.c 2023-06-19 23:35:30.132465000 +0200 @@ -1022,6 +1022,8 @@ @@ -74,412 +11,183 @@ { 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 - } ---- source3/modules/vfs_default.c 2023-05-31 18:06:44.154299500 +0200 -+++ 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; - } - - /* ---- source3/modules/vfs_zfsacl.c 2023-01-18 16:32:24.210553400 +0100 -+++ source3/modules/vfs_zfsacl.c 2023-06-20 08:51:53.077953000 +0200 -@@ -234,13 +234,39 @@ +--- source3/modules/vfs_zfsacl.c 2023-11-27 13:09:10.612012900 +0100 ++++ source3/modules/vfs_zfsacl.c 2025-01-07 18:53:05.292522000 +0100 +@@ -169,6 +169,7 @@ + bool must_add_empty_ace = false; + struct zfsacl_config_data *config = NULL; + int fd; ++ char buf[PATH_MAX]; + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct zfsacl_config_data, +@@ -235,22 +236,49 @@ SMB_ASSERT(i == naces); -- /* store acl */ + /* 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); -+ } -+ } - } ++ fd = fsp_get_io_fd(fsp); ++ ++ rv = facl(fd, ACE_SETACL, naces, acebuf); ++ if (rv != 0) { ++ DEBUG(8, ("zfs_process_smbacl(%s): Not PATHREF: facl(ACE_SETACL, %d): %s\n", ++ fsp_str_dbg(fsp), naces, ++ strerror(errno))); ++ return false; ++ } ++ DEBUG(10, ("zfs_process_smbacl(%s): Not PATHREF: facl(ACE_SETACL, %d) -> %d\n", ++ fsp_str_dbg(fsp), naces, ++ rv)); ++ ++ } else if (fsp->fsp_flags.have_proc_fds) { ++ fd = fsp_get_pathref_fd(fsp); ++ if (fd == -1) { ++ DEBUG(8, ("zfs_process_smbacl(%s): PATHREF(proc_fd): fsp_get_pathref_fd=-1: %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); + errno = EBADF; + return false; +- } - 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 @@ +- if (rv != 0) { +- if(errno == ENOSYS) { +- DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not " +- "supported on the filesystem where the file " +- "reside", fsp_str_dbg(fsp))); +- } else { +- DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp), +- strerror(errno))); +- } ++ } ++ rv = acl(sys_proc_fd_path(fd, buf, sizeof(buf)), ACE_SETACL, naces, acebuf); ++ if (rv != 0) { ++ DEBUG(8, ("zfs_process_smbacl(%s): acl(ACE_SETACL, %d): %s\n", ++ fsp_str_dbg(fsp), naces, ++ strerror(errno))); + return false; ++ } ++ DEBUG(10, ("zfs_process_smbacl(%s): PATHREF(proc_fd): acl(ACE_SETACL, %d) -> %d\n", ++ fsp_str_dbg(fsp), naces, ++ rv)); ++ } else { ++ rv = acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf); ++ if (rv != 0) { ++ DEBUG(8, ("zfs_process_smbacl(%s): PATHREF(base_name): acl(ACE_SETACL, %d): %s\n", ++ fsp_str_dbg(fsp), naces, ++ strerror(errno))); ++ return false; ++ } ++ DEBUG(10, ("zfs_process_smbacl(%s): PATHREF(base_name): facl(ACE_SETACL, %d) -> %d\n", ++ fsp_str_dbg(fsp), naces, ++ rv)); + } + + return True; +@@ -282,25 +310,48 @@ + struct files_struct *fsp, + ace_t **outbuf) { - int naces, rv; +- int naces, rv; ++ int naces, rv = -1, fd = -1; 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; ++ char buf[PATH_MAX]; + -+ 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; ++ if (!fsp->fsp_flags.is_pathref) { ++ fd = fsp_get_io_fd(fsp); ++ if (fd == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): Not PATHREF: fsp_get_io_fd=-1: %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); + errno = EBADF; + return -1; +- } +- naces = facl(fd, ACE_GETACLCNT, 0, NULL); +- if (naces == -1) { +- int dbg_level = 10; +- +- if (errno == ENOSYS) { +- dbg_level = 1; +- } +- DEBUG(dbg_level, ("facl(ACE_GETACLCNT, %s): %s ", ++ } ++ naces = facl(fd, ACE_GETACLCNT, 0, NULL); ++ if (naces == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): Not PATHREF: facl(ACE_GETACLCNT): %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); ++ return -1; ++ } ++ } else if (fsp->fsp_flags.have_proc_fds) { ++ fd = fsp_get_pathref_fd(fsp); ++ if (fd == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): PATHREF(proc_fd): fsp_get_pathref_fd=-1: %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); ++ errno = EBADF; ++ return -1; ++ } ++ naces = acl(sys_proc_fd_path(fd, buf, sizeof(buf)), ACE_GETACLCNT, 0, NULL); ++ if (naces == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): PATHREF(proc_fd): acl(ACE_GETACLCNT): %s\n", + fsp_str_dbg(fsp), strerror(errno))); +- return naces; ++ return -1; ++ } ++ } else { ++ naces = acl(fsp->fsp_name->base_name, ACE_GETACLCNT, 0, NULL); ++ if (naces == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): PATHREF(base_name): acl(ACE_GETACLCNT): %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); ++ return -1; ++ } + } -@@ -309,7 +360,32 @@ + acebuf = talloc_size(mem_ctx, sizeof(ace_t)*naces); +@@ -309,15 +360,37 @@ return -1; } - rv = facl(fd, ACE_GETACL, naces, acebuf); +- if (rv == -1) { +- DBG_DEBUG("acl(ACE_GETACL, %s): %s ", +- fsp_str_dbg(fsp), strerror(errno)); + if (!fsp->fsp_flags.is_pathref) { -+ rv = facl(fsp_get_io_fd(fsp), ACE_GETACL, naces, acebuf); ++ rv = facl(fd, ACE_GETACL, naces, acebuf); ++ if (rv == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): Not PATHREF: facl(ACE_GETACL): %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); + return -1; ++ } ++ DEBUG(10, ("fget_zfsacl(%s): Not PATHREF: facl(ACE_GETACL) -> %d entries\n", ++ fsp_str_dbg(fsp), rv)); ++ } else if (fsp->fsp_flags.have_proc_fds) { ++ rv = acl(sys_proc_fd_path(fd, buf, sizeof(buf)), ACE_GETACL, naces, acebuf); ++ if (rv == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): PATHREF(proc_fd): acl(ACE_GETACL): %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); ++ return -1; ++ } ++ DEBUG(10, ("fget_zfsacl(%s): PATHREF(proc_fd): acl(ACE_GETACL) -> %d entries\n", ++ fsp_str_dbg(fsp), rv)); + } 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)); ---- source3/include/proto.h 2023-05-31 18:06:44.142299400 +0200 -+++ 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); ++ rv = acl(fsp->fsp_name->base_name, ACE_GETACL, naces, acebuf); ++ if (rv == -1) { ++ DEBUG(8, ("fget_zfsacl(%s): PATHREF(base_name): acl(ACE_GETACL): %s\n", ++ fsp_str_dbg(fsp), strerror(errno))); ++ return -1; ++ } ++ DEBUG(10, ("fget_zfsacl(%s): PATHREF(base_name): acl(ACE_GETACL) -> %d entries\n", ++ fsp_str_dbg(fsp), rv)); + } +- ++ + *outbuf = acebuf; +- return naces; ++ return rv; + } -+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, + static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle,