shell, permissions

Musa OyizaMusa Oyiza
18 min read

prerequisites

  • Allowed editors: vi, vim, emacs

  • All your scripts will be tested on Ubuntu 20.04 LTS

  • All your scripts should be exactly two lines long ($ wc -l file should print 2)

  • All your files should end with a new line (why?)

  • The first line of all your files should be exactly #!/bin/bash

  • A README.md file, at the root of the folder of the project, describing what each script is doing

  • You are not allowed to use backticks, &&, || or ;

  • All your files must be executable

overview

This project is a continuation of the previous tutorials on shell navigation and file management, aimed at helping beginners learn the fundamentals of the Linux shell and its commands

In tutorial one, we started with an introduction to the shell and its basic navigation commands. We learned how to navigate the file system using commands such as ls, cd, and pwd. We also learned how to create and remove files and directories using commands like mkdir, touch, and rm. Additionally, we covered how to view file contents using cat, less, and head commands.

In this tutorial, which happened to be tutorial two, we went deeper into file manipulation and management. We learned how to manage file permissions using the chmod command, how to change ownership of files and directories using the chown and chgrp commands. We also covered how to run commands with elevated privileges using sudo and su.

our next tutorial will be three, where we will continue with advanced topics such as Shell, I/O Redirections and filters

introduction

In a Unix-based operating system, shell permissions refer to the access control mechanism that governs who can perform what operations on a file or directory. Shell permissions are essential for ensuring system security and protecting sensitive data from unauthorized access.

Linux file permissions

Linux file permissions refer to the access control mechanism that governs who can perform what operations on a file or directory in a Linux operating system. This mechanism is used to ensure system security and protect sensitive data from unauthorized access.

In Linux, three types of permissions can be assigned to files and directories::

  1. Read (r): This permission grants the user the ability to view or read the contents of a file or directory. In the case of a directory, the user can see the names of the files contained within.

  2. Write (w): This permission grants the user the ability to modify the contents of a file or directory. In the case of a directory, the user can create, delete, and modify files within the directory.

  3. Execute (x): This permission grants the user the ability to execute a file or access the contents of a directory. In the case of a file, this means running the file as a program or script. In the case of a directory, this means accessing files within the directory.

These permissions are assigned to three categories of users:

  1. User: This refers to the owner of the file or directory. The user has the most control over the file or directory and can set permissions for other users.

  2. Group: This refers to a group of users who have been granted permission to the file or directory. Group permissions are useful for allowing multiple users to collaborate on a project while still maintaining security.

  3. Other: This refers to all other users who are not the owner or part of the group. These users have the least amount of access to the file or directory.

In Linux, file permissions are represented by a 10-character string, with the first character indicating the file type (e.g., "d" for directory, "-" for a regular file), and the next three characters indicating the permissions for the owner, the next three for the group, and the last three for others.

For example, if a file has the permissions "-rw-r--r--", this means that the owner has read and write permissions, the group has read permissions, and others have read permissions only.

To modify file permissions in Linux, you can use the chmod command in the terminal. The command takes two arguments: the first is a string of numbers that represents the new permissions, and the second is the name of the file or directory whose permissions you want to modify.

As a DevOps engineer, understanding shell permissions is essential for managing system security and access control. You may need to modify permissions for specific files or directories to allow certain users to perform necessary tasks while still maintaining security. It is important to be careful when modifying permissions to ensure that sensitive data is not exposed to unauthorized users.

Permissions:

