Linux File System Permissions

You are currently viewing Linux File System Permissions

Please note down the following points before moving onwards with the tutorial:

  1. Word "File" down below implies both "Regular File and Directory". If I don’t mean to include "Directory", I’ll be specific about it by using the term "Regular File".
  2. Prompt used in examples below may either be superuser root prompt "#" or regular user prompt "$". It may be required differently in your case depending upon the privileges needed to execute a command, so choose accordingly.

Each file on linux file system (when not considering ACLs) is owned by a single user and a single group. Therefore, access to them is defined based on whether the user is owner, group owner (or group member) or neither (i.e. other). Therefore, permissions applicable depends upon the category, a user lies in:

  1. (u)ser Permissions are applicable when user is the owner of the file.
  2. (g)roup Permissions are applicable when user is the member of the group to which file belongs to.
  3. (o)ther Permissions are applicable when user is neither the owner of the file nor the member of the group to which file belongs to.

Note: Always the most specific permissions are applicable, i.e.
user permissions OVERRIDE group permissions and group permissions OVERRIDE other permissions.

For example, say a user is both the owner and group owner (belongs to the group to which file belongs to) of the file, than in such case the most specific permissions i.e. user permissions will be applicable or given priority. So always remember the following precedence:
User Permissions > Group Permissions > Other Permissions

As discussed earlier within post "User and Group Management", that groups (specifically supplementary groups) exists mainly to facilitate sharing of files between multiple users. By ensuring proper group permissions we can allow multiple users to have access to the common set of files. Same is depicted using the diagram below: groupPerms
In diagram above, user saurabh belongs to the primary group saurabh and supplementary group wheel and webdev, whereas user prateek belongs to the primary group prateek and supplementary group webdev and dbTeam. Both the users belong to the common group webdev and therefore, their access to files and directories belonging to the group webdev will be restricted via group permissions webdev.

Above we categorized permissions applicable depending upon whether a user is owner of the file, group owner of the file or neither i.e. other category. Now, Permissions, itself, can be categorized into three types: (r)ead, (w)rite, and e(x)ecute. With these 3 permissions, we get a total of 8 possibilities for each category: user, group and other.

One important point to note before moving ahead is that, Linux File System Permissions won’t make much sense when it comes to Superuser "root", because of obvious reason that root has all the privileges/power on a system. A regular user may choose to deny root user, permission to access files owned by him, but then again that is preposterous and meaningless.

Similary, judging permissions on a given file w.r.t. to the very owner of that file don’t make much sense, because an owner has complete authority to do what so ever with the files or directories owned by him and can always bypass/change the set user (or owner) permissions.

Therefore, whenever in doubt, judge the effects discussed below w.r.t. group (or group owner) and other permissions and not the user (or owner).

Permissions Effects on Directory
– – – No operations allowed.
r – – Only names of directory contents can be listed.
– w – Only empty directory can be deleted.
– – x Can go inside the directory.
Access to directory contents allowed depending upon their permissions.
r w – Only names of directory contents can be listed.
Only empty directory can be deleted.
r – x Names and metadata of directory and contents can be listed, i.e. long listing ls -l is allowed.
Can go inside the directory
Access to directory contents allowed depending upon their permissions.
– w x Creation and deletion of files and directories within directory is allowed.
Editing/ modification (both content & metadata) is allowed.
Note: A file can be removed by anyone who has write permission to the directory in which the file resides, regardless of the ownership or permissions on the file itself. This unwanted behavior can be overridden with a special permission, the sticky bit discussed later on.
r w x Everything is allowed here.
Permissions Effects on Regular File
– – – No operations allowed.
r – – Reading/Viewing file is allowed only.
– w – Modifying file is allowed only. For Example: $echo "# Appending this line" >> FILEPATH
Editing (or selective editing) can’t be done without viewing file.
– – x No operation allowed.
Execution can’t be done without reading file.
r w – Viewing and Editing file is allowed.
r – x Reading and Executing file is allowed.
– w x Modifying file is allowed only. See example shown above.
Editing (or selective editing) can’t be done without viewing file.
Execution can’t be done without reading file.
r w x Everything is allowed here.

Listing File Permissions and Ownership

metadatInfo

To list permission and ownership information, simply use ls in long listing format with option "-l". For listing directory metadata, "-d" switch is appended with "-l" switch, where "-d" is used to list directories themselves, not their contents.

