What you request is not supported by Linux's ACLs.
setfacl -m u:jim:r-X
(capital X
) gives Jim permission to read all files including directories, and to execute only directories and files that are executable by their owner.
Making directories non-readable has very limited usefulness. If you tell us what you're trying to accomplish, we might be able to offer a better solution.
The permissions set by the default ACL are masked with whatever the mode is that the program creating the file gives. Usually, a program creating a regular file sets the permissions to 0666
(that is, no execute bits), and lets the umask
handle removing access from group and others. For directories the mode is usually set to 0777
so that the x-bits are there, since they are often needed.
A program creating a "private" file, like SSH keys, would specify the permissions as 0600
, to make sure no-one but the user themselves have access.
The manual acl(5)
says that:
OBJECT CREATION AND DEFAULT ACLs
- The access ACL entries corresponding to the file permission bits are modified so that they contain no permissions that are not contained in the permissions specified by the mode parameter.
So, since the ACL u::
corresponds to the usual permission bits for the file's user, the permissions are masked by what the creating program gives.
(In a sense, the default ACL seems to take the place of the umask.) I suspect if you create a directory, you'll see that it does get the x
-bit as you wanted.
Technically that doesn't affect ACL entries for a specific user, as in u:foo:rwx
, but those are limited by the ACL mask. The mask has a correspondence with the traditional group permission bits, and it seems the rule quoted above applies also to the mask, such that the ACL mask is limited by the group permission bits set when the file is created.
Let's try:
$ mkdir dir ; chmod 750 dir ; setfacl -d -m u::rx -m g::rx -m u:foo:rwx dir
$ touch dir/file ; mkdir dir/subdir
The created file has the x-bits masked (getfacl
here shows both the bits set and what the effective values are after applying the mask):
$ getfacl dir/file
user::r--
user:foo:rwx #effective:rw-
group::r-x #effective:r--
mask::rw-
other::---
But the directory doesn't:
$ getfacl dir/subdir/
user::r-x
user:foo:rwx
group::r-x
mask::rwx
...
That might answer (1) and (3). As for (2): IIRC, the setgid-bit (g+s
) on a directory makes new files created inside it inherit the group of the directory (not the mode). The sticky bit (+t
) controls deleting files not owned by you, and actually I have no idea what the setuid-bit (u+s
) would do on a directory.
Best Answer
Linux/Solaris ACLs don't support this. You can't set different default ACLs for files and directories.
Having directories that can be traversed but whose content cannot be listed (executable but not readable) is rarely useful. The fact that is works at all is a bit of a historical accident. Yes, it can occasionally be useful — but do you really need it? (You may want to ask this as a separate question.)
If you really need directories and files with different permissions, here are a few possibilities you can consider:
Make everything private by default (
setfacl -d -m group:mygroup:X
) and use one of the suggestions in Group+rx permission only in directories using ACL?:setfacl
on new regular files.