What do the commands chmod, sudo, su, chown, chgrp do

  1. chmod: This command stands for "change mode" and is used to modify the permissions of a file or directory. It allows the user to add or remove the read, write, and execute permissions for the owner, group, and others. The syntax for chmod is chmod [options] mode file.

  2. sudo: This command stands for "superuser do" and is used to execute commands with elevated privileges. It is often used when a user needs to perform an action that requires administrative access. The syntax for sudo is sudo [command].

  3. su: This command stands for "switch user" and is used to switch to a different user account. It requires the user to enter the password of the account they want to switch to. It is often used to perform tasks that require administrative privileges. The syntax for su is su [username].

  4. chown: This command stands for "change owner" and is used to change the owner of a file or directory. It allows the user to transfer ownership to a different user or group. The syntax for chown is chown [options] new_owner file.

  5. chgrp: This command stands for "change group" and is used to change the group of a file or directory. It allows the user to transfer the file or directory to a different group. The syntax for chgrp is chgrp [options] new_group file.

It's worth noting that these commands are commonly used in Unix-based systems like Linux and macOS. They offer powerful tools for managing file permissions and system access, but they should be used with care as they can have significant consequences if used incorrectly.

Here are some examples of how each command can be used with code:

  1. chmod example:

To add the read and write permissions for the owner and group, and the read permission for others to a file named example.txt, you can use the following command:

chmod 664 example.txt

In Python, you can use the os module to modify the file permissions programmatically. Here's an example that achieves the same result as the command above:

import os

filename = 'example.txt'
os.chmod(filename, 0o664)

Note that the permissions are represented in octal notation in Python, so 664 is equivalent to 0o664 (octal 664).

  1. sudo example:

To install a package using apt-get as the root user, you can use the following command with sudo:

sudo apt-get install <package-name>

In a Python script, you can execute a command with sudo by using the subprocess module. Here's an example that installs the nginx package using apt-get:

import subprocess

subprocess.run(['sudo', 'apt-get', 'install', 'nginx'])
  1. su example:

To switch to the root user account, you can use the following command with su:

su -

In Python, you can switch to a different user account by using the os module to set the effective user ID. Here's an example that switches to the root user:

import os

os.seteuid(0)  # set the effective user ID to 0 (root)

Note that this requires the script to be run with elevated privileges.

  1. chown example:

To change the owner of a file named example.txt to the user john, you can use the following command:

chown john example.txt

In Python, you can change the owner of a file using the os module. Here's an example that changes the owner of example.txt to john:

import os

filename = 'example.txt'
uid = pwd.getpwnam('john').pw_uid  # get the UID of the user 'john'
os.chown(filename, uid, -1)  # change the owner to UID 'john'

Note that this requires the script to be run with elevated privileges.

  1. chgrp example:

To change the group of a file named example.txt to the group developers, you can use the following command:

chgrp developers example.txt

In Python, you can change the group of a file using the os module. Here's an example that changes the group of example.txt to developers:

import os

filename = 'example.txt'
gid = grp.getgrnam('developers').gr_gid  # get the GID of the group 'developers'
os.chown(filename, -1, gid)  # change the group to GID 'developers'

Note that this requires the script to be run with elevated privileges.

How to represent each of the three sets of permissions (owner, group, and other) as a single digit

In Unix-based systems, permissions for a file or directory are divided into three sets: owner, group, and other. Each set has three permissions: read (r), write (w), and execute (x).

To represent each set of permissions as a single digit, we can use the following convention:

  • The read permission is represented by the digit 4.

  • The write permission is represented by the digit 2.

  • The execute permission is represented by the digit 1.

  • If a permission is not granted, it is represented by the digit 0.

To calculate the digit for each set of permissions, we can add the digits corresponding to the granted permissions. For example, if the owner has read and write permissions, the digit for the owner set would be 4+2=6.

Here's an example code snippet in Python that calculates the digit for each set of permissions for a file:

import os

filename = 'example.txt'
st = os.stat(filename)

# calculate owner permissions digit
owner_perm = 0
if st.st_mode & 0o400:
    owner_perm += 4
if st.st_mode & 0o200:
    owner_perm += 2
if st.st_mode & 0o100:
    owner_perm += 1

# calculate group permissions digit
group_perm = 0
if st.st_mode & 0o40:
    group_perm += 4