Permission and ownership information is contained within Metadata which get listed with ls -l/ls -ld. Metadata includes information formatted in 11 fields shown below, in that exact order (i.e. Left to Right):

  1. File Type: Character "-" for regular file, "d" for directory, "c" for character file, "b" for block device file, "s" for socket file, "p" for named pipe/FIFO file and "l" for symbolic link is displayed). In image shown above, first character shows "d" i.e. listed file is directory.
  2. User Permissions: Permissions applicable to user/owner of the file. In image shown above, "r – x" is the permission set for the owner (root) of the directory.
  3. Group Permissions: Permissions applicable to members of the group to which file belongs to. In image shown above, "r w x" is the permission set for the group (webdev) members, to which directory belongs to.
  4. Other Permissions: Permissions applicable to users other than owner and members of the group to which file belongs to. In image shown above, "- – -" (i.e. no permission) permission is set for other users.
  5. ACL State: Character "." if ACLs are absent and "+" if ACLs are present. In image shown above "." implies ACL is not present.
  6. Hardlink Count (in case of file): Number of hardlinks of file.
    Sub-Directory Count (in case of directory): Hardlink field displays the number of sub-directories. In Linux, each directory always has two sub-directories:
    "." A pointer, pointing to the directory itself
    ".." Another pointer, pointing to the parent directory
    Therfore, Hardlink field value will always be N+2, where N is the number of sub-directories other than "." and ".." In image shown above, sub-directory count is "2", which implies no more sub-directory other than the default pointer ones "." and ".."
  7. User Ownership: Name of the user to which file belongs to. In image shown above, owner of the directory is "root".
  8. Group Ownership: Name of the group to which file belongs to. In image shown above, group ownership or the group to which directory belongs to is "webdev".
  9. File Size: Size of the file in bytes. In image shown above, directory size is "112 bytes".
  10. Timestamp: Last "Modify" Time. There are four types of timestamps: Access Time, Modify Time, Change Time and Birth Time. Use stat command view them all. In image shown above, last modify time displayed is "Jun 17 17:05".
  11. File Name: Name of the file. In image shown above, directory name is "webFiles".

Note: With context to Linux File System Permissions, only field 1st, 2nd, 3rd, 4th, 5th, 7th, 8th and 11th are relavant.

Few examples to consider:

$ ls -l /etc/chrony.keys
Displays metadata of file "chrony.keys".
chrony_keys
File Type: Regular File
User Permission: r w –
Group Permission: r – –
Other Permission: – – –
ACL State: . i.e. Absent
User/Owner of File: root
Group Owner of File: chrony
File Name: chrony.keys

$ ls -ld /var/spool/cups
Displays metadata of directory "cups".
cups
File Type: Directory
User Permission: r w x
Group Permission: – – x
Other Permission: – – –
ACL State: . i.e. Absent
User/Owner of File: root
Group Owner of File: lp
File Name: cups

Changing file permissions

chmod command is used to change permissions set on files and directories. chmod stands for Change Mode (Permission is also called Mode of a file). chmod command employs two methods for changing permissions:

  1. Symbolic Method
  2. Numeric Method

chmod

Symbolic Method

Following is the syntax for changing permission using symbolic method of chmod command:
$ chmod WhoWhatWhich file, where

  • Who is u, g, o, a for user, group, other and all respectively. Here u, g, o and a represents the different groups of permissions: u for user, g for group, o for other and a for all.
  • What is +, -, = for add, remove and set exactly respectively. Here symbol + implies adding permission to a set, symbol – implies removing permission from a set and symbol = is meant to replace the entire set for a group of permission.
  • Which is r, w, x for read, write and execute permission respectively.

Numeric Method

Following is the syntax for changing permission using numeric method of chmod command:
$ chmod ### file, where

  1. Each # character symbolizes a digit.
  2. From left to write, first digit represents user permissions, second digit represents group permissions and third digit represents other permissions.
  3. Each digit is summation of integer 4, 2, 1 and 0, where:
    4 means read
    2 means write
    1 means execute
    0 means nothing.
    Each digit is in octal form with base 8, having values within range 0-7. Therefore, for "each digit" we have a total of "8 possibilities" shown below in binary, octal/decimal and equivalent symbolic form.
Binary Format Octal/Decimal Format Equivalent Symbolic Format
000 0 – – –
001 1 – – x
010 2 – w –
011 3 – w x
100 4 r – –
101 5 r – x
110 6 r w –
111 7 r w x

For more details refer to man page: chmod(1)

Examples:

$ chmod u=rwx,g=rx,o= /opt/vbox (OR)
$ chmod 750 /opt/vbox
Give read, write, execute permission to owner of the directory /opt/vbox, read and execute permission to group members and no permission to other users.

