FactorPad
Build a Better Process

Linux Permissions: Files, Directories, Users and Groups

With server-level security built-in to Linux, a small investment of time can help to better protect your data.
  1. Overview - Outline why Linux is known for security.
  2. Change identity - Learn how to differentiate between sudo and su commands.
  3. File & directory - Use a detailed directory listing to introduce file permissions.
  4. Owner & group - Make changes with chmod and chown and use id to examine group memberships.
  5. Next: environment - Explore Linux environment variables.
face pic by Paul Alan Davis, CFA
Updated: February 21, 2021
A key to learning Linux is to see everything once. Then remember where to find it.

Outline Back Tip Next

/ factorpad.com / tech / full-stack / linux-permissions.html


An ad-free and cookie-free website.


Learn how to manage user and group permissions in Linux

Beginner

Video Tutorial

Videos can also be accessed from our Full Stack Playlist 2 on YouTube.

Linux permissions: files, directories, users and groups | Linux Tutorial for Beginners (4:58)

Code Examples and Video Script

Welcome. Today's question: How do you set permissions in Linux?

I'm Paul, and we've seen it, on a Mac or Windows PC, user rights and permissions are often ignored, but in a multi-user system like Linux we like to think of security first.

So here, we'll do an overview and our goal is not to become a full-blown system administrator; intead, we will cover essentials and have a place to return when we forget the details. As we always seem to do.

Step 1 - Overview

We'll use sudo and su to temporarily change our identity and rights.

Then we'll learn how to modify permissions on files and directories, which requires knowledge of owners and groups.

(We will work with these new commands here)

(And practice with others)

And next on our journey, we will talk about the Linux environment.

Step 2 - The How and Why of Changing Identities in Linux

Let's look through a terminal window at a local Linux test server located in my office in Santa Barbara, and pause now if you would like a summary of the commands we will use here.

paul@fullstack:~$ whatis sudo su id chmod chown whatis apt-get whoami ls less sudo (8) - execute a command as another user su (1) - change user ID or become superuser id (1) - print real and effective user and group IDs chmod (1) - change file mode bits chown (1) - change file owner and group whatis (1) - display one-line manual page descriptions apt-get (8) - APT package handling utility - - command-line interface whoami (1) - print effective userid ls (1) - list directory contents less (1) - opposite of more
Use sudo to temporarily perform superuser administrative tasks

Our first identity-changing command is sudo. In the last tutorial on installing packages we put sudo in front of apt-get update.

paul@fullstack:~$ apt-get update E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied) E: Unable to lock directory /var/lib/apt/lists/ E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied) E: Unable to lock the administration directory (/var/lib/dpkt/), are you root?

Without it Linux barks at us.

So when using sudo, Linux verifies that I'm part of the sudo group, and gives administrator privileges.

paul@fullstack:~$ sudo apt-get update Hit http://security.debian.org jessie/updates InRelease Ign http://ftp.us.debian.org jessie InRelease Hit http://ftp.us.debian.org jessie-updates InRelease Hit http://security.debian.org jessie/updates/main Sources Hit http://ftp.us.debian.org jessie Release.gpg Hit http://security.debian.org jessie/updates/main amd64 Packages Hit http://security.debian.org jessie-updates/main Translation-en Hit http://ftp.us.debian.org jessie-updates/main Sources Get:1 http://ftp.us.debian.org jessie-updates/main amd64 Packages/DiffIndex [6,916 B] Get:2 http://ftp.us.debian.org jessie-updates/main Translation-en/DiffIndex [2,704 B] Hit http://ftp.us.debian.org jessie Release Hit http://ftp.us.debian.org jessie/main Sources Hit http://ftp.us.debian.org jessie/main amd64 Packages Hit http://ftp.us.debian.org jessie/main Translation-en Fetched 9,620 B in 2s (4,317 B/s) Reading package lists... Done paul@fullstack:~$

I'll cover groups shortly, and for those following along at home, my Debian 8 installation, as a safety precaution, didn't install sudo by default, so you may need to install it like this.