if st.st_mode & 0o20:
    group_perm += 2
if st.st_mode & 0o10:
    group_perm += 1

# calculate other permissions digit
other_perm = 0
if st.st_mode & 0o4:
    other_perm += 4
if st.st_mode & 0o2:
    other_perm += 2
if st.st_mode & 0o1:
    other_perm += 1

print(f"Permissions for {filename}:")
print(f"Owner: {owner_perm}")
print(f"Group: {group_perm}")
print(f"Other: {other_perm}")

In this example, we use the os.stat() function to get information about the file, including its permissions. We then use bitwise operators to check whether each permission is granted and add up the corresponding digits to get the final digit for each set. Finally, we print the digits for each set.

How to change permissions, owner and group of a file

To change the permissions, owner, and group of a file in Unix-based systems like Linux and macOS, you can use the chmod, chown, and chgrp commands, respectively. You can also achieve the same result programmatically using the os module in Python.

Here's an example of how to change the permissions, owner, and group of a file named example.txt using the chmod, chown, and chgrp commands in the terminal:

# Change the permissions to read and write for the owner and group, and read-only for others
chmod 664 example.txt

# Change the owner to the user 'john'
chown john example.txt

# Change the group to the group 'developers'
chgrp developers example.txt

Here's an example of how to achieve the same result programmatically using Python:

import os
import pwd  # import the pwd module to get user information
import grp  # import the grp module to get group information

# Set the file path
filename = 'example.txt'

# Set the desired permissions
permissions = 0o664  # read and write for owner and group, read-only for others

# Set the desired owner and group
owner = 'john'
group = 'developers'

# Get the UID and GID of the owner and group
uid = pwd.getpwnam(owner).pw_uid
gid = grp.getgrnam(group).gr_gid

# Set the permissions, owner, and group of the file
os.chmod(filename, permissions)
os.chown(filename, uid, gid)
os.chgrp(filename, gid)

Note that changing the permissions, owner, or group of a file may require elevated privileges, so you may need to run the script with sudo or as the root user. Also, be careful when changing the permissions of a file, as giving too many permissions can potentially compromise the security of your system.

Why can’t a normal user chown a file

In Unix-based systems like Linux and macOS, only the superuser (i.e., the root user) has the permission to change the ownership of a file using the chown command. This is a security feature designed to prevent unauthorized users from taking ownership of files that they do not have permission to modify.

When a normal user tries to change the ownership of a file using the chown command, they will receive a "Operation not permitted" error. Here's an example of how this would look like in the terminal:

$ chown john example.txt
chown: changing ownership of 'example.txt': Operation not permitted

However, a normal user can change the ownership of a file that they own to another user that they have the permission to modify. For example, if a user named alice owns a file named example.txt, they can change the ownership of the file to another user named bob that belongs to the same group as alice using the chown command like this:

$ chown bob: example.txt

In Python, you can use the os.chown() function to change the ownership of a file, but you need to run the script as the superuser (i.e., using sudo or running the script as the root user) to avoid the "Operation not permitted" error. Here's an example:

import os

# Set the file path
filename = 'example.txt'

# Set the desired owner and group
owner = 'john'
group = 'developers'

# Get the UID and GID of the owner and group
uid = pwd.getpwnam(owner).pw_uid
gid = grp.getgrnam(group).gr_gid

# Set the owner and group of the file
os.chown(filename, uid, gid)  # This may require elevated privileges

Note that running a script with elevated privileges should be done with caution, as it can potentially compromise the security of your system.How to run a command with root privileges ilusterate with coding

In Unix-based systems like Linux and macOS, you can run a command with root privileges using the sudo command. The sudo command allows you to temporarily elevate your privileges to that of the root user, allowing you to execute commands that require elevated privileges.

To run a command with root privileges using sudo, simply prefix the command with sudo in the terminal. For example, to install a package using the apt-get package manager with root privileges, you can run the following command:

