4. users and permissions - mishraxharshit/harshitxmishra.github.io GitHub Wiki

Phase 4 — Users and Permissions

Previous: Phase 3 — Text Processing | Next: Phase 5 — Processes and Services


4.1 The Permission Model

Linux uses a simple but powerful permission model. Every file and directory has three attributes:

  1. Owner: one user who owns the file
  2. Group: one group associated with the file
  3. Permissions: what the owner, the group, and everyone else can do

Run ls -l to see permissions:

-rwxr-xr-- 1 alice developers 4096 Jan 15 notes.sh
^          |  ^     ^
|          |  |     group
|          |  owner
|          number of hard links
permissions

The permissions string has 10 characters:

- r w x r - x r - -
^ ^^^ ^^^ ^^^
| |   |   |
| |   |   others (everyone else) permissions
| |   group permissions
| owner permissions
file type (- = regular file, d = directory, l = symlink)

Each permission triple is three bits:

  • r — read
  • w — write
  • x — execute
  • - — permission not granted

For files:

  • r — can read the file's content
  • w — can modify or delete the file
  • x — can run the file as a program

For directories:

  • r — can list the directory's contents with ls
  • w — can create, delete, or rename files inside the directory
  • x — can enter the directory with cd and access files inside (execute on a directory means "traverse")

4.2 Numeric (Octal) Permission Notation

Permissions are often written as a three-digit number. Each digit represents one of the three groups (owner, group, others) and is the sum of the permission bits:

Bit Value Meaning
r 4 read
w 2 write
x 1 execute

4.3 Changing Permissions with chmod

# Numeric mode
chmod 755 script.sh         # rwxr-xr-x
chmod 644 notes.txt         # rw-r--r--
chmod 600 ~/.ssh/id_rsa     # rw------- (required for SSH private keys)
chmod -R 755 /var/www/html  # -R applies recursively to all files in directory

Symbolic mode: [who][operation][permission]

who: u=owner, g=group, o=others, a=all

op: + add, - remove, = set exactly

chmod u+x script.sh # add execute for owner chmod go-w notes.txt # remove write for group and others chmod a+r public.txt # add read for everyone chmod u=rw,go=r config.txt # owner: rw, group+others: r

Real-world example: Setting up a web server directory

# Web server user is www-data
# Developer user is alice

Website files: web server reads, developer writes

sudo chown -R alice:www-data /var/www/html sudo chmod -R 755 /var/www/html

This means: alice can write, www-data (and others) can read and traverse

Configuration files with secrets: only root reads

sudo chmod 600 /etc/mysql/mysql.conf.d/mysqld.cnf


4.4 Changing Ownership with chown

# Change owner
sudo chown bob file.txt
sudo chown bob:developers file.txt   # change owner and group
sudo chown :developers file.txt      # change only the group

Recursive: change all files in a directory

sudo chown -R alice:alice /home/alice/

Change group only (shorthand with chgrp)

sudo chgrp developers project/

Real-world scenario: A file transferred as root

# You copied a file as root, now you own it
ls -l report.pdf
# -rw-r--r-- 1 root root 45000 Jan 15 report.pdf

Give it back to alice

sudo chown alice:alice report.pdf


4.5 Understanding Users

Every user has an entry in /etc/passwd. This file is readable by everyone — it does not contain passwords (those are in /etc/shadow).

cat /etc/passwd | head -5
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
# alice:x:1000:1000:Alice Smith,,,:/home/alice:/bin/bash

Each field is colon-separated:

  1. Username
  2. Password placeholder (x means password is in /etc/shadow)
  3. User ID (UID)
  4. Primary Group ID (GID)
  5. GECOS field (full name and other info)
  6. Home directory
  7. Default shell

System accounts (daemons like www-data, mysql) have UIDs below 1000 and their shell is /usr/sbin/nologin, meaning they cannot log in interactively.


4.6 Managing Users