root@fullstack:/root# apt-get install sudo

I prefer to show you how to fend for yourself here, so please get comfortable with --help.

paul@fullstack:~$ sudo --help sudo - execute a command as another user usage: sudo -h | -K | -k | -V usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user] usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command] usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-u user] [VAR=value] [-i|-s] [<command>] usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-u user] file ... Options: -A, --askpass use a helper program for password prompting -b, --background run command in the background -C, --close-from=num close all file descriptors >= num -E, --preserve-env preserve user environment when running command -e, --edit edit files instead of running a command -g, --group=group run command as the specified group name or ID -H, --set-home set HOME variable to target user's home dir -h, --help display help message and exit -h, --host=host run command on host (if supported by plugin) -i, --login run login shell as the target user; a command may also be specified -K, --remove-timestamp remove timestamp file completely -k, --reset-timestamp invalidate timestamp file -l, --list list user's privileges or check a specific command; use twice for longer format -n, --non-interactive non-interactive mode, no prompts are used -P, --preserve-groups preserve group vector instead of setting to target's -p, --prompt=prompt use the specified password prompt -r, --role=role create SELinux security context with specified role -S, --stdin read password from standard input -s, --shell run shell as the target user; a command may also be specified -t, --type=type create SELinux security context with specified type -U, --other-user=user in list mode, display privileges for user -u, --user=user run command (or edit file) as specified user name or ID -V, --version display version information and exit -v, --validate update user's timestamp without running a command -- stop processing command line arguments paul@fullstack:~$ clear
Use su to temporarily operate Linux with a different user ID

The su command allows us to open another shell session as someone else.

paul@fullstack:~$ whoami paul

In Linux there are human users and system users. During installation in tutorial 7, we set up a human user called root, the most powerful user on the system.

As a security precaution, it isn't advised to use the root account for everyday work, so I also set up an account paul, which I'm currently using.

With the su command, I can stay logged in, but open another shell as the root, for example, to view contents of the home directory of the root user.

paul@fullstack:~$ ls -a /root ls: cannot open directory /root: Permission denied paul@fullstack:~$ su root Password: root@fullstack:/home/paul# ls -a /root . .. .bash_history .bashrc .profile root@fullstack:/home/paul# exit exit paul@fullstack:~$ whoami paul paul@fullstack:~$ clear

The prompt changed and with exit, I go back to being paul.

Step 3 - Linux File and Directory Permissions

Next, let's talk about file and directory permissions, often called modes, doing an ls -al showing all details of all files in the home directory for paul.

paul@fullstack:~$ ls -al total 64 drwxr-xr-x 5 paul paul 4096 Mar 2 09:46 . drwxr-xr-x 3 root root 4096 Jan 3 15:09 .. drwx------ 2 paul paul 4096 Feb 26 19:19 .aptitude -rw------- 1 paul paul 23236 Mar 2 11:56 .bash_history -rw-r--r-- 1 paul paul 220 Jan 3 15:09 .bash_logout -rw-r--r-- 1 paul paul 3723 Feb 28 11:31 .bashrc -rw-r--r-- 1 paul paul 3515 Feb 8 07:49 .bashrc.factory -rw-r--r-- 1 paul paul 0 Mar 2 09:46 chmod_me.txt -rw-r--r-- 1 paul paul 0 Mar 2 09:46 chown_me.txt -rw------- 1 paul paul 104 Feb 23 19:52 .lesshst drwxr-xr-x 2 paul paul 4096 Feb 28 14:59 notes -rw-r--r-- 1 paul paul 675 Jan 3 15:09 .profile drwx------ 2 paul paul 4096 Jan 24 15:49 .w3m paul@fullstack:~$

Let's interpret by going left to right, and (in the first column) d means it is a directory, like the directory notes, a - is a regular file.

Step 4 - Linux Owner and Group Permissions

