Creating, renaming, removing, opening, reading from, writing to, and executing files can only be done the operating system. As such, the OS gets to decide when to approve a request to do one of these things and when to reject it. Although not all OSs use the same system, the POSIX standard defines a set of file permissions that are commonly used.
Work with a partner to achieve the following:
dir
with a file foo
and a file baz
where you can ls
and cat
freely, but your partner finds that
ls dir
refuses to runcat dir/foo
workscat dir/baz
refuses to runsimple.sh
which can be run both by bash simple.sh
and ./simple.sh
containing bash commands that
simple_runs
simple_runs
containscat xyxxy
works but echo 'hi' >> xyxxy
does notecho hi >> xyxxy
works but cat xyxxy
does not./xyxxy
works but cat xyxxy
does not./xyxxy
works but echo hi >> xyxxy
does notThe information needed to achieve these goals is explained below. We recommend you read it in full, discussing it with a partner and asking clarifying questions of TAs as you go, then return to the tasks above.
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 except in a few special circumstances. Any 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
.
Every user can belong to any number of groups. You can find out what groups a user belongs to by running the command groups mst3k
; if you omit the user ID, 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.
Permissions are split into three kinds, with different meanings for :
cat file
works)
ls directory/
works)
echo whatnot >> file
works)
rm directory/whatever
works)
./file
works)
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
ls -l
includes the nine permission bits in letter form: a subset of rwxrwxrwx (e.g., rw-rw----
means the owner and all in the owning group have r and w permission, 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
means add r and w permissions for the owning users and the owning group
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
.
File permissions in POSIX-compatible systems also have three more permission bits which we recommend not using because of their potential dangers.
xyxxy
is owned mst3k
and has setuid
permissions, then when tj1a
runs ./xyxxy
, the program runs as mst3k
, not as tj1a
. This can be a security vulnerability and should not be used except when absolutely necessary.
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.
Sometimes we need more fine-grained control than the three-way user-group-other distinction. This is provided using access control lists, or ACLs; they are a list of user+permission pairs associated each file. 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
this m
odifies u
ser mst3k
’s permissions to be r
and x
setfacl -m g:lab_fall2019:r
this m
odifies g
roup lab_fall2019
’s permissions to be r
only (no x
or w
permission)setfacl -x u:mst3k
this removes the u
ser mst3k
’s entry from the permission list, so mst3k
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.
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 that 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 file gloop.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".↩︎