Linux File / Folder Permissions

Checking permissions

# for all files in folder
# ls -l == ll
$ ll
total 9
drwxrwxrwx 1 parikshit parikshit  160 Jul  3 08:07 ./
drwxrwxrwx 1 parikshit parikshit 8192 Jul  3 08:05 ../
-rwxrwxrwx 1 parikshit parikshit   18 Jul  3 08:07 hello-world.sh*
# for single file
$ ls -l hello-world.sh
-rwx

10 bits meaning

  • rightmost zeroth bit: d for directory and - for file
  • 1-3 bits: permissions for the current user
  • 4-6 bits: permissions for current user group
  • 7-9 bits: permissions for other users

Change permissions

you can change permissions using chmod. But remember, on external drives, it won't work.  you can specify permissions using 2 ways

Using letters

u, g, o, and a to specify user, group, other, or all respectively. let's call them action. And we have permissions like r, w, x

Syntax

chmod action(+/-/=)permissions <file or folder>

Examples

# stop execute permission for all
$ chmod a-x hello-world.sh

# change permission of all files in folder
$ chmod a+x -R my_folder

# allow read write for group
$ chmod g+rw hello-world.sh

Using numbers

You can change permissions using numbers like for the user rwx mean 7 or _wx means 3 similarly you can specify permissions

# stop execute permission for all
$ chmod 666 hello-world.sh

# change permission of all files in folder
$ chmod 777 -R my_folder

# allow read write for group
$ chmod g+rw hello-world.sh
The reason to use the number system over the letter system to set permissions is that using the numbers allows you to set the permissions to be different for user, group, and other in one issue of the chmod command and is not reliant on how the permissions are currently set. It is good practice to use -v (verbose) option of the chmod command to see what the permissions changed to since your umask may have had a role in the creation of the permissions.

Directory vs. File Permissions

UNIX is a “top-down” environment. This means that if you deny “group” or “other” permissions to a directory, all subdirectories and files within that directory will be denied the permissions established at the directory level though the settings will appear not to have changed.

The minimum permission for access to a directory is executed (x).

# remove x from current directory
$ sudo chmod a-x  ./
# try to get files
$ ll
ls: cannot open directory '.': Permission denied

Special Permissions

sticky bit (+t mode)

If the sticky bit is set on the directory then only the owner or root can delete or rename files within that directory, regardless of which users have to write access to the directory by way of group membership or ownership.

To understand this concept, we need 2 users. My virtual machine has one user parikshit, I need another one. Let's create demouser,

$ sudo useradd -r -g 1000 demouser

# -r: create a system account
# -g 1000: my group id is 1000
# I am adding demouser in same group

# switch to demouser
$ sudo su demouser

Create two directories demo1 and demo2 using your default account and give 777 permission to it. Then create a file in these directories using both users. You can do using the following commands,

# create demo directory
$ mkdir demo1 demo2

# give 777 to demo directory
$ sudo chmod 777 demo1/ demo2/

As you can see in the above image, 2 directories with 777 permissions. and each directory has one file. Now set the sticky bit for demo1

sudo chmod +t demo1/

As you can see t at last, which means "sticky bit is set and execute is allowed for others". Sometime you find T which means "sticky bit is set but execute is not allowed for others".

Now switch user to demouser using the below command and try to delete files in both directories which are owned by the user parikshit

# switch to demouser
$ sudo su demouser

# delete files in demo2
$ rm demo2/tmp1.txt

# delete files in demo1
# you will get permission denied because of sticky bit enabled
$ rm demo1/tmp1.txt

In linux, /tmp directory is best example of sticky bit.

+s mode (setuid/setgid bit)

+s bit when set on files allows users with permissions to execute a given file the ability to run that file with the permissions of the file owner. We will use touch utility to create files in the directory which is owned by demouser and no other user can create files in that directory. But we will create touch a utility that is also owned by demouser and +s bit enabled so that other user can create file in that directory.

To demonstrate +s mode, we will create a directory demo. The only owner will be allowed to write in it. Like below, I created demo whose owner is demouser:parikshit and parikshit:parikshit is not allowed to create files in demo directory.

setuid won't work with shell script because Linux ignores interpreted executables. So we will use touch. Try to create the file in demo folder using touch but it will fail.

$ touch demo/tmp.txt

# copy touch to current directory
$ cp /usr/bin/touch .

# make demouser owner of touch
$ sudo chown demouser:parikshit touch

# set setuid bit for touch
# so that when other user execute it
# it will execute as demouser
$ sudo chmod u+s touch

# now create file
$ ./touch demo/tmp.txt

Normally, files created in the directory receive ownership of the user that created the file and their default group. but files created in the +s directory receive the ownership of that directory's user and group.

References

https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts
https://unix.stackexchange.com/questions/130906/why-does-setuid-not-work