File Permissions and Access Control Lists
Table of contents
- Understanding File Permissions
- Changing Permissions with chmod
- Understanding Ownership with chown
- Default Permissions with umask
- Access Control Lists (ACLs)
- Viewing ACLs
- Setting ACLs
- Default ACLs for Directories
- Task: Create a directory and set specific ACL permissions for different users and groups. Verify the permissions using getfacl.
- Task: Create a script that changes the permissions of multiple files in a directory based on user input.
- Task: Write a script that sets ACL permissions for a user on a given file, based on user input.
- Advanced Permission Management: Sticky Bit, SUID, and SGID
- Backup and Restore Permissions
- Conclusion
Hey there, fellow Linux enthusiasts! Today, I’m diving into an essential topic: file permissions and ACLs. Understanding these concepts is crucial for managing your system and ensuring that your files are secure and accessible to the right people. Whether you’re a newbie or looking to brush up on your skills, I’ll break it down in a way that’s easy to grasp. Let’s get started!
Understanding File Permissions
In Linux, file permissions might seem a bit intimidating at first, but once you get the hang of it, it’s pretty straightforward.
Run ls -ltr
in your directory to get a detailed list of files and directories.
ubuntu@ip-172-31-23-226:~/day6$ ls -ltr
total 8
-rw-rw-r-- 1 user-2 testers 0 Oct 17 12:18 xyz
drwxrwxr-x 2 ubuntu developers 4096 Oct 17 12:18 pqr
-rwxr-xr-- 1 user-1 developers 48 Oct 18 17:41 abc
In this output, let’s consider the detailed list view of the file abc
:
-rwxr-xr-- 1 user-1 developers 48 Oct 18 17:41 abc
So, what does this mean? Let’s break it down
First character:
-
indicates it's a regular file.d
means it’s a directory.
Next three characters (
rwx
): These are the permissions for the user (owner):r
: Read permission (4)w
: Write permission (2)x
: Execute permission (1)
Next three characters (
r-x
): These show the permissions for the group:r
: Read permission (4)-
: No write permission (0)x
: Execute permission (1)
Last three characters (
r--
): These represent the permissions for others:r
: Read permission (4)-
: No write permission (0)-
: No execute permission (0)
In short, the first character tells you if it’s a file or a directory, while the rest indicates what different users can do with that file.
1
is the number of hard links to the file.user-1
anddevelopers
indicate the owner and group of the file.48
shows the file size in bytes.Oct 18 17:41
indicates the last modification date and time.abc
is the name of the file.
Binary Representation of Permissions
Sometimes it helps to visualize permissions in binary format, especially when dealing with numeric (octal) modes. Here’s a quick table to illustrate:
Permission | Binary | Numeric |
--- | 000 | 0 |
--x | 001 | 1 |
-w- | 010 | 2 |
-wx | 011 | 3 |
r-- | 100 | 4 |
r-x | 101 | 5 |
rw- | 110 | 6 |
rwx | 111 | 7 |
This makes it easier to see how we can combine permissions using numbers. For instance, if you see 755
, that translates to full permissions for the user, and read and execute permissions for the group and others.
Numeric (Octal) vs. Symbolic Modes
Now, let’s talk about how to change file permissions. There are two main ways to do this: numeric (octal) mode and symbolic mode.
Numeric Mode:
You can represent permissions using a three-digit number:chmod 755 fileName
This sets:
7
(rwx) for the user5
(r-x) for the group5
(r-x) for others
Symbolic Mode:
You can also specify permissions using letters (u, g, o for user, group, and others):chmod u=rwx,g=rx,o=r fileName
This gives full permissions to the user, read and execute to the group, and read-only to others.
Changing Permissions with chmod
The chmod
command is your go-to for changing file permissions. Here are some practical examples:
Grant full permissions to the user (owner):
Symbolic:
chmod u+rwx fileName
This grants full permissions (read, write, execute) to the user, but it doesn't modify the permissions of the group or others. If group and others already have permissions, they will remain unchanged.
Octal:
chmod 700 fileName
This explicitly sets full permissions for the owner, and ensures that group and others have no permissions at all.
Remove write permission for others:
Symbolic:
chmod o-w fileName
This removes write permission for others but leaves the user and group permissions unchanged.
Octal:
chmod 775 fileName
This sets full permissions for the owner and group, and read and execute for others. It explicitly defines all permissions for all categories.
Set specific permissions for all categories (read and write for the user, read-only for the group and others):
Symbolic:
chmod u=rw,g=r,o=r fileName
Octal (equivalent):
chmod 644 fileName
Advanced chmod Usage
Recursive Permission Change:
If you want to change permissions for a directory and all its contents, use:chmod -R 755 directoryName
Make a Script Executable:
Got a script that needs to run? Make it executable with:chmod +x script.sh
Understanding Ownership with chown
Every file has an owner and a group, and sometimes you need to change that ownership. Enter the chown
command:
Change the file owner:
chown newOwner fileName
Change both the owner and group:
chown newOwner:newGroup fileName
Change only the group ownership of a file:
chown :newGroup fileName
Change ownership recursively:
chown -R newOwner directoryName
Common Scenarios to use chown
Set file ownership to root:
sudo chown root fileName
Transfer file ownership to another user:
sudo chown anotherUser fileName
Default Permissions with umask
What is umask
?
The umask
command sets the default permissions for new files and directories. When you create a file or directory, Linux starts with a "base" set of permissions and then subtracts the umask
value from it to decide the final permissions.
Base permissions for directories:
777
(read, write, execute for everyone).Base permissions for files:
666
(read, write for everyone, files usually don't have execute permission by default).
How umask
Works
The umask
value subtracts permissions from these base settings. It's like saying, "These are the permissions I don't want."
For example:
- A
umask
of022
subtracts write permissions for the group and others.
Understanding with an Example
1. Default Directory Permissions
The base permission for directories is 777
(meaning everyone can read, write, and execute):
Base: 777 (rwxrwxrwx)
Umask: 022 (--w--w--)
Result: 755 (rwxr-xr-x)
So, when you set umask
to 022
, new directories will have 755
permissions:
The owner can read, write, and execute.
The group and others can only read and execute (no write permission).
2. Default File Permissions
The base permission for files is 666
(meaning everyone can read and write):
Base: 666 (rw-rw-rw-)
Umask: 022 (--w--w--)
Result: 644 (rw-r--r--)
When you create a new file with a umask
of 022
, it will have 644
permissions:
The owner can read and write.
The group and others can only read (no write permission).
Viewing and Setting umask
Check the current
umask
value:umask
Set a new
umask
value:umask 022
This tells Linux to subtract 022
from the base permissions when creating new files or directories, so they are created with more restrictive access.
Access Control Lists (ACLs)
As powerful as standard permissions are, sometimes they aren’t flexible enough for more complex scenarios, like assigning different permissions to multiple users on the same file. That's where Access Control Lists (ACLs) come into play.
ACLs allow you to set detailed permissions for specific users or groups beyond the traditional owner/group/others structure.
Viewing ACLs
To see the current ACLs on a file or directory, you can use the getfacl
command:
getfacl filename
This will display the current permissions, including any ACLs that have been set.
Setting ACLs
To assign ACLs, you’ll use the setfacl
command. For example, if you want to give a specific user (let’s say "user3") read permission on a file, you can run:
setfacl -m u:user3:r filename
-m
: Modify the ACL.u:user3:r
: Assigns read permission to user3.
You can also set ACLs for groups:
setfacl -m g:group1:rw filename
This command gives group1 read and write access to the file.
Example usage (setting ACLs for the file ‘abc’):
ubuntu@ip-172-31-23-226:~/day6$ sudo setfacl -m u:user-3:r abc
ubuntu@ip-172-31-23-226:~/day6$ sudo setfacl -m g:testers:rw abc
ubuntu@ip-172-31-23-226:~/day6$ getfacl abc
# file: abc
# owner: user-1
# group: developers
user::rwx
user:user-3:r--
group::r-x
group:testers:rw-
mask::rwx
other::r--
Default ACLs for Directories
ACLs can also be applied to directories, and you can specify default ACLs, which will be inherited by any files created within the directory:
setfacl -d -m u:user3:rw directoryname
The -d
flag sets a default ACL. Any new files created in the directory will automatically inherit these permissions.
Task: Create a directory and set specific ACL permissions for different users and groups. Verify the permissions using getfacl.
Steps Involved:
Create a Directory: Create a new directory where ACL permissions will be set.
Set ACL Permissions: Assign different permissions to multiple users and groups using the
setfacl
command.Verify ACL Permissions: Use the
getfacl
command to check and verify the assigned ACL permissions.
Let’s get started!
1. Create a Directory
First, let's create a directory named project_directory
.
mkdir project_directory
2. Set Specific ACL Permissions for Different Users and Groups
Now, we'll assign different ACL permissions for two users (alice
and bob
) and a group (developers
).
Assign read and execute permissions to the user
alice
.Assign read, write, and execute permissions to the user
bob
.Assign read-only permissions to the group
developers
.
Commands to Set ACL Permissions:
# Give 'alice' read and execute permissions
setfacl -m u:alice:rx project_directory
# Give 'bob' full read, write, and execute permissions
setfacl -m u:bob:rwx project_directory
# Give the group 'developers' read-only permissions
setfacl -m g:developers:r project_directory
3. Verify the Permissions Using getfacl
To confirm that the permissions have been applied correctly, use the getfacl
command:
getfacl project_directory
This command will display the ACLs for the directory. The output should show the default and additional ACLs for the specified users and group.
Sample Output of getfacl
:
ubuntu@ip-172-31-23-226:~/day6$ getfacl project_directory
# file: project_directory
# owner: ubuntu
# group: ubuntu
user::rwx
user:alice:r-x
user:bob:rwx
group::rwx
group:developers:r--
mask::rwx
other::r-x
user::rwx
: The owner has full permissions (read, write, execute).user:alice:r-x
: Useralice
has read and execute permissions.user:bob:rwx
: Userbob
has full permissions (read, write, execute).group::rwx
: Group has full permissions (read, write, execute).group:developers:r--
: The groupdevelopers
has read-only permission.other::r-x
: Other users have read and execute permissions.
In this task, we created a directory and set ACL permissions for different users (alice
and bob
) and a group (developers
). We assigned different levels of access, including read-only, read and execute, and full permissions. Finally, we verified the ACL settings using the getfacl
command. This approach provides detailed control over access to the directory, extending the traditional permission system in Linux.
Task: Create a script that changes the permissions of multiple files in a directory based on user input.
When managing a directory with multiple files, you might want to change the permissions for all files in that directory. This can be automated by writing a shell script that takes user input and applies the permission changes accordingly.
The script will:
Prompt the user for the directory path.
Ask for the permissions in numeric format (e.g., 755, 644).
Apply those permissions to all files in the directory.
The Script
#!/bin/bash
# Ask the user for the directory path
read -p "Enter the directory path: " dir_path
# Check if the directory exists
if [ ! -d "$dir_path" ]; then
echo "The directory $dir_path does not exist."
exit 1
fi
# Ask the user for the desired permissions in numeric format
read -p "Enter the permissions you want to set (e.g., 755, 644): " permissions
# Validate the permissions input (must be a 3- or 4-digit number)
if [[ ! $permissions =~ ^[0-7]{3,4}$ ]]; then
echo "Invalid permission format. Please enter a valid 3- or 4-digit permission number."
exit 1
fi
# Apply the permissions to all files in the directory
for file in "$dir_path"/*; do
if [ -f "$file" ]; then
sudo chmod "$permissions" "$file"
echo "Changed permissions of $file to $permissions"
fi
done
echo "Permissions updated for all files in $dir_path."
How It Works:
User Input: The script first prompts the user for the directory path and the desired permissions.
Validation: It checks whether the directory exists and whether the permissions input is valid (using a regular expression that matches numeric values like
755
or0644
).Permission Change: If the input is valid, the script uses a
for
loop to apply the permissions to each file in the directory using thechmod
command.Output: The script prints a confirmation message for each file whose permissions are changed.
Usage Example:
$ ./change_permissions.sh
Enter the directory path: /home/user/docs
Enter the permissions you want to set (e.g., 755, 644): 644
Changed permissions of /home/user/docs/file1.txt to 644
Changed permissions of /home/user/docs/file2.txt to 644
Permissions updated for all files in /home/user/docs.
Task: Write a script that sets ACL permissions for a user on a given file, based on user input.
The script will:
Prompt the user for the file path.
Ask for the username for whom to set the ACL permissions.
Prompt for the permissions (read, write, execute).
Apply the ACL permissions using the
setfacl
command.
The Script
#!/bin/bash
# Prompt the user for the file path
read -p "Enter the file path: " file_path
# Check if the file exists
if [ ! -f "$file_path" ]; then
echo "The file $file_path does not exist."
exit 1
fi
# Prompt for the username
read -p "Enter the username to set ACL for: " username
# Check if the user exists in the system
if ! id "$username" &>/dev/null; then
echo "The user $username does not exist."
exit 1
fi
# Prompt for the permissions (read, write, execute)
read -p "Enter the permissions you want to set (r, w, x or a combination, e.g., rwx): " permissions
# Validate the permissions input
if [[ ! $permissions =~ ^[rwx-]+$ ]]; then
echo "Invalid permissions. Please enter a combination of r, w, and x."
exit 1
fi
# Apply the ACL permissions using setfacl
setfacl -m u:"$username":"$permissions" "$file_path"
# Check if the ACL command was successful
if [ $? -eq 0 ]; then
echo "ACL permissions set successfully for user $username on file $file_path."
else
echo "Failed to set ACL permissions."
fi
# Display the ACL permissions for the file
getfacl "$file_path"
How It Works:
User Input: The script prompts for the file path, username, and permissions (read, write, execute) for setting ACL.
Validation: It checks whether the file and user exist, and validates the permissions input to ensure it only includes valid characters (
r
,w
,x
).Set ACL Permissions: The script uses the
setfacl
command to apply the specified permissions for the user on the given file.Output: It confirms the success of the operation and displays the ACL permissions for the file using the
getfacl
command.
Usage Example:
$ ./set_acl_permissions.sh
Enter the file path: /home/user/docs/file1.txt
Enter the username to set ACL for: john
Enter the permissions you want to set (r, w, x or a combination, e.g., rwx): rw
ACL permissions set successfully for user john on file /home/user/docs/file1.txt.
# file: home/user/docs/file1.txt
# owner: user
# group: user
user::rw-
user:john:rw-
group::r--
mask::rw-
other::r--
In this example:
The script sets read and write (
rw
) permissions for the userjohn
on the file/home/user/docs/file1.txt
.After setting the ACL, the updated permissions are displayed.
Advanced Permission Management: Sticky Bit, SUID, and SGID
While file permissions and ACLs give you a lot of control, sometimes you need even more granular permissions for specific use cases. Enter the Sticky Bit, Setuid (SUID), and Setgid (SGID).
Sticky Bit
The sticky bit is most commonly used on shared directories (like /tmp
), where multiple users can create files. It ensures that only the file owner can delete or modify their files, even if other users have write access to the directory.
To set the sticky bit on a directory:
chmod +t directoryname
You can verify the sticky bit is set by running ls -l
. The output will show a t
in the final position of the permissions string, like this:
drwxrwxrwt
SUID (Set User ID)
When the SUID bit is set on an executable file, any user who runs that file will have the file owner’s privileges during execution. This is commonly used for commands like passwd
, which needs root privileges but can be run by any user.
To set the SUID bit:
chmod u+s filename
You’ll see an s
in the user permission field if SUID is set:
-rwsr-xr-x
SGID (Set Group ID)
The SGID bit can be set on files and directories. On files, it works similarly to SUID, but with group privileges. On directories, it ensures that new files created within the directory inherit the group ownership of the directory rather than the creating user's primary group.
To set SGID:
chmod g+s directoryname
You’ll see an s
in the group permission field if SGID is set:
drwxr-sr-x
Backup and Restore Permissions
Managing permissions across multiple files can be tricky, especially when you need to maintain consistency across a directory structure. That’s why it’s useful to be able to back up and restore file permissions.
Backing Up Permissions
To create a backup of the current permissions, you can use the getfacl
command to save them to a file:
getfacl -R directoryname > permissions_backup.txt
This will recursively save all ACLs and regular permissions for files within the specified directory.
Let’s write a script to backup permissions using this command:
#!/bin/bash
# Backup permissions (including ACLs) for a specified directory
# Check if directory argument is provided
if [ $# -ne 1 ]; then
echo "The script should be executed like this: $0 <directory>"
exit 1
fi
DIR=$1
BACKUP_FILE="permissions_backup.txt"
# Backup permissions
getfacl -R "$DIR" > "$BACKUP_FILE"
if [ $? -eq 0 ]; then
echo "Backup successful: Permissions saved to $BACKUP_FILE"
else
echo "Error: Failed to backup permissions."
fi
Sample Output for Backup:
$ ./backup_permissions_acl.sh /mydir
Backup successful: Permissions saved to permissions_backup.txt
Restoring Permissions
Once you’ve backed up your permissions, restoring them is simple with setfacl
. Use the following command to apply the saved permissions:
setfacl --restore=permissions_backup.txt
This ensures that all your file and directory permissions are restored to their previous state.
Let’ write a script to restore permissions using this command:
#!/bin/bash
# Restore permissions (including ACLs) from a backup file
# Check if backup file argument is provided
if [ $# -ne 1 ]; then
echo "The script should be executed like this: $0 <backup-file>"
exit 1
fi
BACKUP_FILE=$1
# Restore permissions
setfacl --restore="$BACKUP_FILE"
if [ $? -eq 0 ]; then
echo "Restore successful: Permissions restored from $BACKUP_FILE"
else
echo "Error: Failed to restore permissions."
fi
Sample Output for Restore:
$ ./restore_permissions_acl.sh permissions_backup.txt
Restore successful: Permissions restored from permissions_backup.txt
Conclusion
File permissions, ownership, and ACLs form the backbone of security in Linux. By mastering these concepts, along with special permissions like the sticky bit, SUID, and SGID, you can gain fine-grained control over your system. Plus, the ability to back up and restore permissions ensures you can easily maintain a secure, well-organized environment. Keep experimenting, and you’ll soon be managing your Linux system like a pro!
Subscribe to my newsletter
Read articles from Spoorti Shetty directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by