# Add a new user (creates home directory, default shell)
sudo adduser bob
# Prompts for password and other info

Add user without interactive prompts (for scripts)

sudo useradd -m -s /bin/bash -c "Bob Jones" bob

-m creates home directory

-s sets the shell

-c sets the comment/full name field

Set or change a password

sudo passwd bob

Delete a user

sudo deluser bob sudo deluser --remove-home bob # also deletes home directory

Modify an existing user

sudo usermod -s /bin/zsh alice # change shell sudo usermod -aG docker alice # add alice to docker group (-a means append) sudo usermod -L alice # lock account sudo usermod -U alice # unlock account sudo usermod -e 2025-12-31 contractor # set account expiry date

See user information

id alice

uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo),998(docker)

See who is currently logged in

who w last | head -10 # login history


4.7 Managing Groups

# See all groups
cat /etc/group | grep alice

See groups the current user belongs to

groups

alice sudo docker

Create a group

sudo groupadd developers

Add user to group (takes effect on next login)

sudo usermod -aG developers alice

Remove user from group

sudo gpasswd -d alice developers

Delete a group

sudo groupdel developers


4.8 The Root User and sudo

The root user has UID 0 and bypasses all permission checks. Running everything as root is dangerous: a single typo like rm -rf /tmp /important (note the accidental space) can destroy the system.

sudo (superuser do) lets authorised users run individual commands as root. It logs every action, requires the user's own password, and can be restricted to specific commands.

# Run a single command as root
sudo apt update

Open a root shell (be careful, stay in it only for what you need)

sudo bash

or

sudo su -

Run a command as a different user

sudo -u www-data ls /var/www/html

See what sudo commands you are allowed to run

sudo -l

sudo configuration is in /etc/sudoers. Edit it with visudo, which validates syntax before saving (a broken sudoers file can lock you out).

sudo visudo

Common sudoers entries:

Give alice full sudo access (same as root)

alice ALL=(ALL:ALL) ALL

Allow alice to run apt without a password

alice ALL=(ALL) NOPASSWD: /usr/bin/apt

Give the developers group full access

%developers ALL=(ALL:ALL) ALL


4.9 SSH Keys for Authentication

Password authentication is convenient but less secure. SSH keys use asymmetric cryptography: a private key (never shared) and a public key (placed on the server).

# Generate an SSH key pair
ssh-keygen -t ed25519 -C "alice@mycomputer"
# Creates:
# ~/.ssh/id_ed25519       (private key — never share this)
# ~/.ssh/id_ed25519.pub   (public key — place this on servers)

Copy public key to a remote server

ssh-copy-id [email protected]

This adds your public key to ~/.ssh/authorized_keys on the server

Connect using the key (no password prompt if configured correctly)

ssh [email protected]

If you have multiple keys, specify which one

ssh -i ~/.ssh/work_key [email protected]

Required permissions for SSH keys (SSH refuses to use keys with wrong permissions)

chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub chmod 600 ~/.ssh/authorized_keys


4.10 Special Permission Bits

Beyond the standard rwx bits, there are three special bits.

Setuid (SUID): When set on an executable, the program runs with the file owner's permissions rather than the executing user's permissions. The passwd command uses this: it runs as root so it can write to /etc/shadow, even when run by a regular user.

ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 /usr/bin/passwd
#     ^ the 's' in owner execute position means setuid is set

Setgid (SGID): On an executable, runs with the file group's permissions. On a directory, new files created inside inherit the directory's group rather than the creator's primary group. Useful for shared project directories.

chmod g+s /shared/project
# Files created inside inherit project's group

Sticky bit: On a directory, only the file's owner (or root) can delete the file, even if others have write permission on the directory. Used on /tmp so users cannot delete each other's temporary files.

ls -ld /tmp
# drwxrwxrwt 20 root root 4096 Jan 15 /tmp
#          ^ the 't' in others execute position means sticky bit is set