The next block of three letters, read, write, and execute refer to the rights of the owner, paul as noted here (in the first or 'owner' column where it says paul).

So in the directory notes, paul can read, write and execute files.

The next three refer to groups, noted in the second column, paul here (the second or 'group' column).

Every user is assigned to at least one group, even if that group is named after the user. So any other member of the group paul, can read and execute files, but not write to the notes directory, because the w is missing.

The next block of three refer to the world, or guests, so they can only read and execute.

How to change user and group permissions

There are three ways to change permissions as shown in our Linux Cheat Sheet giving you a few choices (Octal, Binary and Mode).

Octal Binary Mode
0 000 ---
1 001 --x
2 010 -w-
3 011 -wx
4 100 r--
5 101 r-x
6 110 rw-
7 111 rwx

The one I find easiest is the Octal method, and here let's tighten this up a bit for the file chmod_me.txt.

paul@fullstack:~$ ls -al total 64 drwxr-xr-x 5 paul paul 4096 Mar 2 09:46 . drwxr-xr-x 3 root root 4096 Jan 3 15:09 .. drwx------ 2 paul paul 4096 Feb 26 19:19 .aptitude -rw------- 1 paul paul 23236 Mar 2 11:56 .bash_history -rw-r--r-- 1 paul paul 220 Jan 3 15:09 .bash_logout -rw-r--r-- 1 paul paul 3723 Feb 28 11:31 .bashrc -rw-r--r-- 1 paul paul 3515 Feb 8 07:49 .bashrc.factory -rw-r--r-- 1 paul paul 0 Mar 2 09:46 chmod_me.txt -rw-r--r-- 1 paul paul 0 Mar 2 09:46 chown_me.txt -rw------- 1 paul paul 104 Feb 23 19:52 .lesshst drwxr-xr-x 2 paul paul 4096 Feb 28 14:59 notes -rw-r--r-- 1 paul paul 675 Jan 3 15:09 .profile drwx------ 2 paul paul 4096 Jan 24 15:49 .w3m paul@fullstack:~$ chmod 660 chmod_me.txt

And then verify.

paul@fullstack:~$ ls -al total 64 drwxr-xr-x 5 paul paul 4096 Mar 2 09:46 . drwxr-xr-x 3 root root 4096 Jan 3 15:09 .. drwx------ 2 paul paul 4096 Feb 26 19:19 .aptitude -rw------- 1 paul paul 23236 Mar 2 11:56 .bash_history -rw-r--r-- 1 paul paul 220 Jan 3 15:09 .bash_logout -rw-r--r-- 1 paul paul 3723 Feb 28 11:31 .bashrc -rw-r--r-- 1 paul paul 3515 Feb 8 07:49 .bashrc.factory -rw-rw---- 1 paul paul 0 Mar 2 09:46 chmod_me.txt -rw-r--r-- 1 paul paul 0 Mar 2 09:46 chown_me.txt -rw------- 1 paul paul 104 Feb 23 19:52 .lesshst drwxr-xr-x 2 paul paul 4096 Feb 28 14:59 notes -rw-r--r-- 1 paul paul 675 Jan 3 15:09 .profile drwx------ 2 paul paul 4096 Jan 24 15:49 .w3m paul@fullstack:~$
View a system users list

So I mentioned users, both human and system. We can see all 27 users by viewing the systemwide /etc/passwd file.

paul@fullstack:~$ less /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false Debian-exim:x:104:109::/var/spool/exim4:/bin/false messagebus:x:105:110::/var/run/dbus:/bin/false statd:x:106:65534::/var/lib/nfs:/bin/false sshd:x:107:65534::/var/run/sshd:/usr/sbin/nologin paul:x:1000:1000:Paul Davis,,,:/home/paul:/bin/bash /etc/passwd (END)

There's root and paul at the bottom, with the rest being system users like mail, news and backup.

View a system groups list

Another important file is the systemwide /etc/group file, listing all 53 groups.

