Date: Tue, 30 May 2023 21:06:08 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 271704] O_PATH and acl_get_fd_np doesn't work on FreeBSD 13(.2) and causes vfs_zfsacl in Samba to fail Message-ID: <bug-271704-227-P1jQshIEBA@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-271704-227@https.bugs.freebsd.org/bugzilla/> References: <bug-271704-227@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D271704 --- Comment #9 from Peter Eriksson <pen@lysator.liu.se> --- Linux uses the getxattr/setxattr calls for NFS stuff. Well, the generic way Samba handles O_PATH stuff on Linux for syscalls that fails is apparently to use /proc/self/fd/%d (where %d is the fd for the O_P= ATH descriptor) and then call the path-based variants of the syscall using that path instead of using the fd if (!fsp->fsp_flags.is_pathref) { result =3D fchmod(fsp_get_io_fd(fsp), mode); END_PROFILE(syscall_fchmod); return result; } if (fsp->fsp_flags.have_proc_fds) { int fd =3D fsp_get_pathref_fd(fsp); const char *p =3D NULL; char buf[PATH_MAX]; p =3D sys_proc_fd_path(fd, buf, sizeof(buf)); if (p !=3D NULL) { result =3D chmod(p, mode); } else { result =3D -1; } END_PROFILE(syscall_fchmod); return result; } /*=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 * This is no longer a handle based call.=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 */ result =3D chmod(fsp->fsp_name->base_name, mode); (The last line of code is the reason most calls still work for a default-compiled Samba on FreeBSD 13 - it falls back to using the (insecure) full path based functionality... But that code was missing in the vfs_zfsacl module). For FreeBSD I think using openat(fd, "", O_EMPTY_PATH) is a cleaner way to = get an fd that you can use... Something like this: if (!fsp->fsp_flags.is_pathref) { rv =3D facl(fsp_get_io_fd(fsp), ACE_SETACL, naces, acebuf); } else { #if defined(HAVE_OPENAT) && defined(O_EMPTY_PATH) fd =3D fsp_get_pathref_fd(fsp); /* First try this for versions of FreeBSD that allows facl(= ) on O_PATH fd's */ rv =3D facl(fd, ACE_SETACL, naces, acebuf); if (rv < 0 && errno =3D=3D EBADF) { /* Fall back to getting a real fd via openat() */ int saved_errno, real_fd; real_fd =3D openat(fd, "", O_EMPTY_PATH); if (real_fd < 0) { errno =3D EBADF; return false; } rv =3D facl(real_fd, ACE_SETACL, naces, acebuf); saved_errno =3D errno; close(real_fd); errno =3D saved_errno; } #else /* Last ditch fallback */ rv =3D acl(fsp->fsp_name->base_name, ACE_SETACL, naces, ace= buf); #endif } (facl is a helper function in libsunacl that calls the right acl_get_fd_np/acl_get_file functions that Samba uses for compatibility with Solaris). --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-271704-227-P1jQshIEBA>