i A Refresher on Unix Permissions · Dark Matter Industries

A Refresher on Unix Permissions

I had to deal with some extended attributes recently while using rsync to create back ups of some blobs on one of my macOS machines, when it occured to me how much the original Unix (POSIX) file permission regime has been extended. Certainly on macOS this is now a thing of beauty (or frustration, depending on what you are trying to achieve!).

Since I had to relearn some parts of the system, how about I share it with you in a concise format?

Here’s what we see with a long directory listing:

% ls -l
total 2624
drwxr-xr-x@  62 baryon  staff     1984 13 Jun  2018 2013 Consol/
drwx------@  24 baryon  staff      768 17 Dec 07:32 Databases/
drwxr-xr-x   13 baryon  staff      416  2 Aug 23:57 MathJax/
drwx------+   7 baryon  staff      224 20 Dec 11:22 Music/
drwx------@   4 baryon  staff      128  5 Sep  2018 OmniPresence/
-rw-r--r--    1 baryon  staff       21 23 May  2020 PS1.zshrc
drwxr-xr-x+   5 baryon  staff      160  3 Jun  2020 Public/
drwxr-xr-x   27 baryon  wheel      864 22 Dec 16:38 anaconda3/
-rwxr-xr-x    1 baryon  staff      172 25 Nov  2019 find_color.sh*
drwxr-xr-x   21 baryon  staff      672 22 Dec 18:36 google-cloud-sdk/
-rw-r--r--    1 baryon  staff        0 25 Jan  2020 mvphotos.sh
drwxr-xr-x    3 baryon  staff       96  4 Jun  2020 repos/
drwx------    5 baryon  staff      160  6 Jul 20:46 sent/
drwxr-xr-x   22 baryon  staff      704  6 Jul 23:26 shell_logs/
-rw-r--r--@   1 baryon  staff     3128 27 May  2020 th18_2.csv
...truncated...

The first bit in the permissions block is a general descriptor:

- = normal file
d = default permissions applied to this directory
c = character device file
b = block device file

then it is:

drwxr-xr-x
 |_||_||_|
 usr gp other

there is an additional bit at the end with a + or @ sign.

+ = Access Control Lists is applied to the object
@ = object has extended attributes enabled

Also note that the “staff” group in macOS is equivalent to “All Users” on Windows.

POSIX Access Control Lists (ACL)

The base Unix (originating from POSIX) permission system is not very flexible, especially in the modern context. This is solved by the POSIX ACL. This table show how much more granularity you can have with ACL:

ACL ACL Usage POSIX equivalent
Owner user::rwx Owner
Additional Specific User user:baryon:rwx Not applicable
Default Group group::rwx Group
Additional Specific Group group:engineers:rwx Not applicable
Other Users other::rwx Other
Default Mask mask::rwx Not applicable

POSIX only allows users of your one specified group access, or you will have to open it up to “other”, which essentially is giving access to everyone on the system. With ACL you can specify other groups or users to have read, write and/or execute access to your files, ad infinitum.

“Default Mask” refers to the maximum permissions for this object regardless what is written in (what you see when you perform ls -a). For instance if the user has rwx but the mask is rw-, the permission is rw-.

On macOS, to access the ACL, use:

% ls -le
-rw-r--r--    1 baryon  staff        0 29 Dec 12:11 ACL_test.txt
drwx------@   4 baryon  staff      128  5 Sep  2018 OmniPresence/
-rw-r--r--    1 baryon  staff       21 23 May  2020 PS1.zshrc
drwx------+   5 baryon  staff      160 20 Dec 11:50 Pictures/
 0: group:everyone deny delete
drwxr-xr-x+   5 baryon  staff      160  3 Jun  2020 Public/
 0: group:everyone deny delete

To change ACL permissions, for example, to the first file above:

% chmod +a 'majortom allow read,write,delete' ACL_test.txt 

% ls -le
-rw-r--r--    1 baryon  staff        0 29 Dec 12:11 ACL_test.txt
0: user: majortom allow read,write,delete

This can also be viewed and changed with the “get info” tool in Finder on macOS:

Click on the + to add majortom in this case.

Interestingly there is another bit that is set by default for removable media, the “ignore ownership of this volume”. This is required because otherwise the ownership and group UUIDs may not match after mounting on another system.

On Linux, you need the acl suite which is likely not part of the main distro and you’ll have to install separately (see this nice article by Benjamin Cane).

Octal Values

