return 0;
}
+#endif
+
+static int fd_acl_make_read_only_fallback(int fd) {
+ struct stat st;
+
+ assert(fd >= 0);
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ if ((st.st_mode & 0222) == 0)
+ return 0;
+
+ if (fchmod(fd, st.st_mode & 0555) < 0)
+ return -errno;
+
+ return 1;
+}
int fd_acl_make_read_only(int fd) {
+ assert(fd >= 0);
+
+#if HAVE_ACL
_cleanup_(acl_freep) acl_t acl = NULL;
bool changed = false;
acl_entry_t i;
int r;
- assert(fd >= 0);
-
/* Safely drops all W bits from all relevant ACL entries of the file, without changing entries which
* are masked by the ACL mask */
maybe_fallback:
if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
return r;
+#endif
/* No ACLs? Then just update the regular mode_t */
return fd_acl_make_read_only_fallback(fd);
}
+static int fd_acl_make_writable_fallback(int fd) {
+ struct stat st;
+
+ assert(fd >= 0);
+
+ if (fstat(fd, &st) < 0)
+ return -errno;
+
+ if ((st.st_mode & 0200) != 0) /* already set */
+ return 0;
+
+ if (fchmod(fd, (st.st_mode & 07777) | 0200) < 0)
+ return -errno;
+
+ return 1;
+}
+
int fd_acl_make_writable(int fd) {
+ assert(fd >= 0);
+
+#if HAVE_ACL
_cleanup_(acl_freep) acl_t acl = NULL;
acl_entry_t i;
int r;
r = dlopen_libacl();
if (r < 0)
- return r;
+ goto maybe_fallback;
acl = sym_acl_get_fd(fd);
if (!acl) {
- if (!ERRNO_IS_NOT_SUPPORTED(errno))
- return -errno;
-
- /* No ACLs? Then just update the regular mode_t */
- return fd_acl_make_writable_fallback(fd);
+ r = -errno;
+ goto maybe_fallback;
}
for (r = sym_acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
return -errno;
if (sym_acl_set_fd(fd, acl) < 0) {
- if (!ERRNO_IS_NOT_SUPPORTED(errno))
- return -errno;
-
- return fd_acl_make_writable_fallback(fd);
+ r = -errno;
+ goto maybe_fallback;
}
return 1;
-}
-#endif
-
-int fd_acl_make_read_only_fallback(int fd) {
- struct stat st;
-
- assert(fd >= 0);
-
- if (fstat(fd, &st) < 0)
- return -errno;
-
- if ((st.st_mode & 0222) == 0)
- return 0;
-
- if (fchmod(fd, st.st_mode & 0555) < 0)
- return -errno;
-
- return 1;
-}
-
-int fd_acl_make_writable_fallback(int fd) {
- struct stat st;
-
- assert(fd >= 0);
-
- if (fstat(fd, &st) < 0)
- return -errno;
- if ((st.st_mode & 0200) != 0) /* already set */
- return 0;
-
- if (fchmod(fd, (st.st_mode & 07777) | 0200) < 0)
- return -errno;
+maybe_fallback:
+ if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
+ return r;
+#endif
- return 1;
+ /* No ACLs? Then just update the regular mode_t */
+ return fd_acl_make_writable_fallback(fd);
}
int inode_type_can_acl(mode_t mode) {
#include "shared-forward.h"
-int fd_acl_make_read_only_fallback(int fd);
-int fd_acl_make_writable_fallback(int fd);
-
#if HAVE_ACL
#include <acl/libacl.h> /* IWYU pragma: export */
#include <sys/acl.h> /* IWYU pragma: export */
int acls_for_file(const char *path, acl_type_t type, acl_t acl, acl_t *ret);
int fd_add_uid_acl_permission(int fd, uid_t uid, unsigned mask);
-int fd_acl_make_read_only(int fd);
-int fd_acl_make_writable(int fd);
-
/* acl_free() takes multiple argument types. Multiple cleanup functions are necessary. */
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(acl_t, sym_acl_free, acl_freep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(char*, sym_acl_free, acl_free_charpp, NULL);
static inline int fd_add_uid_acl_permission(int fd, uid_t uid, unsigned mask) {
return -EOPNOTSUPP;
}
-
-static inline int fd_acl_make_read_only(int fd) {
- return fd_acl_make_read_only_fallback(fd);
-}
-
-static inline int fd_acl_make_writable(int fd) {
- return fd_acl_make_writable_fallback(fd);
-}
#endif
+int fd_acl_make_read_only(int fd);
+int fd_acl_make_writable(int fd);
+
int inode_type_can_acl(mode_t mode);