chmod +t /shared/uploads


Phase 4 Exercises

Exercise 1: Create a file called test.txt. Use ls -l to see its permissions. Use chmod to change permissions to 640. Verify with ls -l. Explain what 640 means.

Exercise 2: Create a directory called shared. Set permissions so the owner can read/write/execute, the group can read and execute, and others have no access. What numeric permission is this?

Exercise 3: Look up your own UID and GID using id. Then look at your entry in /etc/passwd. What is your default shell?

Exercise 4: Run ls -la /usr/bin/sudo and /usr/bin/passwd. Note the special permission bits. Explain why each one needs the permissions it has.

Exercise 5: Generate an SSH key pair with ssh-keygen. Verify that the private key has permissions 600 and the public key has permissions 644.


Common Mistakes in Phase 4

Mistake: Setting 777 permissions chmod 777 gives everyone full access. This is almost never correct. If you find yourself doing this to "fix a permission error", stop and understand why the error is occurring.

Mistake: Logging in as root for daily work Use your regular user account and sudo only when required. If you damage something as root, there is no safety net.

Mistake: Forgetting that group membership changes need re-login If you add a user to a group with usermod -aG, the user must log out and back in (or run newgrp groupname) for the change to take effect in their shell session.

Mistake: Keeping SSH private keys unprotected Your private key at ~/.ssh/id_ed25519 must have permissions 600. If it is world-readable, SSH will refuse to use it and print an error about "unprotected private key file".


Previous: Phase 3 — Text Processing | Next: Phase 5 — Processes and Services

# Phase 4 — Users and Permissions

Previous: [Phase 3 — Text Processing](Phase-3-Text-Processing) | Next: [Phase 5 — Processes and Services](Phase-5-Processes-and-Services)


4.1 The Permission Model

Linux uses a simple but powerful permission model. Every file and directory has three attributes:

  1. Owner: one user who owns the file
  2. Group: one group associated with the file
  3. Permissions: what the owner, the group, and everyone else can do

Run ls -l to see permissions:

-rwxr-xr-- 1 alice developers 4096 Jan 15 notes.sh
^          |  ^     ^
|          |  |     group
|          |  owner
|          number of hard links
permissions

The permissions string has 10 characters:

- r w x r - x r - -
^ ^^^ ^^^ ^^^
| |   |   |
| |   |   others (everyone else) permissions
| |   group permissions
| owner permissions
file type (- = regular file, d = directory, l = symlink)

Each permission triple is three bits:

  • r — read
  • w — write
  • x — execute
  • - — permission not granted

For files:

  • r — can read the file's content
  • w — can modify or delete the file
  • x — can run the file as a program

For directories:

  • r — can list the directory's contents with ls
  • w — can create, delete, or rename files inside the directory
  • x — can enter the directory with cd and access files inside (execute on a directory means "traverse")

4.2 Numeric (Octal) Permission Notation

Permissions are often written as a three-digit number. Each digit represents one of the three groups (owner, group, others) and is the sum of the permission bits:

Bit Value Meaning
r 4 read
w 2 write
x 1 execute

So:

  • rwx = 4+2+1 = 7
  • rw- = 4+2+0 = 6
  • r-x = 4+0+1 = 5
  • r-- = 4+0+0 = 4
  • --- = 0+0+0 = 0

Common permission combinations:

Number String Typical Use
755 rwxr-xr-x Executable program, public website directory
644 rw-r--r-- Regular text file, configuration file
700 rwx------ Personal script only you can run
600 rw------- Private key, password file
777 rwxrwxrwx Avoid: gives everyone full access
000 --------- No one can access (even owner, unless root)

4.3 Changing Permissions with chmod

# Numeric mode
chmod 755 script.sh         # rwxr-xr-x
chmod 644 notes.txt         # rw-r--r--
chmod 600 ~/.ssh/id_rsa     # rw------- (required for SSH private keys)
chmod -R 755 /var/www/html  # -R applies recursively to all files in directory