$ sudo apt-get install package_name

You will be prompted to enter your password to authenticate the command.

In Python, you can run a command with root privileges using the subprocess module. You can use the subprocess.run() function to run a command with sudo as follows:

import subprocess

# Set the command to run with root privileges
command = ['apt-get', 'install', 'package_name']

# Run the command with sudo
result = subprocess.run(['sudo'] + command, capture_output=True, text=True)

# Print the result
print(result.stdout)

In this example, the subprocess.run() function is used to run the apt-get install package_name command with sudo. The capture_output=True the parameter is used to capture the output of the command, and the text=True parameter is used to convert the output to a string. The output of the command is then printed to the console using print(result.stdout). Note that running a command with sudo should be done with caution, as it can potentially compromise the security of your system.

How to change user ID or become superuser

In Unix-based systems like Linux and macOS, you can change the user ID or become the superuser (i.e., root user) using the su command. The su command allows you to switch to another user account or become the superuser, provided that you have the necessary permissions.

To become the superuser using su, open a terminal and type the following command:

$ su

You will be prompted to enter the password for the superuser. Once you enter the correct password, you will become the superuser and will be able to execute commands that require elevated privileges.

To switch to another user account using su, open a terminal and type the following command, replacing username with the name of the user account that you want to switch to:

$ su username

You will be prompted to enter the password for the user account that you want to switch to. Once you enter the correct password, you will switch to that user account and will be able to execute commands that the user has permission to execute.

In Python, you can change the user ID or become the superuser using the os.setuid() and os.seteuid() functions. The os.setuid() function sets the effective user ID of the current process, while the os.seteuid() function sets the effective user ID of the current process to the real user ID of the user running the process. Here's an example of how to become the superuser in Python:

import os

# Become the superuser
os.seteuid(0)

# Run commands that require elevated privileges here...

# Revert back to the original user
os.seteuid(os.getuid())

In this example, the os.seteuid(0) function is used to become the superuser, and the os.seteuid(os.getuid()) function is used to revert back to the original user. Note that changing the user ID or becoming the superuser should be done with caution, as it can potentially compromise the security of your system.

Other Man Pages:

  1. How to create a user

In Unix-based systems like Linux and macOS, you can create a user using the useradd command. Here's an example of how to create a new user named "john":

$ sudo useradd john

In Python, you can create a user by running the subprocess.run() function with the sudo command and the useradd command as arguments. Here's an example of how to create a new user named "john" using Python:

import subprocess

# Create a new user named "john"
result = subprocess.run(['sudo', 'useradd', 'john'], capture_output=True, text=True)

# Print the result
print(result.stdout)
  1. How to create a group

still, In Unix-based systems like Linux and macOS, you can create a group using the groupadd command. Here's an example of how to create a new group named "staff":

$ sudo groupadd staff

In Python, you can create a group by running the subprocess.run() function with the sudo command and the groupadd command as arguments. Here's an example of how to create a new group named "staff" using Python:

import subprocess

# Create a new group named "staff"
result = subprocess.run(['sudo', 'groupadd', 'staff'], capture_output=True, text=True)

# Print the result
print(result.stdout)
  1. How to print real and effective user and group IDs

In Unix-based systems like Linux and macOS, you can print the real and effective user and group IDs using the id command. Here's an example of how to print the real and effective user and group IDs:

$ id

In Python, you can print the real and effective user and group IDs by running the os.getuid(), os.geteuid(), os.getgid(), and os.getegid() functions. Here's an example of how to print the real and effective user and group IDs using Python:

import os

# Print the real and effective user IDs
print(f"Real user ID: {os.getuid()}")
print(f"Effective user ID: {os.geteuid()}")

# Print the real and effective group IDs
print(f"Real group ID: {os.getgid()}")
print(f"Effective group ID: {os.getegid()}")
  1. How to print the groups a user is in

