Changelog:
- 14 Sep 2023: change
owning users
toowning user
1 Users
and
Groups
Every program runs as some user. This is true even
of the user interface, a program that allows you to run other programs.
When one program runs another, the new program runs as the same user as
the old one except in a few special circumstances. An example special
circumstance is the log in
program, which itself runs as
root
, but after you log in, runs your user interface as
your user account.
You can find out what user you are running as via the command whoami
.
Each user generally has a name and also a numerical ID. Typically, the numerical ID is what is used internally by the kernel to identify a user.
Every user can belong to any number of groups. You
can find out which groups a user belongs to by running the command groups <username>
;
if you omit the username, it will list your own group memberships.
Every file and directory also has a user and a group—but just one group, not a whole set. The user of a file does not need to belong to the group of the file.
2 POSIX file permissions
Permissions are split into three kinds, with different meanings for:
- r
-
- for files
-
permission to read its contents (e.g.
cat file
works) - for directories
-
permission to list its contents (e.g.
ls directory/
works)
- w
-
- for files
-
permission to write its contents
(e.g.
echo whatnot >> file
works) - for directories
-
permission to add and remove its contents
(e.g.
rm directory/whatever
works)
- x
-
- for files
-
permission to execute its contents (e.g.
./file
works) - for directories
-
permission to access its contents (e.g.
directory/whatever
works)
Every file has these permissions for 3 classes of users, stored as a nine-bit number; from high to low order, those bits are
- u
- owning user may read/write/execute
- g
- members of owning group may read/write/execute
- o
- others may read/write/execute
ls -l
includes the nine permission bits in letter form: a subset of rwxrwxrwx
(e.g. rw-rw----
means the owner and all users in the owning
group have r and w permissions, but not x permission; and other users
have no permissions). Commands that change these often use octal
(base-8) representation of the number (e.g. 660 for
rw-rw----
).
Using chmod
The most commonly used permission tool is chmod
, used as
chmod [permission] file
. As noted in man chmod
, the
permission argument can be either letters or octal
chmod 644 file
means “change the permission bits to exactly 6448 = 1101001002 = rw-r–r–chmod ug+rw file
meansadd r and w permissions for the owning user and the owning group
2.1 Defaults: the
umask
When you make a new file, its gets all permissions except a few; the
omitted few are specified by the umask
. A special command,
umask
, can display (and change) these, either in octal or
letter format.
On the department machines, if you run umask
you’ll see
0022
. That means that new files get permission
0755
: a nine-bit ~0022
. What that actually
looks like can be see by adding the symbolic flag: umask -S
shows u=rwx,g=rx,o=rx
.
2.2 setuid, setgid, and sticky
File permissions in POSIX-compatible systems also have three more permission bits which we recommend not using because of their potential dangers.
- setuid
-
- executable file
-
If executable
xyxxy
is owned bymst3k
and hassetuid
permissions, then whentj1a
runs./xyxxy
, the program runs asmst3k
, not astj1a
. This is often used by OS-supplied programs likesudo
that require more permissions than the user running them would normally have.There are many ways in which naively setting an executable program setuid is likely to create a major security vulnerability. Code that would be perfectly safe in other sensitive programs can be dangerous in setuid programs because of the extraordinary control an attacker has over the setuid program’s environment. Even the expertly-maintained programs like sudo have made subtle but very serious mistakes.
- non-executable file
- does nothing
- directory
- does nothing on most POSIX systems
- setgid
-
- executable file
- like setuid, but with group, not user. This can be a security vulnerability and should not be used except when absolutely necessary.
- non-executable file
- does nothing
- directory
- when a new file is created in the directory, it inherits the directory’s group instead of the creating user’s group. This can be a security vulnerability and should not be used unless you are sure you know what you are doing.
- sticky
-
- file
- does nothing in most POSIX systems
- directory
-
the files inside it can only be removed or renamed by the owner of the
file, owner of the directory (but
root
is always allowed).
If you use a four-digital octal with chmod
, these
permissions will be the first octal digit. Sticky may sometimes be worth
setting; we recommend never using the other two.
3 Access Control Lists
Sometimes we need more fine-grained control than the three-way user-group-other distinction. This is provided using more general access control lists, or ACLs; they are a list of user+permission pairs associated with each file. Unlike the simpler POSIX permission bits, they can include settings for much more than a single user or group. Every OS I’ve ever used has ACL support, though actual use of them is relatively uncommon; the standard system works in most cases.
The command getfacl file
shows the full permission information for a file. The command
setfacl
creates and modifies entries in the permissions
list. There are many ways of doing this, as man setfacl
shows, but three examples will suffice for most common cases:
setfacl -m u:mst3k:rx
: thism
odifiesu
sermst3k
’s permissions to ber
andx
setfacl -m g:lab_fall2019:r
: thism
odifiesg
rouplab_fall2019
’s permissions to ber
only (now
orx
permission)setfacl -x u:mst3k
: this removes theu
sermst3k
’s entry from the permission list, somst3k
will be handled like any other user.
While ACLs are not commonly needed, they are a safe way of handling cases where they are needed.
4 Executable text files
What does it mean for a file to be executable? On POSIX, there are two main cases where this is sensible:
If the file is an executable binary (typically an ELF executable), then being executable means the loader will agree to give it memory and jump to its starting code.
If the file is a plain text file, then being executable means
check for a shebang1 line.
A
shebang
is a line of the form#!/path/to/program
(or sometimes#!/usr/bin/env program
). One common shebang is#!/bin/bash
. If a filegloop.sh
begins#!/bin/bash
and is executable, then running./gloop.sh
is equivalent to running/bin/bash ./gloop.sh
A quine is a program that, when run, displays its own contents. The following file is a quine, provided it is executable:
#!/bin/cat
So is the following:
#!/bin/cat
Quines are interesting to create in many languages.
But if you use shebangs, they are trivial to create
using the interpreter "cat."
”shebang” comes from the colloqial name of the first two characters:
#
is ”hash” and!
is ”bang”. ”Hashbang” was shortened to ”shbang,” with a vowel added for readability. You can still sometimes hear ”hashbang” used to mean the#!
itself, as in ”a shebang begins with a hashbang, then path to the interpreter.”↩︎