# Symbolic mode: [who][operation][permission]
# who:  u=owner, g=group, o=others, a=all
# op:   + add, - remove, = set exactly
chmod u+x script.sh         # add execute for owner
chmod go-w notes.txt        # remove write for group and others
chmod a+r public.txt        # add read for everyone
chmod u=rw,go=r config.txt  # owner: rw, group+others: r

Real-world example: Setting up a web server directory

# Web server user is www-data
# Developer user is alice

# Website files: web server reads, developer writes
sudo chown -R alice:www-data /var/www/html
sudo chmod -R 755 /var/www/html
# This means: alice can write, www-data (and others) can read and traverse

# Configuration files with secrets: only root reads
sudo chmod 600 /etc/mysql/mysql.conf.d/mysqld.cnf

4.4 Changing Ownership with chown

# Change owner
sudo chown bob file.txt
sudo chown bob:developers file.txt   # change owner and group
sudo chown :developers file.txt      # change only the group

# Recursive: change all files in a directory
sudo chown -R alice:alice /home/alice/

# Change group only (shorthand with chgrp)
sudo chgrp developers project/

Real-world scenario: A file transferred as root

# You copied a file as root, now you own it
ls -l report.pdf
# -rw-r--r-- 1 root root 45000 Jan 15 report.pdf

# Give it back to alice
sudo chown alice:alice report.pdf

4.5 Understanding Users

Every user has an entry in /etc/passwd. This file is readable by everyone — it does not contain passwords (those are in /etc/shadow).

cat /etc/passwd | head -5
# root:x:0:0:root:/root:/bin/bash
# daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
# alice:x:1000:1000:Alice Smith,,,:/home/alice:/bin/bash

Each field is colon-separated:

  1. Username
  2. Password placeholder (x means password is in /etc/shadow)
  3. User ID (UID)
  4. Primary Group ID (GID)
  5. GECOS field (full name and other info)
  6. Home directory
  7. Default shell

System accounts (daemons like www-data, mysql) have UIDs below 1000 and their shell is /usr/sbin/nologin, meaning they cannot log in interactively.


4.6 Managing Users

# Add a new user (creates home directory, default shell)
sudo adduser bob
# Prompts for password and other info

# Add user without interactive prompts (for scripts)
sudo useradd -m -s /bin/bash -c "Bob Jones" bob
# -m creates home directory
# -s sets the shell
# -c sets the comment/full name field

# Set or change a password
sudo passwd bob

# Delete a user
sudo deluser bob
sudo deluser --remove-home bob    # also deletes home directory

# Modify an existing user
sudo usermod -s /bin/zsh alice             # change shell
sudo usermod -aG docker alice              # add alice to docker group (-a means append)
sudo usermod -L alice                      # lock account
sudo usermod -U alice                      # unlock account
sudo usermod -e 2025-12-31 contractor      # set account expiry date

# See user information
id alice
# uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo),998(docker)

# See who is currently logged in
who
w
last | head -10    # login history

4.7 Managing Groups

# See all groups
cat /etc/group | grep alice

# See groups the current user belongs to
groups
# alice sudo docker

# Create a group
sudo groupadd developers

# Add user to group (takes effect on next login)
sudo usermod -aG developers alice

# Remove user from group
sudo gpasswd -d alice developers

# Delete a group
sudo groupdel developers

4.8 The Root User and sudo

The root user has UID 0 and bypasses all permission checks. Running everything as root is dangerous: a single typo like rm -rf /tmp /important (note the accidental space) can destroy the system.

sudo (superuser do) lets authorised users run individual commands as root. It logs every action, requires the user's own password, and can be restricted to specific commands.

# Run a single command as root
sudo apt update

# Open a root shell (be careful, stay in it only for what you need)
sudo bash
# or
sudo su -

# Run a command as a different user
sudo -u www-data ls /var/www/html