In Unix-based systems like Linux and macOS, you can print the groups a user is in using the groups command. Here's an example of how to print the groups that the current user is in:

$ groups

In Python, you can print the groups that a user is in by running the subprocess.run() function with the groups command and the username as arguments. Here's an example of how to print the groups that the user "john" is in using Python:

import subprocess

# Print the groups that the user "john" is in
result = subprocess.run(['groups', 'john'], capture_output=True, text=True)

# Print the result
print(result.stdout)

How to print the effective userid

In Unix-based systems like Linux and macOS, you can print the effective userid using the id -u command. Here's an example of how to print the effective userid:

$ id -u

In Python, you can print the effective userid by running the os.geteuid() function. Here's an example of how to print the effective userid using Python:

import os

# Print the effective userid
print(f"Effective userid: {os.geteuid()}")

This will print the effective userid of the current process. If you want to print the effective userid of another user, you'll need to run your Python script as that user or use the seteuid() function to temporarily change the effective userid of the current process.

exercises

  1. To create a new file called "test.txt" in your home directory with read and write permissions for the owner, group, and others, run the following command:
touch ~/test.txt
chmod 666 ~/test.txt

This will create a new file in your home directory called "test.txt" and set its permissions to read and write for the owner, group, and others.

  1. To change the permissions of the "test.txt" file to read and write for the owner only, run the following command:
chmod 600 ~/test.txt

This will modify the permissions of the "test.txt" file to allow read and write access only for the owner, and remove all access for group and others.

  1. To create a new directory called "testdir" in your home directory with read, write, and execute permissions for the owner, read and execute permissions for the group, and no permissions for others, run the following command:
mkdir ~/testdir
chmod 700 ~/testdir

This will create a new directory in your home directory called "testdir" and set its permissions to read, write, and execute for the owner, and no access for group and others.

  1. To change the permissions of the "testdir" directory to read, write, and execute for the owner, and read and execute for the group and others, run the following command:
chmod 755 ~/testdir

This will modify the permissions of the "testdir" directory to allow read, write, and execute access for the owner, and read and execute access for group and others.

  1. To create a new user account on your system and create a new file called "secret.txt" with read and write permissions for the owner only, run the following commands:
sudo adduser newuser
su newuser
touch secret.txt
chmod 600 secret.txt

This will create a new user account called "newuser" and switch to that account. Then it will create a new file called "secret.txt" and set its permissions to read and write for the owner only.

To verify that the original user account can no longer read or write the file, switch back to your original user account and try to access the file:

su your-username
cat ~/secret.txt

This should result in a "Permission denied" error, indicating that the original user account does not have permission to read the file.

Thank you for taking the time to read this blog. I hope you gained some knowledge today! If you found this article useful, please like, share, and follow me in the future for more blog entries like this.

Let's get together. On these platforms, I discuss web development, content creation, open source, career advice, and tech jobs.

Linkedin

Twitter

20
Subscribe to my newsletter

Read articles from Musa Oyiza directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Musa Oyiza
Musa Oyiza

I am a rising star in the world of software development. As a junior developer, I am constantly pushing the boundaries of what is possible and learning new skills along the way. Currently enrolled in the ALX Software Engineering Programme, I am passionate about sharing my knowledge with others. That's why I have created this blog, where I can offer insights and advice to fellow developers while continuing to learn and grow myself. With a strong background in programming languages like Java and Python, I am excited to tackle new challenges and explore the latest technologies. Whether it's building complex software applications or developing innovative solutions for clients, I am always up for the task. But it's not just about the technical side of things for me. I also understand the importance of collaboration and communication in the development process. That's why I am a team player who thrives in a fast-paced, dynamic environment where I can work closely with others to achieve shared goals. So if you're looking for a knowledgeable and driven software developer who is eager to share her expertise with others, look no further I am here. With my talent, passion, and dedication, I am sure to make a lasting impact in the world of software engineering.