https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=78adc10ab819f10e1b6211b4bbc149e97f9b9e36
commit 78adc10ab819f10e1b6211b4bbc149e97f9b9e36 Author: Corinna Vinschen <[email protected]> AuthorDate: Mon Mar 31 10:58:26 2025 +0200 Commit: Corinna Vinschen <[email protected]> CommitDate: Mon Mar 31 22:03:48 2025 +0200 Cygwin: ACLs: Add some useful non-POSIX ACL functions from FreeBSD Add the following functions: acl_get_fd_np acl_get_link_np acl_get_perm_np acl_is_trivial_np acl_set_fd_np acl_set_link_np acl_strip_np Signed-off-by: Corinna Vinschen <[email protected]> Diff: --- winsup/cygwin/cygwin.din | 7 ++ winsup/cygwin/include/cygwin/version.h | 4 +- winsup/cygwin/include/sys/acl.h | 12 +++ winsup/cygwin/sec/posixacl.cc | 179 ++++++++++++++++++++++++++++++--- winsup/doc/posix.xml | 7 ++ 5 files changed, 193 insertions(+), 16 deletions(-) diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index deac201c085c..d7a17b234a4c 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -179,18 +179,25 @@ acl_from_mode NOSIGFE acl_from_text SIGFE acl_get_entry NOSIGFE acl_get_fd SIGFE +acl_get_fd_np SIGFE acl_get_file SIGFE +acl_get_link_np SIGFE acl_get_perm NOSIGFE +acl_get_perm_np = acl_get_perm NOSIGFE acl_get_permset NOSIGFE acl_get_qualifier SIGFE acl_get_tag_type NOSIGFE acl_init SIGFE +acl_is_trivial_np SIGFE acl_set_fd SIGFE +acl_set_fd_np SIGFE acl_set_file SIGFE +acl_set_link_np SIGFE acl_set_permset NOSIGFE acl_set_qualifier NOSIGFE acl_set_tag_type NOSIGFE acl_size NOSIGFE +acl_strip_np SIGFE acl_to_any_text SIGFE acl_to_text SIGFE acl_valid NOSIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index f341dba5b988..e4c16db43e30 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -493,12 +493,14 @@ details. */ 356: Export posix_spawn_file_actions_addchdir and posix_spawn_file_actions_addfchdir. 357: Export posix_close. + 358: Export acl_get_fd_np, acl_get_link_np, acl_get_perm_np, + acl_is_trivial_np, acl_set_fd_np, acl_set_link_np, acl_strip_np. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 357 +#define CYGWIN_VERSION_API_MINOR 358 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/cygwin/include/sys/acl.h b/winsup/cygwin/include/sys/acl.h index 74e50ba9e1d4..5789dd03a80c 100644 --- a/winsup/cygwin/include/sys/acl.h +++ b/winsup/cygwin/include/sys/acl.h @@ -92,6 +92,18 @@ extern ssize_t acl_size (acl_t __acl); extern char *acl_to_text (acl_t __acl, ssize_t *__len_p); extern int acl_valid (acl_t __acl); +/* Non-libacl extensions to POSIX.1e draft 17 */ + +/* FreeBSD, NetBSD */ +extern acl_t acl_get_fd_np (int __fd, acl_type_t __type); +extern acl_t acl_get_link_np (const char *__path_p, acl_type_t __type); +extern int acl_get_perm_np (acl_permset_t __permset_d, acl_perm_t __perm); +extern int acl_is_trivial_np (const acl_t __acl, int *__trivialp); +extern int acl_set_fd_np (int __fd, acl_t __acl, acl_type_t __type); +extern int acl_set_link_np (const char *__path_p, acl_type_t __type, + acl_t __acl); +extern acl_t acl_strip_np (const acl_t __acl, int __recalculate_mask); + #ifdef __cplusplus } #endif diff --git a/winsup/cygwin/sec/posixacl.cc b/winsup/cygwin/sec/posixacl.cc index 6b01ded5906b..6f3ef15ca216 100644 --- a/winsup/cygwin/sec/posixacl.cc +++ b/winsup/cygwin/sec/posixacl.cc @@ -322,7 +322,7 @@ acl_delete_perm (acl_permset_t permset_d, acl_perm_t perm) } __except (EINVAL) {} __endtry - return -1; + return -1; } extern "C" int @@ -674,14 +674,11 @@ fhandler_socket_unix::acl_get (acl_type_t type) extern "C" acl_t acl_get_fd (int fd) { - cygheap_fdget cfd (fd); - if (cfd < 0) - return NULL; - return cfd->acl_get (ACL_TYPE_ACCESS); + return acl_get_fd_np (fd, ACL_TYPE_ACCESS); } -extern "C" acl_t -acl_get_file (const char *path_p, acl_type_t type) +static acl_t +__acl_get_file (const char *path_p, acl_type_t type, unsigned follow_mode) { if (type != ACL_TYPE_ACCESS && type != ACL_TYPE_DEFAULT) { @@ -689,7 +686,7 @@ acl_get_file (const char *path_p, acl_type_t type) return NULL; } fhandler_base *fh; - if (!(fh = build_fh_name (path_p, PC_SYM_FOLLOW, stat_suffixes))) + if (!(fh = build_fh_name (path_p, follow_mode, stat_suffixes))) return NULL; if (fh->error ()) { @@ -701,6 +698,12 @@ acl_get_file (const char *path_p, acl_type_t type) return acl; } +extern "C" acl_t +acl_get_file (const char *path_p, acl_type_t type) +{ + return __acl_get_file (path_p, type, PC_SYM_FOLLOW); +} + int fhandler_base::acl_set (acl_t acl, acl_type_t type) { @@ -844,14 +847,12 @@ fhandler_socket_unix::acl_set (acl_t acl, acl_type_t type) extern "C" int acl_set_fd (int fd, acl_t acl) { - cygheap_fdget cfd (fd); - if (cfd < 0) - return -1; - return cfd->acl_set (acl, ACL_TYPE_ACCESS); + return acl_set_fd_np (fd, acl, ACL_TYPE_ACCESS); } -extern "C" int -acl_set_file(const char *path_p, acl_type_t type, acl_t acl) +static int +__acl_set_file (const char *path_p, acl_type_t type, acl_t acl, + unsigned follow_mode) { if (type != ACL_TYPE_ACCESS && type != ACL_TYPE_DEFAULT) { @@ -859,7 +860,7 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl) return -1; } fhandler_base *fh; - if (!(fh = build_fh_name (path_p, PC_SYM_FOLLOW, stat_suffixes))) + if (!(fh = build_fh_name (path_p, follow_mode, stat_suffixes))) return -1; if (fh->error ()) { @@ -871,6 +872,12 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl) return ret; } +extern "C" int +acl_set_file (const char *path_p, acl_type_t type, acl_t acl) +{ + return __acl_set_file (path_p, type, acl, PC_SYM_FOLLOW); +} + extern "C" int acl_delete_def_file (const char *path_p) { @@ -1151,3 +1158,145 @@ acl_to_any_text (acl_t acl, const char *prefix, char separator, int options) __endtry return NULL; } + +/* FreeBSD extensions */ + +extern "C" acl_t +acl_get_fd_np (int fd, acl_type_t type) +{ + cygheap_fdget cfd (fd); + if (cfd < 0) + return NULL; + return cfd->acl_get (type); +} + +extern "C" int +acl_is_trivial_np (const acl_t acl, int *trivialp) +{ + __try + { + if (!(__aclcheck (acl->entry, acl->count, NULL, true))) + *trivialp = acl->count - acl->deleted <= MIN_ACL_ENTRIES ? 1 : 0; + return 0; + } + __except (EINVAL) {} + __endtry + return -1; +} + +extern "C" acl_t +acl_get_link_np (const char *path_p, acl_type_t type) +{ + return __acl_get_file (path_p, type, PC_SYM_NOFOLLOW); +} + +extern "C" int +acl_set_fd_np (int fd, acl_t acl, acl_type_t type) +{ + if (type != ACL_TYPE_ACCESS && type != ACL_TYPE_DEFAULT) + { + set_errno (EINVAL); + return -1; + } + cygheap_fdget cfd (fd); + if (cfd < 0) + return -1; + return cfd->acl_set (acl, type); +} + +extern "C" int +acl_set_link_np (const char *path_p, acl_type_t type, acl_t acl) +{ + return __acl_set_file (path_p, type, acl, PC_SYM_NOFOLLOW); +} + +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2001 Chris D. Faulhaber + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +extern "C" acl_t +acl_strip_np (const acl_t acl, int recalculate_mask) +{ + acl_t acl_new, acl_old; + acl_entry_t entry, entry_new; + acl_tag_t tag; + int entry_id, have_mask_entry; + + acl_old = acl_dup (acl); + if (acl_old == NULL) + return NULL; + + have_mask_entry = 0; + acl_new = acl_init (MAX_ACL_ENTRIES); + if (acl_new == NULL) + { + acl_free (acl_old); + return NULL; + } + tag = ACL_UNDEFINED_TAG; + + /* only save the default user/group/other entries */ + entry_id = ACL_FIRST_ENTRY; + while (acl_get_entry (acl_old, entry_id, &entry) == 1) + { + entry_id = ACL_NEXT_ENTRY; + + if (acl_get_tag_type (entry, &tag) == -1) + goto fail; + + switch (tag) + { + case ACL_USER_OBJ: + case ACL_GROUP_OBJ: + case ACL_OTHER: + if (acl_create_entry (&acl_new, &entry_new) == -1) + goto fail; + if (acl_copy_entry (entry_new, entry) == -1) + goto fail; + break; + case ACL_MASK: + have_mask_entry = 1; + break; + default: + break; + } + } + + if (have_mask_entry && recalculate_mask) + { + if (acl_calc_mask (&acl_new) == -1) + goto fail; + } + + return (acl_new); + +fail: + acl_free (acl_new); + acl_free (acl_old); + + return NULL; +} diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index bb5f4146dbc3..af63aa060442 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1636,18 +1636,25 @@ ISO®/IEC DIS 9945 Information technology acl_from_text (POSIX.1e draft) acl_get_entry (POSIX.1e draft) acl_get_fd (POSIX.1e draft) + acl_get_fd_np (FreeBSD, NetBSD) acl_get_file (POSIX.1e draft) acl_get_perm (POSIX.1e draft) + acl_get_link_np (FreeBSD, NetBSD) + acl_get_perm_np (FreeBSD, NetBSD) acl_get_permset (POSIX.1e draft) acl_get_qualifier (POSIX.1e draft) acl_get_tag_type (POSIX.1e draft) acl_init (POSIX.1e draft) + acl_is_trivial_np (FreeBSD, NetBSD) acl_set_fd (POSIX.1e draft) + acl_set_fd_np (FreeBSD, NetBSD) acl_set_file (POSIX.1e draft) + acl_set_link_np (FreeBSD, NetBSD) acl_set_permset (POSIX.1e draft) acl_set_qualifier (POSIX.1e draft) acl_set_tag_type (POSIX.1e draft) acl_size (POSIX.1e draft) + acl_strip_np (FreeBSD, NetBSD) acl_to_any_text (POSIX.1e draft) acl_to_text (POSIX.1e draft) acl_valid (POSIX.1e draft)
