a [bite sized] guide to unix file permissions

Unix 101: access controls are done at the file and directory level.

  • A file or directory is "owned" by a user and a group.

  • The file's "mode" controls who is allowed to access, execute, or modify the file.

  • Permissions are divided by "user", "group", and "other".

For example, let's make a new file and check its permissions:

% touch a
% ls -l a
-rw-r--r--  1 fred  staff  0 Dec  3 15:52 a

touch creates a blank file named a. ls -l asks for the "long" output of the ls or "list" command, which shows us the permissions, owner, size, and modification time. We can see this file is owned by fred (hey, that's me), group staff, but what permissions are on the file?

-rw-r--r--
 ^   ^   ^
 |   |   |
 |   |   |---- other
 |   |---- group
 |---- user

Referring to this handy diagram, we can see that the "user" permissions of the file's owner (fred), are "read and write". The permissions of anyone in the file's owning "group" (which is staff) is "read". Everyone who's not fred or in group staff has only "read" permission.

OK, so what are those other --- things for?

the execute bit

Also known as +x.

For files

Controls whether or not the file can be executed as a standalone command. Programs such as ls and cat are stored in files with the +x bit enabled.

% chmod u+x a.out	# user can execute a.out
% ls -l a.out
-rwxr--r-- … a.out

% chmod g+x a.out	# group can execute a.out
% ls -l a.out
-rwxr-xr-- … a.out

% chmod +x			# everyone can execute a.out!
% ls -l a.out
-rwxr-xr-x … a.out

Shell scripts are ordinary files with a "shebang" starting line and the execute bit set on the file.

If I create hello.sh in my current directory:

#!/bin/sh
echo "hello, world!"

When I try to run it, I get an error:

% ./hello.sh
Permission denied

When I set the executable bit, I can now run it as a command:

% chmod +x ./hello.sh
% ./hello.sh
hello, world!

For directories

The executable bit controls whether the directory can be "traversed". For example, say I want to share a directory, but I don't want people to poke around my home directory. Home directories are usually -rwx------ to prevent people from snooping.

% ls -ld ~
-rwx------  1 fred  staff  0 Dec  3 15:52 /home/fred
% ls -ld ~/projects
-rwxr-xr-x  1 fred  staff  0 Dec  3 15:52 /home/fred/projects

OK, cool. Say now I want to share my projects directory with someone else on the system. Even if I set the permissions to "wide open" 0777 (user, group, and everyone can read/write/execute), you still won't be able to look in my projects directory.

% chmod 777 ~/projects
% sudo -u bob ls /home/fred/projects
Permission denied

That's because the "execute" bit on my home directory isn't allowing bob to traverse /home/fred to get to /home/fred/projects. The fix?

% chmod +x ~
% ls -ld ~
-rwx--x--x  1 fred  staff  0 Dec  3 15:52 /home/fred
% sudo -u bob ls /home/fred/projects
manic
fidget

Because the "read" bit isn't set on my home directory, bob can't list the contents. He can, however, "traverse" it and look at the contents of /home/fred/projects.

the "extra" bits

setuid

for programs

Forces the program run as the user that owns the file, no matter what user is running it. Unless you're writing a daemon or system utility, you don't need this.

In fact, setuid is a cause of security problems: if, for example, the rm program — usually owned by root user, root group — had the setuid bit set, then it would always run with root's permissions. Anyone could blow away the entire system by running rm -rf /, which would be a bad thing™.

setgid

for programs

Forces the program run as the group that owns the file, no matter what user is running it. Unless you're writing a daemon or system utility, you don't need this.

for directories

Makes sure that newly created directories & files are owned by the same group. See this post on effective use of the setgid book.

user / group sticky

These are mainly used to protect files /tmp from being deleted by anyone but their owners. /tmp has "wide open" permissions, so everyone can create temporary files. With the "sticky" bit set, however, only the file or directory's owning group or user can delete. This prevents hijinks like deleting other users' temporary files.