$ chmod u+x /home/sanketkrsingh/monitor.sh
Add execute permission to the existing set of permissions of user/owner of the file /home/sanketkrsingh/monitor.sh.

$ chmod go-rw /home/student/dataFile.db
Remove read and write permission from the existing set of permissions of group members and other users for /home/student/dataFile.db file.

Note: There is no equivalent Numeric Method for above two examples, because like in the case of Symbolic Method, there is no way to add or remove permission from the existing set of permissions in Numeric Method. In Numeric Method, permissions are set exactly and directly as required, which is equivalent to using "=" symbol in Symbolic Method.

$ chmod a+x /home/saurabh/.bashrc
Add execute permission for everyone on file .bashrc

# chmod 644 /etc/passwd (OR)
# chmod u=rw,go=r /etc/passwd (OR)
# chmod u=rw,g=r,o=r /etc/passwd
Give read and write permission to owner of the file /etc/passwd, read permission to group members and read permission to all the other users. This also makes the /etc/passwd file world readable.

$ chmod -R g+rwX /webFiles
The above command recursively set read and write access to directory webFiles and all its children for their group owner, but will only apply execute permission to directories and not regular files.
Note: The chmod command supports -R option for recursively setting permissions on an entire directory tree. While using this option, make sure to use uppercase "X" permission instead of lowercase "x" permission to indicate that execute permission should only be applied on directories and not regular files.

Changing file user and group ownership

The nature of the Linux File System is such, that a user who creates the file, owns the file. It means, user ownership of a newly created file, by default, goes to the user who created the file plus the group ownership goes to the user’s private (or primary) group.

Now, since in Linux based systems (like RHEL, Ubuntu etc.) a user private group is often a group with only one user as a member, to grant access based on user or group membership, the owner or the group owner of a file may need to be changed.

Note: Only superuser root can change the user ownership of a file. Group ownership, however can be set either by root or by the owner (or user owner) of the file.

chown is the most preferred command, because it can be used to change both user ownership and group ownership, set on a file. Other than it, one may choose to use similar commands like chgrp and newgrp, but keep in mind that, they can only be used to make changes to group ownership. Both chown and chgrp commands works similarly and can also be used with -R option for recursively applying permission across directory tree.

newgrp command is used in a similar fashion as su command. It is used to change the current group ID (or user’s private group) during a login session. If the optional - flag is given, the user’s environment will be reinitialized as though the user had logged in, otherwise the current environment, including current working directory, remains unchanged.

The syntax for chown command is:
# chown [-R] USERNAME:GROUPNAME FILENAME(s) : For changing both user and group ownership
# chown [-R] USERNAME FILENAME(s) : For changing user ownership only
# chown [-R] :GROUPNAME FILENAME(s) : For changing group ownership only

The syntax for chgrp command is:
# chgrp [-R] GROUPNAME FILENAME(s)

The syntax for newgrp command is:
$ newgrp - GROUPNAME (Recommended) (OR)
$ newgrp GROUPNAME
where GROUPNAME is any valid primary or supplementary group user belongs to.

For more details refer to man pages: chown(1), chgrp(1) and newgrp(1).

Examples:

# chown student:student /tmp/fooFile.txt
Grant user and group ownership of file /tmp/fooFile.txt to user student and user’s primary group student respectively.

# chown saurabh /webFiles/saurabh.py
Grant user ownership of python file /webFiles/saurabh.py to user saurabh.

# chown :prateek /webFiles/saurabh.py (OR)
# chgrp prateek /webFiles/saurabh.py
Grant group ownership of python file /webFiles/saurabh.py to user prateek’s primary group prateek.

# chown -R :webdev /webFiles (OR)
# chgrp -R webdev /webFies
Grant group ownership of directory webFiles and all its children (files and sub-directories within it) to group webdev.

# chown -R prateek:dbTeam /dbFiles
Grant user and group ownership of directory dbFiles and all its children to user prateek and group dbTeam respectively.

Understanding Special Permissions

Apart from the three basic premissions (r)ead, (w)rite and e(x)ecute, there are three more Special Permissions: (s)etuid or (s)uid bit, (s)etgid or (s)gid bit and s(t)icky bit in Linux File Systems. Following table explains the behavior of these special permission bits on files.

Special Permission Bit Effect on Executable File (Binary or Regular) Effect on Directory Effect on Non-Executable File (Binary or Regular)
(s)uid (OR) (s)etuid bit File will always run with the privileges of the owner of the file, when executed by any user having execute permission on the file. No Effect No Effect
(s)gid (OR) (s)etgid bit File will always run with the privileges of the group owner of the file, when executed by any user having execute permission on the file. Files newly created in the directory (after setting up the setgid bit) have their group owner set to match the group owner of the directory. No Effect
s(t)icky bit No Effect Users with (w)rite permission on the directory can only remove files that they own; they cannot remove or force saves to files owned by other users. No Effect

