Introduction to File Permissions
In UNIX/Linux, these permissions can be represented either symbolically (rwx) or numerically using octal numbers. The numerical representation is derived from the binary system: read is 4, write is 2, and execute is 1. By adding these numbers together, a numeric permission value can be produced for a set of permissions. For example, read and write permission would be 6 (4+2), while read and execute would be 5 (4+1).
Here's a simple table format:
Permission Type | Symbol | Octal | Description |
---|---|---|---|
Read | r | 4 | Allows the contents of a file to be read. For directories, it allows the listing of its contents. |
Write | w | 2 | Allows writing to a file or truncating it. For directories, it permits adding, removing, and renaming files in the directory. |
Execute | x | 1 | Allows executing a file (for scripts/programs). For directories, it permits accessing contents and entering the directory. |
You can also add/modify/remove special permissions such as setuid, setgid, sticky bit with chmod
You can use this table to understand the different symbolic or octal value to use with chmod
Permission Type | Octal | Syntax (Symbolic) |
---|---|---|
read+write+execute | 4+2+1=7 | rwx |
read+write | 4+2+0=6 | rw- |
read+execute | 4+0+1=5 | r-x |
read | 4+0+0=4 | r-- |
write+execute | 0+2+1=3 | -wx |
write | 0+2+0=2 | -w- |
execute | 0+0+1=1 | --x |
Differentiating File and Directory Permissions
In UNIX/Linux systems, permissions work a bit differently for files and directories. While the same symbolic (r, w, x) and octal (4, 2, 1) representations are used for both, their implications vary depending on whether they're applied to a file or a directory.
1. Files:
- Read (r / 4):
- Allows the content of the file to be read.
- Without this permission, a user cannot view the content of the file.
- Write (w / 2):
- Allows modification of the file, which includes writing new content, editing existing content, and truncating the file.
- It doesn't mean you can delete the file. File deletion is a property of the directory containing the file.
- Execute (x / 1):
- Allows the file to be executed, provided it's a script or a program.
- Without this permission, a user cannot run the file even if it's an executable script or binary.
2. Directories:
- Read (r / 4):
- Allows listing of the directory's content.
- A user with read permission can see the names of files and subdirectories within the directory.
- Write (w / 2):
- Allows modification of the directory's content, including adding new files, deleting existing files, and renaming.
- A user with write permission can modify the directory's content but may not be able to list its contents unless they also have read permission.
- Execute (x / 1):
- Allows access to the directory and its content. This is essential for directory traversal.
- Even if a user has read permission for a directory, they cannot list its contents without execute permission. Conversely, even if they have execute permission, they cannot list the directory's content without read permission.
- The execute permission on directories is sometimes referred to as the "search" permission, as it allows users to access the content of the directory when provided with a direct path.
Implications of Giving Certain Permissions to Directories:
When managing directory permissions, it's crucial to understand the broader implications:
- Write Without Execute: If a user has write but not execute permission on a directory, they can't access any of its content directly. However, if they know the name of a file inside it, they can still delete or rename it, which poses a security risk.
- Execute Without Read: A user with only execute permission on a directory can access its content if they know the exact path. However, they can't list the content of the directory itself.
- No Execute Permission: If a directory lacks execute permission for a user, that user can't access the directory or any of its subdirectories, even if they have read or write permissions.
Understanding chmod command
chmod
stands for "change mode". It's a UNIX/Linux command used to change the permissions of files and directories. Permissions determine who can read, write, or execute a file or directory. They ensure the security and proper functioning of file systems, preventing unauthorized access or unwanted modifications.
Every file and directory in your UNIX/Linux system has associated access rights, which may be found by typing ls -l
. The output will have a series of characters like -rwxr-xr--
, indicating the permissions.
Syntax:
Using Octal Notation:
chmod [numeric permissions] [file/directory name]
Using Symbolic Notation:
chmod [who][operation][permissions] [file/directory name]
IMPORTANT: Take Backup before you start
Before making broad changes, it's a good practice to save the current permissions to a file. This can be done using the stat
command in Linux:
find /path/to/directory -exec stat -c "%a %n" {} \; > permissions_backup.txt
This command will store the permission of all directories and files inside /path/to/directory so in case you mesh up the directory permission while applying chmod recursively, you can use this backup file to restore the permission.
For Example:
Here I have some temporary directory structure
# tree /tmp/dir1/ /tmp/dir1/ ├── dir2 │  ├── dir3 │  │  ├── dir4 │  │  └── file3 │  └── file2 └── file1 3 directories, 3 files
This is the current permission for entire structure:
# find /tmp/dir1 -exec stat -c "%a %n" {} \; 755 /tmp/dir1 770 /tmp/dir1/dir2 750 /tmp/dir1/dir2/dir3 755 /tmp/dir1/dir2/dir3/dir4 777 /tmp/dir1/dir2/dir3/file3 640 /tmp/dir1/dir2/file2 644 /tmp/dir1/file1
Let me take a backup of the permission state of /tmp/dir:
find /tmp/dir1 -exec stat -c "%a %n" {} \; > permissions_backup.txt
Now I recursively apply 777 permission to all files and directories inside /tmp/dir
:
chmod -R 777 /tmp/dir1/
Verify the new permission
# find /tmp/dir1 -exec stat -c "%a %n" {} \; 777 /tmp/dir1 777 /tmp/dir1/dir2 777 /tmp/dir1/dir2/dir3 777 /tmp/dir1/dir2/dir3/dir4 777 /tmp/dir1/dir2/dir3/file3 777 /tmp/dir1/dir2/file2 777 /tmp/dir1/file1
Now I want to revert to my earlier state of permission, so let's apply the permission from our backup file, here is a small shell script which reads our backup file line by line and applies the permission to respective file and directory:
#!/bin/bash
while read -r line; do
perms=$(echo "$line" | awk '{print $1}')
file=$(echo "$line" | awk '{print $2}')
chmod $perms "$file"
done < permissions_backup.txt
Execute the script:
sh restore_perm.sh
Verify the new permission is same as before executing chmod -R 777 /tmp/dir
:
# find /tmp/dir1 -exec stat -c "%a %n" {} \; 755 /tmp/dir1 770 /tmp/dir1/dir2 750 /tmp/dir1/dir2/dir3 755 /tmp/dir1/dir2/dir3/dir4 777 /tmp/dir1/dir2/dir3/file3 640 /tmp/dir1/dir2/file2 644 /tmp/dir1/file1
Examples: Applying recursive permissions using chmod
1. Change permissions for both files and directories recursively:
chmod -R 755 /path/to/directory
This sets read, write, and execute permissions for the owner and read and execute permissions for the group and others for every file and directory inside /path/to/directory
.
2. Change permissions for directories only:
find /path/to/directory -type d -exec chmod 755 {} \;
Searches inside /path/to/directory
and applies 755
permissions to all directories it finds. This means read, write, and execute permissions for the owner, with read and execute permissions for both the group and others.
3. Change permissions for files only:
find /path/to/directory -type f -exec chmod 644 {} \;
Searches inside /path/to/directory
and adjusts permissions to 644
for all files. This provides read and write permissions for the owner and read-only for the group and others. It's a common setting for web files that shouldn't be executable.
4. Remove write permissions for group and others for all items:
chmod -R go-w /path/to/directory
Recursively removes write permissions from both the group and others for every item (files and directories) inside /path/to/directory
, enhancing security by preventing unauthorized modifications.
5. Add execute permissions for the owner for all directories:
find /path/to/directory -type d -exec chmod u+x {} \;
Finds all directories inside /path/to/directory
and gives execute permissions to the owner. Execute permissions are essential for accessing or traversing through directories.
6. Remove execute permissions for all files:
find /path/to/directory -type f -exec chmod a-x {} \;
Searches for all files inside /path/to/directory
and removes execute permissions for everyone (owner, group, and others). This ensures no file becomes accidentally executable.
Bonus Tip: What is --preserve-root? Why you should use it?
- In this tutorial I will be using
--preserve-root
with all of mychmod
commands - This is a recommended option to use when you are planning to assign permission recursively as this can be destructive
- Imagine by mistake you removed all permission from
/ (root)
directory, this would lead in an unusable system - It is similar to running
rm -rf /
which if you are a Linux Administrator should know, this can destroy your server - With
--preserve-root
we inform the command not to modify root directory permission
DO NOT USE THIS COMMAND
# chmod --changes --recursive 755 /
Snippet from my terminal with this command, see the damage this command can do to your server when using without (--preserve-root).
This would recursively change the permission of all files and dir under /
which can also destroy your system
In such case it is always recommended to use
# chmod --changes --recursive --preserve-root 755 /
chmod: it is dangerous to operate recursively on '/'
chmod: use --no-preserve-root to override this failsafe
It may not be possible to use this additional option every time with chmod
so you can create an alias
# alias chmod='chmod --preserve-root'
and also add this to your /etc/bashrc
or individual user's .bashrc
file for permanent changes
Now if we use chmod
, it does not allow to modify root permission
# chmod -c --recursive 755 /
chmod: it is dangerous to operate recursively on '/'
chmod: use --no-preserve-root to override this failsafe
Conclusion
chmod
can be used with -R
or also referred as --resursive
to assign/modify permission to files and directories recursively. Although it is recommended to use --changes
and --preserve-root
along with the command to avoid any destruction.
It is possible that you may not want out STDOUT
on the screen so you can choose to reduce all messages and errors to a different file by using
# chmod --recursive --changes 755 /tmp/dir1/ >& /tmp/logfile
So this would store all the output to /tmp/logfile
which you can use for debug purpose.
Lastly I hope the steps from the article to apply chmod
recursively on Linux was helpful. So, let me know your suggestions and feedback using the comment section.
References
I have used below external references for this tutorial guide
man page for chmod