There are three categories of file permissions for any given file: owner, group, and everyone else. Some of the more common file ownership commands are chown, chmod and chgrp.
chown is used to change the ownership of a file. It can be used as follows:
chown user:group path/to/file_or_directory # Change owner and groupchown user: path/to/file_or_directory # Change owner and group to have same _user_
chgrp on the other hand is used to modify just the group of a file:
chgrp group path/tp/file
The primary use of this is to change the group ownership of a file without modifying who owns it.
chmod is used to adjust file permissions more generally. It does not set user or group ownership, but defines how a user or group (or everyone else) can access the file. The command supports two types of notation: symbolic notation (u+x) or octal notation (755).
The general syntax of chmod is chmod [who] [operator] [permission] <file>, where:
[who]
[operator]
[permission]
u (user/owner)
+ (add)
r (read)
g (group)
- (remove)
w (write)
o (others)
= (set)
x (execute)
a (all)
Example
To give the owner for the script.sh file permission to execute, we might do:
chmod u+x script.sh
To set different permissions for group and owner, we can do:
chmod --recursive g+wx,o+x script.sh
Octal notation for chmod works in the same way, except all three permissions are set at once using three digit numbers. The digits represent user/owner, group, and others respectively. Each of the digits is the sum of the permission values, which are:
Permission
Value
Read
4
Write
2
Execute
1
Example
To allow the owner of a file to read/write/execute, allow group to just read/write, and everyone else to just read:
chmod 764 script.sh
Where the first 7 refers to the owner (4 + 2 + 1), while the 6 refers to the group (4 + 2), and 4 refers to every one else (4). Permissions would then show up as:
-rwxrw-r-- 1 owner group script.sh
File attributes
File attributes are an extended set of control that go beyond standard file permissions. The primary commands are lsattr and chattr to list and change the attributes respectively.
lsattr is useful to check whether protections like immutability1 or append-only are active on a file. The general flag options are -R (recurse), -a (all, including hidden files), -d (show dir attributes instead of contents).
The output of lsattr might look something like this:
Some different options in the output are (the man chattr for more):
Letter
Attributes
Description
a
append-only
File can only be opened in append mode for writing
i
immutable
File cnanot be modified, deleted, or renamed
s
secure delection
When deleted, the kernel will overwrite its data blocks with 0
u
undeletable
The file cannot be deleted (but can be modified)
A
no atime update
The file’s access time doesn’t update when the file is read
c
compressed
The file is automatically compressed when written to disk
e
uses extents
Indicates that the file is using extents for mapping the blocks on disk
Note
An extent is a method to track where data lives on a disk used by modern filesystems. Rather than keeping track of individual blocks (especially when the files are fragmented), extents uses single records that describe the size and extent of a block.2
Whereas lsattr is used to list the attributes of a file, chattr is used to change or set them. The way it works is by using plus/minus signs to set or remove attributes. For instance, if we want to make a file immutable:
Special permissions are used to temporarily grant users extra access under certain conditions. These are controlled by three primary concerns: setuid, setgit, and sticky bit.
setuid allows a program to run with the privileges of the file’s owner, rather than those of the user actually running the file. This is commonly used to allow regular users to run files that require elevated privileges. To setuid, use the command chmod u+s <file>.3
Example
To allow a file to always run as root, regardless of who created the file or who is running it:
Likewise, we can use setgid to allow a file to run with the permissions of the group. chmod g+s <file>. This is a far more common and useful thing done these days:
sudo groupadd projectsudo usermod -aG project alicesudo usermod -aG project bobsudo mkdir /srv/sharedsudo chown root:project /srv/sharedsudo chmod 2775 /srv/shared # the 2 here is the setgid bit-> ls /srv/shareddrwxrwsr-x root project /srv/shared
This means that whenever alice or bob create files in /srv/shared the group ownership of those files will be project, rather than the users themselves:
alice$touch file1-rw-r--r-- alice project file1bob$touch file2-rw-r--r-- bob project file2
For comparison, if we had not used setgid, file creation would look like this:
-rw-r--r-- alice alice file1-rw-r--r-- bob bob file2
This would require regular chgrp calls to ensure everyone can access the files.
Note
When multiple people have write access to a directory we can set chmod +t <directory> to enforce a sticky bit. This is a special permission used to prevent deletion or renaming of files not owned. Setting this up means that different users can write to a directory, but can only delete their own files.
umask
umask us the user creation mask. It is used to set the default permissions for newly created files and directories in Linux.
It works by subtracting the defined permission bits (default of 022) from a set of starting bits. That is to say, new files are often created with default permissions of 666, while directories with 777.
When a user creates a new file, then, the permissions assigned to that file will be 666 - 022 for a resulting permission set of 644 (meaning the user creating the file can read/write, everyone else can only read).4
Common umask values are:
umask
File permissions (666 & ~umask)
Dir permissions (777 & ~umask)
Meaning
000
666 → rw-rw-rw-
777 → rwxrwxrwx
No restrictions: everyone can read/write (and execute dirs). Generally unsafe.
022
644 → rw-r--r--
755 → rwxr-xr-x
Owner full access; group/others read-only (files) or read/execute (dirs). Default on many distros.
027
640 → rw-r-----
750 → rwxr-x---
Owner full access; group read-only; no access for others.
077
600 → rw-------
700 → rwx------
Owner full access; group/others have no permissions. Very restrictive.
002
664 → rw-rw-r--
775 → rwxrwxr-x
Owner/group full access; others read-only. Useful for shared group projects.
umask values can be set with both octal and symbolic notation:
# Change the mask symbolically to allow read permission for all users (the rest of the mask bits are unchanged): umask a+r# Set the mask (using octal) to restrict no permissions for the file's owner, and restrict all permissions for everyone else: umask 077
umask is a per-user setting. To make it persistent, add it to your shell startup files (e.g. .bashrc, .bash_profile, or system-wide /etc/profile).
Footnotes
Immutable files are those that cannot be modified, deleted, renamed, or have their contents name. In the context of Linux attributes, it means that these properties cannot be bypassed even by the root user. ↩
Note that some filesystems, like btrfs, will not show the e attribute in the output of lsattr. This is because chattr/lsattr were primarily written for extX filesystems. Additionally, in btrfsall files are extent-based already. ↩
Although this sounds great in theory, the Linux kernel does not honor setuid on interpreted scripts. This is because when running a script, such as a bash script, the kernel is invoking /bin/bash or what have you, which creates a security liability. ↩
The mechanism is not a literal subtraction. It is a bitwise mask that turns off the corresponding permission bits. ↩