Setting up special permission bit

setuid/suid bit is always set on user (or owner), setgid/sgid bit is always set on group owner and sticky bit is always set on others. chmod command is used for setting up the suid, sgid and sticky bit in following manner:

Special Permission Bit Symbolic Method Numeric Method
setuid or suid bit $ chmod u+s FILEPATH/FILENAME $ chmod 4### FILEPATH/FILENAME
setgid or sgid bit $ chmod g+s FILEPATH/FILENAME $ chmod 2### FILEPATH/FILENAME
sticky bit $ chmod o+t FILEPATH/FILENAME $ chmod 1### FILEPATH/FILENAME

Examples:

# chmod g+s /dbFiles
Set the sgid bit on directory "dbFiles"

# chmod 2750 /webFiles
Set the sgid bit, read write execute permission for owner, read execute permission for group owner (or group members) and nothing for other users.

# chmod o+t /webFiles
Set the sticky bit on directory "webFiles"

Understanding Default File Permissions

You may have noticed, that whenever a new file is created, it is created with some default set of permissions i.e. it has permissions set for user owner, group owner and other users. Usually on Linux systems, by default:

A newly created regular file has A newly created directory has
rw set for user owner rwx set for user owner
rw (or r) for group owner rwx (or rx) for group owner
r for others rx for others

Did you ever wondered, where does these initial set of permissions comes from?

These default permissions on files are set by the process which creates them. For Example:
Note: The permissions below are w.r.t. creator or user owner of the file.

  1. A text file when created using command like touch or text editors (like vim, nano, emacs), or by shell redirection method, by default has read, write permission, but no execute permission.
  2. A binary file when generated by a compiler, by default has read, write and execute permission.
  3. A new directory when created using mkdir command, usually by default has all read, write and execute permission.

These initial set of permissions are set based on the umask (or User Mask) value of the process creating the files. Every process on the system has a umask, which is an octal bitmask that is used to clear the permissions of new files that are created by the process. If a bit is set in the umask, then the corresponding permission is cleared in new files. Lets understand this further with the example of shell’s umask. Shell is a process which allows us to execute multiple commands to perform various tasks on the system. Being a process, shell also carries a user mask value which can be displayed using the command umask. As evident form the image below, on RHEL and based distributions: umask01

  1. Shell’s umask value is 0022 by default, when logged in via superuser root account.
  2. Shell’s umask value is 0002 by default, when logged in via regular user account.

Note: The shell’s different umask values depending upon the type of user logged in, is controlled via global shell configuration files. Following is the code snippet from files /etc/profile and /etc/bashrc defining the shell’s umask value depending upon the type of user logged in:

if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
       umask 002
    else
       umask 022
    fi

Working Principle of umask

Lets consider the umask set to 0022. The leading 0 (first digit from left) indicates entire number is in octal format and next three digits indicates the permission bit to be cleared from user owner permission, group owner permission and other permission respectively.

  • While creating a new directory, the default permissions will be evaluated as following:
    All Permission – umask Permission Bit = Default Permission for Directories
    Therefore, for a newly created directory we have 0755 as default permission:
    For User owner permission: 7 – 0 = 7
    For Group owner permission: 7 – 2 = 5
    For Other permission: 7 – 2 = 5

  • For safety purpose, the newly created regular files are not given execute permission by default. Therefore clearing the execute bit further, will give the default permissions for regular files i.e.:
    All Permission – umask Permission Bit – Execute Bit = Default Permission for Regular Files
    Therefore, for a newly created regular file we have 0644 as default permission:
    For User owner permission: 7 – 0 – 1 = 6
    For Group owner permission: 7 – 2 – 1 = 4
    For Other permission: 7 – 2 – 1 = 4

So, if a bit is set in umask, the corresponding permission bit is cleared or removed in new files.

Changing umask

  • System wide (global) default umask values for Bash Shell users are defined in file /etc/profile and /etc/bashrc. The code snippet is shared above. Making changes here will effect every user on the system.

  • Users may choose to add or modify default umask values in local Bash shell configuration files ~/.profile and ~/.bashrc within their home directories. Just add umask followed by numeric argument in one of the files. umask values defined here will override the umask values defined within global Bash shell initialization files.

  • For changing umask of current working shell, use umask command with single numeric argument:
    # umask 0027 (OR)
    $ umask 0007

Leave a Reply