# See what sudo commands you are allowed to run
sudo -l

sudo configuration is in /etc/sudoers. Edit it with visudo, which validates syntax before saving (a broken sudoers file can lock you out).

sudo visudo

# Common sudoers entries:
# Give alice full sudo access (same as root)
alice   ALL=(ALL:ALL) ALL

# Allow alice to run apt without a password
alice   ALL=(ALL) NOPASSWD: /usr/bin/apt

# Give the developers group full access
%developers   ALL=(ALL:ALL) ALL

4.9 SSH Keys for Authentication

Password authentication is convenient but less secure. SSH keys use asymmetric cryptography: a private key (never shared) and a public key (placed on the server).

# Generate an SSH key pair
ssh-keygen -t ed25519 -C "alice@mycomputer"
# Creates:
# ~/.ssh/id_ed25519       (private key — never share this)
# ~/.ssh/id_ed25519.pub   (public key — place this on servers)

# Copy public key to a remote server
ssh-copy-id [email protected]
# This adds your public key to ~/.ssh/authorized_keys on the server

# Connect using the key (no password prompt if configured correctly)
ssh [email protected]

# If you have multiple keys, specify which one
ssh -i ~/.ssh/work_key [email protected]

# Required permissions for SSH keys (SSH refuses to use keys with wrong permissions)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys

4.10 Special Permission Bits

Beyond the standard rwx bits, there are three special bits.

Setuid (SUID): When set on an executable, the program runs with the file owner's permissions rather than the executing user's permissions. The passwd command uses this: it runs as root so it can write to /etc/shadow, even when run by a regular user.

ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 /usr/bin/passwd
#     ^ the 's' in owner execute position means setuid is set

Setgid (SGID): On an executable, runs with the file group's permissions. On a directory, new files created inside inherit the directory's group rather than the creator's primary group. Useful for shared project directories.

chmod g+s /shared/project
# Files created inside inherit project's group

Sticky bit: On a directory, only the file's owner (or root) can delete the file, even if others have write permission on the directory. Used on /tmp so users cannot delete each other's temporary files.

ls -ld /tmp
# drwxrwxrwt 20 root root 4096 Jan 15 /tmp
#          ^ the 't' in others execute position means sticky bit is set

chmod +t /shared/uploads

Phase 4 Exercises

Exercise 1: Create a file called test.txt. Use ls -l to see its permissions. Use chmod to change permissions to 640. Verify with ls -l. Explain what 640 means.

Exercise 2: Create a directory called shared. Set permissions so the owner can read/write/execute, the group can read and execute, and others have no access. What numeric permission is this?

Exercise 3: Look up your own UID and GID using id. Then look at your entry in /etc/passwd. What is your default shell?

Exercise 4: Run ls -la /usr/bin/sudo and /usr/bin/passwd. Note the special permission bits. Explain why each one needs the permissions it has.

Exercise 5: Generate an SSH key pair with ssh-keygen. Verify that the private key has permissions 600 and the public key has permissions 644.


Common Mistakes in Phase 4

Mistake: Setting 777 permissions chmod 777 gives everyone full access. This is almost never correct. If you find yourself doing this to "fix a permission error", stop and understand why the error is occurring.

Mistake: Logging in as root for daily work Use your regular user account and sudo only when required. If you damage something as root, there is no safety net.

Mistake: Forgetting that group membership changes need re-login If you add a user to a group with usermod -aG, the user must log out and back in (or run newgrp groupname) for the change to take effect in their shell session.

Mistake: Keeping SSH private keys unprotected Your private key at ~/.ssh/id_ed25519 must have permissions 600. If it is world-readable, SSH will refuse to use it and print an error about "unprotected private key file".


Previous: [Phase 3 — Text Processing](Phase-3-Text-Processing) | Next: [Phase 5 — Processes and Services](Phase-5-Processes-and-Services)

⚠️ **GitHub.com Fallback** ⚠️