There are 3 permission groups (user, group and others) and each permission group is represented by 3 bits : rwx for instance is 111 in binary. -w- is 010.

The binary can be converted to Octal:

binary - octal
000    - 0
100    - 4
010    - 2
001    - 1

For combinations we just add the octals:

binary - octal
110    - 6  (100 + 010 = 4+2 = 6)   // hence octal 6 represents rw-

You can use the stat (“status”) utility to find the octal permission value. On macOS:

% stat -f %A quarks.db
644        // which represents rw-r--r--

On linux the syntax is slightly different:

$ stat --format "%a" quarks.db
644

Hence to change the permissions of a file:

% chmod 600 myfile
-rw------- 1 majortom staff 12 Dec 20 12:12 quarks.db

We can also use the human readable format:

% chmod ugo+x quarks.db  // add execute permissions to (u)ser,(g)roup,(o)ther
-rwx--x--x 1 majortom staff 12 Dec 20 12:12 quarks.db

The umask

When creating a file, Unix uses a default mask to create default permissions. The mask is the number you subtract from 777 (for directories) and 666 (for files) to create the permissions. You can find out what the umask is for your system via:

% umask
022

Here the default mask is 022 hence default file permissions will be 644 or rwx-r—r—.

You can change the mask with:

% umask 077

Extended Attributes in OSX/Mac OS X/macOS

A file or directory with an “@“ at the end of its permission bits indicates that it has extended attributes. Extended attributes are metadata that can contain all sorts information on the file from quarantine information to origin data etc. It is like EXIF for JPEGs.

We can view extended attributes thus:

% xattr quarks.db
com.apple.lastuseddate#PS
com.apple.quarantine

% xattr Image\ from\ iOS.jpg 
com.apple.macl
com.apple.metadata:kMDItemWhereFroms
com.apple.metadata:kMDLabel_ivepqw6wbtgyubkhqjyajjhzza
com.apple.quarantine

You can delete extended attributes with the -d flag:

% xattr -d com.apple.quarantine quarks.db

The extended attributes listed above are just the labels (or keys of a key-value pair). If you want to see the “values” of the attributes, use the -l (list) flag:

% xattr -l unifying1.10.421.dmg 
com.apple.lastuseddate#PS:
00000000  4D BC FF 5D 00 00 00 00 CA B7 BB 2D 00 00 00 00  |M..].......-....|
00000010
com.apple.macl:
00000000  01 00 BA A5 0A 5B B6 22 41 C5 99 9F AB CC 7F E3  |.....[."A.......|
00000010  42 BE 02 00 63 82 3C 06 3C B6 43 2A 9C 16 99 63  |B...c.<.<.C*...c|
00000020  A8 C4 11 51 00 00 00 00 00 00 00 00 00 00 00 00  |...Q............|
00000030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000040  00 00 00 00 00 00 00 00                          |........|
00000048
com.apple.metadata:kMDItemDownloadedDate:
00000000  62 70 6C 69 73 74 30 30 A1 01 33 41 C1 D7 F9 E6  |bplist00..3A....|
00000010  E0 73 EF 08 0A 00 00 00 00 00 00 01 01 00 00 00  |.s..............|
00000020  00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 13                                   |.....|
00000035
com.apple.metadata:kMDItemWhereFroms:
00000000  62 70 6C 69 73 74 30 30 A1 01 5F 10 54 68 74 74  |bplist00.._.Thtt|
00000010  70 73 3A 2F 2F 64 6F 77 6E 6C 6F 61 64 30 31 2E  |ps://download01.|
00000020  6C 6F 67 69 2E 63 6F 6D 2F 77 65 62 2F 66 74 70  |logi.com/web/ftp|
00000030  2F 70 75 62 2F 63 6F 6E 74 72 6F 6C 64 65 76 69  |/pub/controldevi|
00000040  63 65 73 2F 75 6E 69 66 79 69 6E 67 2F 75 6E 69  |ces/unifying/uni|
00000050  66 79 69 6E 67 31 2E 31 30 2E 34 32 31 2E 64 6D  |fying1.10.421.dm|
00000060  67 08 0A 00 00 00 00 00 00 01 01 00 00 00 00 00  |g...............|
00000070  00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
00000080  00 00 61                                         |..a|
00000083
com.apple.quarantine: 0083;5dffbc4d;Safari;4C69C726-526D-49F2-8945-BE80745B3DC7

Here we can see the source of this downloaded file in the attribute kMDItemWhereFroms.