Revision / Modified: Apr. 21, 2002
Author: Tom Berger
Original documents:
http://www.mandrakeuser.org/docs/basics/bpermis.html
http://www.mandrakeuser.org/docs/basics/bpermis2.html
Linux knows users by their accounts. In order to use your system, you have to tell it who you are (i.e. which account you want access to) by 'logging in'. Having done that you will be taken to your account's home directory ('/home/account'), where you can do pretty much what you want.
Each UNIX system has one 'human' account already built-in, and that's the 'root' account. The 'root' account is special in several ways: its home directory is '/root' and whoever is 'root' has total control over the system.
The basic idea behind this scheme is to allow separating the daily use of
an operating system from system administration. Among other things this
prevents an error made during normal use of the operating system to have any
severe impact on the operating system itself.
It also allows for different users on the same system. These additional users
do not have to be human: system services often have accounts of their own, so
that they don't have to be run via the 'root' account. This way a
mis-configured system service is prevented from having a major impact on the
operating system itself, too.
Now, how does the operating system determines who is allowed to do what? This is where permissions kick in.
Each file on a UNIX system has a permission setting, represented by the first ten characters in a file listing and the ownership names:
ls -l file
-rw-rw-r-- (...) owner group (...) file
Everything in UNIX is managed via files, even access to devices (via the device files in '/dev') like printers, modems, sound cards etc. If you do not have the permission on a file which represents a device, you can't use that device.
The first concept of permissions is ownership. You either own a file or a directory you have created or that has been handed over to you by using the 'chown' command (short for 'change owner', more on this command later). If you own a file, you can do whatever you want with it, usually.
But often more than one account needs access to a file or device. Changing the ownership of this file every time someone else needs access to it would be very tedious to say the least. This is why ownership is not only provided for single accounts but also for groups. Groups are defined in '/etc/group', an entry in this file looks like this:
group_name:x:group_ID:group_members
To see a list of groups your current account is a member of, use the command
groups
So, if you are member of a group and that group has permissions on a file, you can do something with that file, even if you are not its owner.
An average UNIX system has some 60.000 files and more. A majority of them has to to accessible in some way by all the users on a system. One way to achieve this could be to create an 'catch-all' group which would unite all the accounts on a system and assign all the files in question to this group. But since permissions do not only decide who has access to a file, but also what kind of access, such a group would defeat the purpose of the system: there are many cases in which members of a certain group need more rights on a file, but others need limited access to this file, too. This is the rationale behind the others 'group'. Permissions on a file given to this particular group are granted for all accounts on a system. Have a look at the example again:
ls -l file
-rw-rw-r-- (...) owner group (...) file
Characters 2-4 ('rw-') describe the permissions of the owner, characters 5-7 ('rw-') describe the permissions of the owner group, and characters 8-10 describe the permissions of everyone else on that file.
Let's move on from the 'who' part of permissions to the 'what' part. There's pretty much you can do with (or to) a file: you can read it, change it, delete it or - in some cases - execute it. Permissions decide which of these actions can be taken, too. This is the concept of accessibility.
Permissions on access can be granted in three ways: permission to read
(marked with 'r'), permission to write and delete (marked with 'w') and
permission to execute (marked with 'x'). In the above example the owner and
the owner group have the permissions to read and change / delete the file.
Everyone else might read the file, but is not allowed to change its
contents.
No one may execute this file. In contrast to operating systems like Windows
9x, a file must not only contain executable content (either binary or script)
but it must also have the execution bit set. This allows to exclude accounts
from running the file or program, usually for system security reasons. Even
'root' can't execute files without the execution bit, but he or she can make
every file executable. Of course, if this file doesn't contain executable
content, you still won't be able to execute it, regardless of the execution
bit.
Directories also feature permissions. Due to their nature, the permission bits have a slightly different meaning: 'r-x' means being able to list directory contents and to make this directory the working directory. 'rwx' means being allowed to put into or remove files from that directory. Every other combination of permissions will not allow you to access this directory.
(Notice that with the introduction of the Mandrake Security Tools (MSEC) in ML 7, default permissions on files may differ widely depending on the overall security level chosen during installation or later using 'DrakConf'.)
It is a distinguishing mark of the Unix/Linux concept of computing to
manage all input/output operations via files. If you send a file to
your printer for example, you in fact send it to the file '/dev/lp0'. If you
are connected to net via a modem all data is written and read from
'/dev/ttyS0' (or S1/S2/S3).
The upshot is that either you or the program you execute need permission to
read and write that file. Without this, it won't work. The same applies to
directories: you can't run a program which resides in a directory you don't
have access to or which needs write access to a directory you don't have write
access to. Many configuration problems are simply due to wrong permissions.
Checking permissions is an important step in troubleshooting.
Now you might say that since you are the only user on your machine, 'why
fiddling around with all this permissions stuff, I just stay root, so I am
allowed to do everything'.
This is precisely the reason why you shouldn't do that. A single
wrong root command can blow your system to pieces, whereas as a simple user
you just can't break anything vitally important. Especially if you
are new to Linux you really should use this mechanism to protect yourself
from your errors.
But there is even more to that:
Most programs you start run with the permissions of the user that started
them. So if you started a program as a normal user and it runs berserk you can
normally kill it easily and it can't do any real damage because it has no
rights to do so. Now imagine the same with a program with root privileges... I
think you see the point.
The execute permission on a file indeed makes this file executable. Many files of script languages like Perl or even simple shell scripts rely on this. If you've downloaded a script and it just won't run, check if the execution bit has been set (see next chapter).
Programs can run with a different user id (UID). Some programs require root privileges even if they are started by a normal user (like the X server via the Xwrapper in '/usr/X11R6/bin'), such programs are indicated by an 's':
-rws--x--x 1 root root [...] /usr/X11R6/bin/Xwrapper*
(the asterisk sign '*' tells you that it is an executable file).
However such programs pose a security threat since they allow crackers to gain root access to a box using so-called overflow exploits. Therefore it is advisable to keep the number of such programs as small as possible and have an eye on security alerts. Notice that Linux won't execute SUID shell scripts.
Confused? :) Well, maybe things will get somewhat clearer with real life examples.
A very good example is the 'slocate' package. If you've got that package installed, open a terminal and type:
ls -l /usr/bin/updatedb
That's the program for updating the '(s)locate' database. You should get something like:
-rwxr-xr-x 1 root slocate [...] /usr/bin/updatedb*
The first nine characters describe the access rights (the first '-' denotes the file type):
Owner | Group | Others = rwx | r-x | r-x
Remember: 'r' stands for 'read', 'w' for write, and 'x' for execute. '-' means 'not set' and therefore no right. The order of rights is always 'rwx'. So this string decodes to:
Now you need to know who is the user (owner) of this file and to which group it belongs to. You'll find this information right after the inode number (1):
root slocate
Owner is root, name of the group is 'slocate'.
Too easy so far? Right so. If you try to execute this program as a normal user, you get:
slocate: You are not authorized to create a default slocate database!
The slocate database is in '/var/lib/slocate'. Let's have a look:
ls -l /var/lib/
drwxr-x--- 2 root slocate [...] slocate/
The rights on this directory look somewhat different:
(Remember: In regard to directories the read and execute permission belong
together, i.e. you must have both rights to be allowed to enter a
directory!).
Since you are not 'root', you can't run 'updatedb': you lack the
right to change content in '/var/lib/slocate'.
Now you might wonder: "If I don't have access to the slocate database, how
comes I can run 'locate' as a normal user? It surely needs
access to this database as well!" That's correct.
If you run ls -l /usr/bin/locate, you will get something like this:
-rwxr-sr-x 1 root slocate [...] /usr/bin/locate*
Note the 's' that replaces the 'x' in the column of the group rights. This
denotes another important mechanism you might have already heard of earlier:
the setUID/setGID mechanism. This mechanism allows users to execute a program
with a different User or Group ID.
Every account and group has an associated unique ID number, since the
operating system prefers dealing with numbers instead of names. You use names
and the system translates that into numbers. You don't have to worry about
those, I just mention them here to explain where 'setUID' and 'setGID' come
from. If you are really curious, run
id
But if you run 'locate' the 'setGID' ('set Group ID') bit on
the 'slocate' executable makes the system think you are a member of the group
'slocate' and thus grants you read access to the database in
'/var/lib/slocate'.
The same happens with programs which run 'setUID' ('set User ID'), usually
'setuid root', like the aforementioned 'Xwrapper':
-rws--x--x 1 root root [...] /usr/X11R6/bin/Xwrapper*
The 'Xwrapper' tricks the operating system into thinking that you are 'root' when you start X. The advantage here is that this program allows you to run X and applications on X without having to be root (see Introducing Processes).
Remember: Permissions encompass two concepts, ownership and accessibility. Therefore you have two ways of influencing permissions: changing the ownership with the command 'chown' (CHange OWNer) or changing the accessibility with the command 'chmod' (CHange MODus).
'chown' is a fairly simple command:
chown tom:users test.txt
changes the ownership of the file 'test.txt' to owner 'tom' and group 'users'. You can only 'chown' files which you are owning (only 'root' can 'chown' files and directories which are not owned by him). If you just want to change the owner group, use 'chgrp'. You can do this 'recursively' (i.e. for every subdirectory and the files contained therein) by appending the '-R' option:
chown -R tom:users docs
sets the ownership of all files and directories in the directory 'docs' to owner tom, group users.
'chmod' is somewhat more difficult to handle. There are three groups: user, groups and others. Take the first letters: u, g, o. And there are three rights: read, write, execute (rwx). 'chmod's syntax goes like this (simplified):
chmod [ugo] [+-] [rwx] file
Let's say you want to grant (+) the 'read' right (r) to others (o) on the file 'test.txt'. This would be done like this:
chmod o+r file.txt
You want to rip (-) the owner group (g) of the right to execute (x) the program '/usr/bin/runme':
chmod g-x /usr/bin/runme
(Most likely you have to be 'root' for this...).
You want to deny (-) everyone access (rwx) to the directory 'secure' except to
its owner:
chmod go-rwx secure
'chmod' knows some more useful switches, one of which is 'a' (for 'all'). Thus
chmod a+r test.txt
would grant 'read' rights to the user, the owner group and others.
Another one is the 's' switch for setting the UID or GID:
chmod a+x,u+s file
will set 'file' to 'setUID root' and executable by everyone.
Like 'chown', you can run 'chmod' recursively using
the '-R' option (capital 'R'!). But read the warning
below!
'chmod' also accepts defining rights by a octal triplet: '4' means 'read', '2' means 'write and '1' 'execute'. If one of these is not granted, its value becomes '0'. A leading fourth cipher may set 'setuid' ('4'), 'setgid' ('2') or the 'sticky bit' ('1'):
chmod 750 file
sets the owner right on [file] to read + write + execute (4+2+1=7), the group right to read + execute (4+0+1=5), everyone else has no rights at all (0+0+0=0).
Is there a difference between those two methods? Yes. The first method
sets rights relative, the second absolute.
Example:
ls -l some.txt
-rw-r----- (...) some.txt
Now assume you want to grant 'others' the 'read' right to this file. With the first method, you'd do
chmod o+r some.txt
and you get
-rw-r--r-- (...) some.txtWith the second method, you get a different result when applying the same:
chmod 444 some.txt
-r--r--r-- (...) some.txt
The first method leaves the 'write' right of the owner untouched. When using the second method, you always have to specify the absolute permissions for owner, group and others to get the desired result, in this case
chmod 644 some.txt
It might be better you concentrate on one method to avoid mixups.
Handle permissions with care! They are an integral part of Linux' security concept and may cause you some trouble if applied thoughtlessly. Some examples:
chmod -R a-x text. This is a very popular one. You have copied a directory called 'text' from a MS Windows partition. Due to discrepancies in file handling all the files in this directory have the execution bit set (x). "No problem" you think and execute this command. Next time you want to switch into this directory, you just get
bash: cd: text: Permission denied
You 'su' to the root account and try again:
bash: cd: text: Permission denied
What the ...? Well, you did not only remove the execution bit from the files in the 'text' directory but also from the directory itself! Which means that no one - even 'root' - is allowed to go into this directory anymore! Just set the execution bit on the directory again:
chmod ug+x test
If you have a directory structure which contains files you want to strip recursively of the execution bit, but want to prevent 'chmod' from changing the directory bits, too, you will need something like this:
find . -type f -exec chmod a-x {} \;
This will find all normal text files ('-type f') and run ('-exec') 'chmod a-x' on them.
chmod a+rw /dev/.... A popular 'trick' to circumvent collisions with permissions set on device files. Generally one must be very careful in granting rights to the 'others' group. To this group belongs everyone, may he be a legal guest on your box or a filthy intruder! There is usually something wrong a program's configuration if you feel the urge to do this step. If there is absolutely no other way, it is far better to proceed like this:
1) 'su' to 'root'. Run chmod g+rw,o-rwx on the offending
device file.
2) Run chgrp group on the same file.
3) Add the user to the corresponding group entry in '/etc/group'.
The same goes for setUID root programs. If you feel you must set a program 'uid root', proceed like I have outlined in the article on PPP.
Notice that changing the permissions on device files is likely to either not work at all or to only have temporary effect, either due to devfs or to PAM.
Executing 'chown' before 'chmod'. This is a bad idea because 'chmod' reverts any changes made by 'chown'. 'chmod' sets 'user' and 'group' of the file corresponding to the GID and UID of the person who ran 'chmod'. So run 'chmod' first and then 'chown'!