posted 2018-03-06; updated 2024-04-09
Using POSIX ACLs sucks because a lot of common tools mess with the permission bits, and ACLs change the meaning of your ancient, totally standard permission bits. I've hacked together various fixes for this in the past, and you can read these for some dumb history:
Six years of suck. The following packages are all still broken, in the sense that they fuck with the permission bits after creating files, and thus break your default ACLs:
The approach we've been using is to call the standalone apply-default-acl program on each new file, but launching a new process for every file is stupid and slow.
The magic behind apply-default-acl is now available in libadacl, the shared library that powers (and is shipped as part of) apply-default-acl. When you install apply-default-acl, the library is installed too. It has exactly one function in its public API:
#define ACL_ERROR -1
#define ACL_FAILURE 0
#define ACL_SUCCESS 1
int apply_default_acl(const char* path, bool recursive);
The two arguments are,
path
is a directory?
The function returns one of the constants,
path
.
When recursive
is true
, the
most bad result from all of the paths is returned.
#include <libadacl.h>
to the top of your C program.
apply_default_acl()
on the paths that you want to fix.
Lucky for you I have three examples prepared: new patches for coreutils, tar and p7zip.
With a recent version (0.3.1 or newer) of apply-default-acl installed, you should be able to build patched versions of these tools. If you need libadacl in your own programs, read the patches to see what they do.
user $ wget -q https://ftp.gnu.org/gnu/coreutils/coreutils-9.3.tar.xz
user $ tar -xf coreutils-9.3.tar.xz
user $ rm coreutils-9.3.tar.xz
user $ cd coreutils-9.3/
user $ wget -q https://michael.orlitzky.com/code/releases/coreutils-9.3_libadacl-0.4.4.patch
user $ patch -p1 < coreutils-9.3_libadacl-0.4.4.patch
patching file Makefile.in
patching file src/copy.c
user $ rm coreutils-9.3_libadacl-0.4.4.patch
user $ ./configure && make
user $ wget -q https://ftp.gnu.org/gnu/tar/tar-1.35.tar.xz
user $ tar -xf tar-1.35.tar.xz
user $ rm tar-1.35.tar.xz
user $ cd tar-1.35
user $ wget -q https://michael.orlitzky.com/code/releases/tar-1.35_libadacl-0.4.4.patch
user $ patch -p1 < tar-1.35_libadacl-0.4.4.patch
patching file src/Makefile.in
patching file src/common.h
patching file src/extract.c
patching file src/warning.c
user $ rm tar-1.35_libadacl-0.4.4.patch
user $ ./configure && make
user $ wget -q https://downloads.sourceforge.net/project/p7zip/p7zip/16.02/p7zip_16.02_src_all.tar.bz2
user $ tar -xf p7zip_16.02_src_all.tar.bz2
user $ rm p7zip_16.02_src_all.tar.bz2
user $ cd p7zip_16.02
user $ wget -q https://michael.orlitzky.com/code/releases/p7zip-16.02_libadacl-0.4.0.patch
user $ patch -p1 < p7zip-16.02_libadacl-0.4.0.patch
patching file CPP/Windows/FileDir.cpp
patching file makefile.linux_amd64_asm
patching file makefile.linux_x86_asm_gcc_4.X
patching file makefile.machine
user $ rm p7zip-16.02_libadacl-0.4.0.patch
user $ make
user $ mkdir 7zip-23.01
user $ cd 7zip-23.01
user $ wget -q https://downloads.sourceforge.net/sevenzip/7-Zip/23.01/7z2301-src.tar.xz
user $ tar -xf 7z2301-src.tar.xz
user $ rm 7z2301-src.tar.xz
user $ wget -q https://michael.orlitzky.com/code/releases/7zip-23.01_libadacl-0.4.4.patch
user $ patch -p1 < 7zip-23.01_libadacl-0.4.4.patch
File CPP/7zip/7zip_gcc.mak is read-only; trying to patch anyway
patching file CPP/7zip/7zip_gcc.mak
File CPP/Windows/FileDir.cpp is read-only; trying to patch anyway
patching file CPP/Windows/FileDir.cpp
user $ rm 7zip-23.01_libadacl-0.4.4.patch
user $ cd CPP/7zip/Bundles/Alone2
user $ make -f ../../cmpl_gcc.mak # or ../../cmpl_clang.mak