paul@fullstack:~$ less /etc/group root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4: tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20: fax:x:21: voice:x:22: cdrom:x:24:paul floppy:x:25:paul tape:x:26: sudo:x:27:paul audio:x:29:paul dip:x:30:paul www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: /etc/group (25 lines trimmed)
See all groups to which a user belongs using the id command

I can use the id command to see my groups.

paul@fullstack:~$ id paul uid=1000(paul) gid=1000(paul) groups=1000(paul),24(cdrom),25(floppy),27(sudo), 29(audio),30(dip),44(video),46(plugdev),108(netdev)

There's my user ID (uid=1000), group ID (gid=1000) and my groups.

How to change owners and groups for files and directories

Next, let's use the chown command, acting as the root with su, login and change the owner of a file called chown_me.txt to the root.

paul@fullstack:~$ ls -al total 64 drwxr-xr-x 5 paul paul 4096 Mar 2 09:46 . drwxr-xr-x 3 root root 4096 Jan 3 15:09 .. drwx------ 2 paul paul 4096 Feb 26 19:19 .aptitude -rw------- 1 paul paul 23236 Mar 2 11:56 .bash_history -rw-r--r-- 1 paul paul 220 Jan 3 15:09 .bash_logout -rw-r--r-- 1 paul paul 3723 Feb 28 11:31 .bashrc -rw-r--r-- 1 paul paul 3515 Feb 8 07:49 .bashrc.factory -rw-rw---- 1 paul paul 0 Mar 2 09:46 chmod_me.txt -rw-r--r-- 1 paul paul 0 Mar 2 09:46 chown_me.txt -rw------- 1 paul paul 104 Feb 23 19:52 .lesshst drwxr-xr-x 2 paul paul 4096 Feb 28 14:59 notes -rw-r--r-- 1 paul paul 675 Jan 3 15:09 .profile drwx------ 2 paul paul 4096 Jan 24 15:49 .w3m paul@fullstack:~$ su root Password: root@fullstack:/home/paul# chown root chown_me.txt

And then verify.

root@fullstack:/home/paul# ls -al total 64 drwxr-xr-x 5 paul paul 4096 Mar 2 09:46 . drwxr-xr-x 3 root root 4096 Jan 3 15:09 .. drwx------ 2 paul paul 4096 Feb 26 19:19 .aptitude -rw------- 1 paul paul 23236 Mar 2 11:56 .bash_history -rw-r--r-- 1 paul paul 220 Jan 3 15:09 .bash_logout -rw-r--r-- 1 paul paul 3723 Feb 28 11:31 .bashrc -rw-r--r-- 1 paul paul 3515 Feb 8 07:49 .bashrc.factory -rw-rw---- 1 paul paul 0 Mar 2 09:46 chmod_me.txt -rw-r--r-- 1 root paul 0 Mar 2 09:46 chown_me.txt -rw------- 1 paul paul 104 Feb 23 19:52 .lesshst drwxr-xr-x 2 paul paul 4096 Feb 28 14:59 notes -rw-r--r-- 1 paul paul 675 Jan 3 15:09 .profile drwx------ 2 paul paul 4096 Jan 24 15:49 .w3m root@fullstack:/home/paul#

Step 5 - Next: Linux Environment Variables

Okay, let me show you where we are headed in this Playlist.

(Here is the beginning of our software stack)

We're nearing the end of Project 2, Linux for Beginners. Our next Project is to set up the software layer with Python, but before that we will tackle the Environment in the next tutorial.

Have a nice day.


What's Next?

How are we doing? Please send feedback on our YouTube Channel. Connect @factorpad on twitter for updates.

Outline Back Tip Next

/ factorpad.com / tech / full-stack / linux-permissions.html


linux permissions
linux change user
linux file permissions
chmod command
chown command
linux change group
id command
linux su
linux sudo
linux directory permissions
linux change owner
check permissions linux
chmod permissions
linux user group
linux switch user
linux list groups
linux passwd
linux tutorial

A newly-updated free resource. Connect and refer a friend today.