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
.