Understanding file permissions

file permissions control who can access a file, and when.

who can access them is controlled by /etc/passwd and /etc/groups, the permissions structure holds three fields; owner, group (as specified by stat), and everyone.

below is a table explaining the numerical representations.

Binary Octal/Decimal Meaning
001 1 Executable
010 2 Writable
100 4 Readable

by adding these base values, we can get the following remaining options.

Binary Octal/Decimal Meaning
000 0
011 3 Writable and Executable
101 5 Readable and Executable
110 6 Readable and Writable
111 7 Readable, Writable, and Executable

by invoking chmod 735 file, we're letting;

you've also probably seen an ascii representation (or "symbolic notation") for all of these bits when using ls or stat. it looks like this;

$ stat test
  File: test
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 812h/2066d      Inode: 3010549     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1337/    dcat)   Gid: (    0/    root)
Access: 2018-10-11 16:07:08.333135491 +0200
Modify: 2018-10-11 16:07:08.333135491 +0200
Change: 2018-10-11 16:07:08.333135491 +0200
 Birth: -

as seen above, the permissions of this file is 0644 or in ascii -rw-r--r--.

a good way to visualize this is by converting 644 to binary, but as individual digits, and then compare it with the ascii line.

first let's make a shell function for printing binary numbers.

dec2bin() {
    for i in $@
    do
        echo "obase=2; $i" | bc
    done
}

now we can use the function to get the binary representation of 0644.

$ a=0 b=6 c=6 d=4
$ dec2bin $a $b $c $d
0
110
110
100

now we can compare that to the more user-friendly string we have.

$ # we use `tr` to strip away anything that isn't a digit/number
$ # then we print out the string using `printf` to add newlines
$ dec2bin $a $b $c $d | tr -cd '[:digit:]' ; printf '\n-rw-r--r--\n'
0110100100
-rw-r--r--

as we can see, each individual bit coresponds with its ascii representation.

there's also a modes, typically SUID, SGID, and sticky bit.

these are represented by the first character in the ascii string, somewhat poorly represented as it is not a single bit.

the purpose of SUID, and SGID (Set {User,Group} ID) is to allow an executable to execute the syscall setuid() in order to change the owner or group of the process.

examples of this would be doas, sudo, su, &c.


see also; file permissions, file system permissions, chmod(2), chmod(1).