File (and directory) permissions in Linux and Unix-based systems define what the owner, the group, and others can or cannot do with a file or directory.
Run the following command in any directory that contains files or directories (the stat command can provide even more detail):
ls -l
The output might look something like this:
-rw-r--r-- 1 owner owner 310 Oct 31 16:32 fileName drwxr-xr-x 2 owner group 4096 Apr 26 2021 directoryName
Each line starts with a series of 10 consecutive characters.
All characters except the first can be:
- r
- Read access
- w
- Write access
- x
- Execute access
- –
- No access
They are grouped as:
- -uuu——
- Privileges of the user that owns the file
- —-ggg—
- Privileges of the group that owns the file
- ——-ooo
- Privileges of any other user
Example:
- -rwx–xr–
- The owner can read, write, and execute
- The group can only execute
- Others can only read
The first character indicates the file type and can only be:
- –
- Regular file
- b
- Block special file
- c
- Character special file
- d
- Directory
- l
- Symbolic link
- p
- FIFO
- s
- Socket
- w
- Whiteout
The file type cannot be changed, but it is important to know how to identify directories and symbolic links. All the other types are for special use cases.
Another way to represent file permissions is with a 3-digit number, where each digit is the sum of:
- 4 = Read
- 2 = Write
- 1 = Execute
Combined, the possible values are:
- 0 = No access
- 3 = Write + Execute
- 5 = Read + Execute
- 6 = Read + Write
- 7 = Read + Write + Execute
Example:
- 750
- The owner can read, write, and execute.
- The group can read and execute.
- Others have no access.
Use the chmod command to change file permissions:
- chmod +x fileName
- Grant execute access to the owner, group, and others.
- chmod -w fileName
- Remove write access from the owner, group, and others.
- chmod g=r fileName
- Set the group to read-only, removing any other access it had.
- chmod o+x -R fileName
- Grant execute access to others recursively, preserving any existing access.
Tip: use -v for more verbose output.
Attributes define what can be done with a file, not who can do it.
List the attributes of a file or directory with:
lsattr
A series of 22 characters (----------------------) shows all the attributes for each item in the current directory.
The seven most important attributes are:
- A
- Do not update the access timestamp (
atime).
- Do not update the access timestamp (
- S
- Changes are written synchronously to disk.
- a
- The file can only be appended to, not modified.
- i
- The file becomes immutable and cannot be modified.
- j
- Changes are written to the ext3 journal before being applied to the file.
- t
- Disable tail-merging.
- u
- When the file is deleted, its data is saved, allowing undeletion.
Use the chattr command to change attributes:
- sudo chattr +a fileName
- Enable the append-only attribute.
- sudo chattr -i -R fileName
- Disable the immutable attribute recursively.
- sudo chattr =ua fileName
- Enable only the listed attributes, disabling all others.
SUID (Set-user Identification) & SGID (Set-group Identification)
When either of these flags is set on an executable file, the file runs with the privileges of its owner rather than the user executing it. For example, if a regular user runs a script owned by root that has SUID set, it will execute with root privileges.
- 2000
- SGID is set.
- 4000
- SUID is set.
- 6000
- SGID + SUID are both set.
In the ls -l output, an s replaces x to indicate these flags:
- —s——
- SUID is set.
- ——s—
- SGID is set.
Set SUID:
chmod u+s fileName
Unset SGID:
chmod g-s fileName
STICKY BIT
The sticky bit is primarily used on shared directories. It allows users to create files, and read or execute files owned by others, but prevents them from deleting files they do not own.
- 1000
- Sticky bit is set.
- ———t
- The x for others is replaced by t when the sticky bit is set.
Set the sticky bit on a directory (or file):
chmod +t fileName
BONUS
For security reasons, it is highly recommended to identify and unset SUID and SGID on files, as they can easily be abused.
Search by numeric permission:
find / -perm /2000 find / -perm /4000 find / -user root -perm /6000
Or by symbolic permission:
find / -perm /g+s find / -perm /u+s find / -user root -perm /u+s,g+s
To find and unset in one go:
for i in `find / -perm +2000` do chmod g-s $i done