2

I think the answer is "That's just how it works," but I figured I'd ask in case I'm doing something wrong.

My account's default umask is 0077. I'm in the wheel group.

I have a directory with this ACL:

# file: .
# owner: root
# group: wheel
# flags: -s-
user::rwx
group::rwx
other::r-x
default:user::rwx
default:group::rwx
default:group:wheel:rwx
default:mask::rwx
default:other::r-x

I create a file, and the permissions are properly set according to the above ACL.

$ touch z
$ ls -al
drwxrwsr-x+ 2 root      wheel 4,096 Aug  7 12:36 .
drwxr-xr-x. 7 root      root  4,096 Aug  6 17:31 ..
-rw-rw-r--+ 1 ehymowitz wheel     0 Aug  7 12:36 z

I now decide that this is an executable, so I change the permissions. This time, it does not follow the ACL, it follows the umask.

$ chmod +x z
$ ls -al
drwxrwsr-x+ 2 root      wheel 4,096 Aug  7 12:36 .
drwxr-xr-x. 7 root      root  4,096 Aug  6 17:31 ..
-rwxrw-r--+ 1 ehymowitz wheel     0 Aug  7 12:36 z

I need to specify a+x to make this work.

$ chmod a+x z
$ ls -al
drwxrwsr-x+ 2 root      wheel 4,096 Aug  7 12:36 .
drwxr-xr-x. 7 root      root  4,096 Aug  6 17:31 ..
-rwxrwxr-x+ 1 ehymowitz wheel     0 Aug  7 12:36 z

I guess I just don't understand why touch creates a file according to the ACL, but chmod adjusts the permissions ignoring the ACL.

hymie
  • 1,710

2 Answers2

2

Explicit feature of chmod.

man chmod

A combination of the letters ugoa controls which users' access to the file will be changed: the user who owns it (u), other users in the file's group (g), other users not in the file's group (o), or all users (a). If none of these are given, the effect is as if (a) were given, but bits that are set in the umask are not affected.


If you want to check some related ideas about ACLs, there's an answer I've found informative. It lets you see the exact details of the system calls that are setting the file permissions. (Thanks slm!)

How does umask affect ACLs?

However it's not necessarily a good introduction to how these details can be used. *nix permissions are pretty weird once you start wanting to use default ACLs (or traditional set-GID). Currently there's a limitation that the umask you would want for the most consistent behaviour is not supported on multi-user workstation OS's that use systemd (and also udisks mounts FAT filesystems with the wrong permission bits).

Default ACLs might be used on Unix fileservers for Windows workstations. I think in some cases this could involve using a hacky Samba configuration to effectively override the umask. Of course Linux can access Samba, and then you can benefit from this override hack^Wfeature. The same hack can be configured within Linux by using the FUSE filesystem "bindfs".

(That said, Linux mv between folders on the same mounted filesystem never respects different default ACLs. nautilus (GNOME Files) doesn't implement default ACLs on move either. Windows Explorer does).

sourcejedi
  • 50,249
  • 1
    chmod is ACL agnostic, but note that "Windows" uses the modern ACEs not the withdrawn ACLs and as a result, Linux and Samba do not play well together since both systems are not 100% compatible. If you like uniform "ACL" handling in UNIX and Windows, you need a ZFS based fileserver that fully supports NFSv4. – schily Aug 07 '18 at 15:30
1

You are witnessing one of the more subtleties of Unix/Linux permissions. The ACLs are being picked up when you invoke the touch command from the parent directory where the file is being created. The ACLs incorporate both the traditional permissions (modes) + the ACLs.

When you're using chmod you're manipulating just the MODE bits of the files or directories you're acting on. Keep in mind that these are discretely different and so care has to be paid when manipulating them.

Example

If you use strace you can see how chmod works. To start let's create a file, file_077:

$ rm afile_077*; umask 077; strace -s 2000 touch afile_077 > afile_077.tr 2>&1

See the results:

$ ll afile_077
-rw------- 1 user1 user1 0 Aug  7 09:32 afile_077

Change the permissions on the file to a+x:

$ strace -s 2000 chmod a+x afile_077  > afile_077_chmod.tr 2>&1

Look at the resulting log:

$ cat afile_077_chmod.tr 
...
umask(0)                                = 02
stat("afile_077", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fchmodat(AT_FDCWD, "afile_077", 0711)   = 0
...

Here we can see that chmod is interrogating the umask and then setting the MODE bits accordingly. It never looks to ACLs. NOTE: Keep in mind that this interrogation by chmod isn't that it's going to incorporate the output of umask in its operations.

slm
  • 369,824