Permissions
All this time we have been talking about finding and executing commands, but
there is one issue that I haven't mentioned. That is the concept of
permissions.
To access a file, you need to have permission to do so. If you want to read a
file, you need to have read permission. If you want to write to a file, you need
to have write permission. If you want to execute a file, you must have execute
permission.
Permissions are set on a file using the chmod command or when the file is
created (the details of which I will save for later). You can read the
permissions on a file by using either the l command or
ls -l. At the beginning
of each line will be ten characters, which can either be dashes or letters. The
first position is the type of the file, whether it is a regular file (-), a
directory (d), a block device
file (b), and so on. Below are some examples of
the various file types.
Image - Various file types. (interactive)
- - regular file
c - character device
b - block device
d - directory
p - named pipe
l - symbolic link
We'll get into the details of these files as we move along. If you are
curious about the format of each entry, you can look at the ls man-page.
The next nine positions are broken into three groups. Each group consists of three
characters indicating the permissions. They are, in order, read(r), write(w), and execute(x). The first
set of characters indicates what permissions
the owner of the file has. The second set of characters
indicates the permissions
for the group of that file. The last set of characters indicates
the permissions
for everyone else.
If a particular permission is not given, a dash (-) will appear here. For
example, rwx means all three permissions
have been given. In our example above,
the symbolic link
/usr/bin/vi has read, write, and execute permissions
for everyone. The device nodes
/dev/tty1 and /dev/hda1 have permissions
rw- for the owner and group, meaning only read and write, but not execute
permissions have
been given. The directory /bin has read and execute permissions
for everyone (r-x), but only the owner can write to it (rwx).
For directories, the situation is slightly different than for regular files.
If you do not have read permission on a directory, you cannot read the contents
of that directory. Also, if you do not have write permission on a directory, you
cannot write to it. This means that you cannot create a new file in that directory.
Execute permissions
on a directory mean that you can search it or list its contents. That is, if the
execution bit is not set on a directory but the read bit is, you can see what
files are in the directory but cannot execute any of the files or even change
into that directory. If you have execution permission but no read permission,
you can execute the files, change directories, but not see what is in the
files.
Write permission on a directory also has an interesting side effect. Because
you need to have write permission on a directory to create a new file, you also
need to have write permission to remove an existing file. Even if you do not
have write permission on the file itself, if you can write to the directory, you
can erase the file.
At first this sounds odd. However, remember that a directory is nothing more
than a file in a special format. If you have write permission to a
directory-file, you can remove the references to other files, thereby removing
the files themselves.
If we were to set the permissions
for all users so that they could read, write, and execute a file, the command would look
this:
You can also use symbolic permissions
to accomplish the same thing. We use the letters u, g, and o to specify the
user(owner), group, and others for this file, respectively. The
permissions are then r for read, w for write, and x for
execute. So to set the permissions so
that the owner can read and write a file, the command would look like this:
Note that in contrast to the absolute numbers, setting the permissions
symbolically is additive. So, in this case, we would just change the user's permissions
to read and write, but the others would remain unchanged. If we changed the command to this
we would be adding write permission for the user of that file. Again, the
permissions for the others would be unchanged.
To make the permissions for the group and others to be the same as for the user, we could set it like
this
which simply means "change the mode so that the permissions
for the group and others equals the user." We also could have set them all explicitly in
one command, like this
which has the effect of setting the permissions
for everyone to read and write. However, we don't need to write that much.
Combining the commands, we could have something that looks like this:
This means "set the permissions
for the user to read and write, then set the permissions
for group and others to be equal to the user."
Note that each of these changes is done in sequence. So be
careful what changes are made. For example, let's assume we have a file that is
read-only for everyone. We want to give everyone write permission for it, so we
try
This is a typo because we meant to say
go=u. The effect is that we added read permissions
for the user, but then set the permissions on the group and user to the same as others.
We might want to try adding the write permissions
like this:
This works on some systems, but not on the Linux distributions that I have
seen. According to the man-page,
this will not change those permissions where
the bits in the UMASK are set. (More on this later. See the chmod
man-page for details.)
To get around this, we use a to specify all users. Therefore,
the command would be
There are a few other
things that you can do with permissions.
For example, you can set a program to
change the UID
of the process when the program is executed. For example, some
programs need to run as root to access other files. Rather than giving the user
the root password, you can set the program so that when it is executed, the
process is run as root. This is a Set-UID, or SUID
program. If you want to run a
program with a particular group ID, you would use the SGID program with the s
option to chmod, like this
or
There are a few other special cases, but I will leave it up to
you to check out the chmod man-page
if you are interested.
When you
create a file, the access permissions
are determined by their file creation mask. This is defined by the UMASK variable
and can be set using the umask command. One thing to keep in mind is that this
is a mask. That is, it masks out
permissions rather than assigning them. If you remember, permissions
on a file can be set using the chmod command and a three-digit value. For example
explicitly sets the permissions
on the file letter.john to 600 (read and write permission for the user and nothing for
everyone else). If we create a new file, the permissions
might be 660 (read/write for user and group). This is determined by the UMASK. To understand
how the UMASK works, you need to remember that the permissions
are octal
values,
which are determined by the permissions
bits. Looking at one set of permissions
we have
bit: | 2 | 1 | 0
| value: | 4 | 2 | 1
| symbol: | r | w | x
|
which means that if the bit with value 4 is set (bit 2), the file can be
read; if the bit with value 2 is set (bit 1), the file can be written to; and if
the bit with value 1 is set (bit 0), the file can be executed. If multiple bits
are set, their values are added together. For example, if bits 2 and 1 are set
(read/write), the value is 4+2=6. Just as in the example above, if all three are
set, we have 4+2+1=7. Because there are three sets of permissions
(owner, group,
others), the permissions
are usually used in triplets, just as in the chmod
example above.
The UMASK value masks out the bits. The
permissions that each position in the UMASK masks out are the same as the file
permissions themselves. So, the left-most position masks out the owner
permission, the middle position the group, and the right most masks out all
others. If we have UMASK=007, the permissions
for owner and group are not
touched. However, for others, we have the value 7, which is obtained by setting
all bits. Because this is a mask,
all bits are unset. (The way I remember this
is that the bits are inverted. Where it is set in the UMASK, it will be unset in
the permissions,
and vice versa.)
The problem many people have is that
the umask
command does not force permissions,
but rather limits
them. For example, if we had UMASK=007, we could assume that any file created
has permissions
of 770. However, this depends on the program that is creating
the file. If the program is creating a file with permissions
777, the umask
will
mask out the last bits and the permissions
will, in fact, be 770. However, if
the program creates permissions
of 666, the last bits are still masked out.
However, the new file will have permissions
of 660, not 770.
Some programs, like the C compiler, do generate files with the execution bit
(bit 0) set. However, most do not. Therefore, setting the UMASK=007 does not
force creation of executable programs, unless the program creating the file does
itself).
Lets look at a more complicated example. Assume we have
UMASK=047. If our program creates a file with permissions
777, then our UMASK
does nothing to the first digit, but masks out the 4 from the second digit,
giving us 3. Then, because the last digit of the UMASK is 7, this masks out
everything, so the permissions
here are 0. As a result, the permissions for the
file are 730. However, if the program creates the file with permissions
666, the
resulting permissions
are 620. The easy way to figure out the effects of the
UMASK are to subtract the UMASK from the default permissions
that the program
sets. (Note that all negative values become 0.)
As I mentioned, one way
the UMASK is set is through the environment
variable
UMASK. You can change it
anytime using the umask
command. The syntax is simply
umask <new_umask>
Here the <new_umask> can either be the numeric
value (e.g., 007) or symbolic. For example, to set the umask
to 047 using the
symbolic notation, we have
umask u=,g=r,o=rwx
This has the effect
of removing no permissions
from the user, removing read permission from the
group, and removing all permissions
from others.
Being able to change the permissions on a file is often not enough. What if the
only person that should be able to change a file is not the owner? Simple! You
change the owner. This is accomplished with the chown command, which has the
general syntax:
Where "new_owner" is the name of the user account we want to sent the owner of
the file to, and "filename" is the file we want to change. In addition, you
can use chown to change not only the owner, but the group of the file as well.
This has the general syntax:
Another useful trick is the ability to set the owner and group to the same ones
as another file. This is done with the --reference= option, which sets to the
name of the file you are referencing. If you want to change just the group, you
can use the chgrp command, which has the same basic syntax as chown. Not that
both chgrp and chmod can also take the --reference= option. Further, all three
of these commands take the -R option, which recursively changes the permissions,
owner or group.
|