User and Rights Management

History
When comparing the historical development of Linux and Windows, we can clearly see that UNIX (ancestor of Linux) was designed for another goal than MS-DOS (ancestor of Windows).

MS-DOS was a single-user-operating-system. As it was mainly used on Personal Computers (Desktop), it was an acceptable assumption to say that everyone sitting in front of this computer may do whatever he likes to. However, as the threat of viruses and trojan increased, DOS/Windows began protecting the "system" from the "normal applications". Especially Windows NT (of which current Windows versions inherit) with it's new file system NTFS introduced some user-rights.

UNIX was designed (a decade earlier) to be a multi-user-operating-system. It was mainly used for mainframes (super-computers that had several monitors and keyboards, called terminals, attached to it), they had to protect the users from one another: one user may not destroy another's users work (without his consent). That's why all actions that could potentially alter the system (e.g. installing software), or change the state of the system (e.g. shutdown) and all direct access to devices (e.g. Hard-Disk) were restricted. Instead of disallowing what the user may not do (Windows approach), the UNIX administrators had to give permissions what they trust the user to do.

Windows NT (and 2000, XP, Vista etc.) have roots in both MS-DOS and also other multi-user operating system designs (such as VMS). At the Windows 2000 era the MS-DOS based Windows (3.1, 95, 98, ME) was merged with the more robust NT code. But in this authors opinion the multi-user design was weakened in favour of the single user (ease of use).

Least Privilege Principle
In UNIX (as in Win NT), every program runs within a user. Sometimes a user is created for a specific program (e.g. www-data is used by Apache only).


 * Every program and every user of the system should operate using the least set of privileges necessary to complete the job. (Saltzer and Schroeder, 1974)

To put it in human language: do not give out keys according to the trust you have in this person, but according to the task/responsibility this person has.

Wikipedia: Principle of least privilege

Users and Groups
UNIX (and as such, Linux) has incorporated the following user model:
 * Each user belongs to at least one group (normally it is named after the user: username 'root', groupname 'root').
 * Each user has an unique Id (uid) and a unique username (or: login name). He may have more properties (e.g. full name, adress, ...).
 * Each group as an unique Id (gid) and a unique groupname. It may have a full name, too.


 * Each program belongs to a user
 * Each resource (i.e. something the program can access) is owned by an user U AND a group G. (Even if normally the case, this user U doesn't have to belong to the group G.)

Users
A user is rather a context that a program is executed in than 1:1-identical to the real user sitting in front of the computer: The programs the user sees (windows or commandline-outputs) may or may not come from different users.

As such, special programs (i.e. most of those starting up automatically on boot-up) have their own context.

Superuser
If a user needs more privileges than were given to him, he can become another user (su) or do something in another users' stead (sudo).

There is one special user called "superuser" (uid: 0, username: "root") that has the ultimate keys. Core changes to the system cannot be done otherwise than becoming a superuser. (However, the following recipes apply for other users, too.)

Get a Superuser (su)
Who has not dreamed of becoming the boss one day? The command su asks to switch the context to the root one. Continuing the key metaphor, it is as if you go to your boss saying: "Can you give me your keys for a minute?" If you sucessfully enter his password, all your dreams can come true.

Example:

$ su www-data Password: su: Authentication failure $ su Password: $ exit $
 * 1) su www-data
 * 1) exit

Interpretation:


 * In the first line, the person request to get the user www-data.
 * The second line asks for the corresponding password.
 * The given password didn't match the password in the user database (/etc/passwd and maybe /etc/shadow, too), so the context switch failed (Authentication failure). In fact, www-data does not have any password, so it is impossible to do it this way. But wait, didn't we say, root may do anything? Let's ask the boss:
 * The person request to get root.
 * It enters the password of root.
 * The password was correct. Note that the $ transformed himself into a # in order to remind the person that he is in the boss-mode (Caution!).
 * The person, disguised as boss, asks to get www-data.
 * su realizes he is in root-context, so he does it without asking a password.
 * See the $ ! We did it, we are www-data now!
 * We'll type exit to leave the www-data-context, and again to leave the root-context.

Do as a Superuser (sudo)
Soon, UNIX developers realized that it is rather dangerous to let a program do anything that he likes (even when allowed to). So they found a more restrictive way:

Imagine, you say to your boss: "Hey boss, can you open this door for me?" Or to be more exact: "Hey boss, here is what I wanted to do, but I can't: I wanted to get me a broom, paint it red, and put it back. But I can't do it, it is locked and I don't have the keys, please do it for me." He is a very indulgent boss, you know !

Technically spoken, sudo receives a command that should be executed in another context, compares it to the list of actions that are allowed for the user that demands the action, and if OK, executes this command.

Importantly every command done through sudo is logged: an administrator can know who did what and when.

Additionally, one is less tented to execute commands in root context that could be done without it.

If you're still not convinced of the advantages of sudo, but have to use it, you can do

sudo bash

which basically does the same thing as su does.

Example:

$ sudo /root/startapache.sh Apache started. $ sudo ufw enable [sudo] password for root: Firewall is active and enabled on system startup $ sudo /etc/init.d/apache stop [...]

Interpretation:


 * The first command shows a allowed command. The program sudo looked up in /etc/sudoers where it found the folling line, so he allowed the action without demanding a password:

user ALL=(ALL) NOPASSWD:/root/startapache.sh (user: username of the person)
 * After sudo finished the permission check, he immediately runs the demanded command.
 * Then we might want to enable our Firewall. This concerns the system as a whole and as such, ufw checks if it is run in root-context.
 * Sudo finds the folling line in /etc/sudoers:

%admin ALL=(ALL) ALL
 * As the user is part of the group "admin", he is allowed to use this. He has to enter the root's password, though.
 * sudo executes ufw and gives him "enable" as parameter
 * The Firewall enables himself
 * And we are back in the context of the user.
 * If we do a second sudo request (e.g. stopping Apache), sudo remembered that we typed in a good password and does not ask again (for 5 minutes).

Groups
Users are grouped in ... well, groups. But some groups only contain one user. For example, it is current usage that the group named after the user contains no other user (which would be rather confusing, you'll admit.)

Groups are powerful tools of managing permissions. Let's say, you want some user to be able to change the files in the web server:

Example:

$ sudo addgroup webserver Adding group `webserver' (GID 1001) ... Done. $ sudo adduser user1 webserver Adding user `user1' to group `webserver' ... Adding user user1 to group webserver Done. $ sudo adduser user2 webserver Adding user `user2' to group `webserver' ... Adding user user2 to group webserver Done. $ sudo chown -R :webserver /var/www $ sudo chmod -R g+w /var/www $ ls -alF /var/www drwxrwxr-x 5 root     webserver 4.0K 2009-07-01 21:14 ./ drwxr-xr-x 16 root    root      4.0K 2009-04-27 14:00 ../ -rw-rw-r-- 1 root     webserver   45 2009-04-27 14:00 index.html

Interpretation:


 * You create a new Group "webserver"
 * add the users user1 and user2
 * and then "give" the files to this group:
 * First you change the ownership (chown) of /var/www and its containing files.
 * -R : "Recursively": Do it for this file/directory and all files/directories that are contained
 * :webserver : Do not change the user (nothing before the :), but only the group (after :)
 * /var/www : You can specify several files/directories here, separated by a space.
 * Second, give permissions (chmod) to these files:
 * -R : "Recursively", as in chown
 * g+w : To "group, give (+) (remove would be -) the write-permission (g / w explained: Files)
 * /var/www : Here follows the list of files/directories to which these permissions changes are applied
 * To check if all permissions were applied correctly, we check the content of /var/www.

Let's assume that the Webserver himself needs write access, too. (This is not the case at HTML-Websites, but CMSs like Drupal may need this.) First, let's check as which user the apache is running. Then we will apply the procedure above, changing the user of the file this time.

Example:

$ sudo /etc/init.d/apache start * Starting web server apache2 httpd (pid 2768) already running       [ OK ] $ ps aux | grep apache2 root     2768  0.0  0.3  37256  7876 ? Ss  08:50   0:00 /usr/sbin/apache2 -k start www-data 2772  0.0  0.1  37256  4044 ? S   08:50   0:00 /usr/sbin/apache2 -k start [...] user        5838  0.0  0.0   3044   876 pts/0    R+   09:40   0:00 grep --color=auto apache2 $ sudo chown -R www-data: /var/www $ ls -alF /var/www drwxrwxr.x 5 www-data www-data 4096 2009-07-01 21:14 ./ drwxr-xr-x 16 root    root     4096 2009-04-27 14:00 ../ -rw-rw-r-- 1 www-data www-data   45 2009-04-27 14:00 index.html $ sudo chown -R :webserver /var/www $ ls -alF /var/www drwxrwxr-x 5 www-data webserver 4096 2009-07-01 21:14 ./ drwxr-xr-x 16 root    root      4096 2009-04-27 14:00 ../ -rw-rw-r-- 1 www-data webserver   45 2009-04-27 14:00 index.html

Interpretation:


 * First we Make sure apache has been started. It has already been started at startup here.
 * Then we list all currently running programs (ps aux), throwing away all lines that do not contain 'apache2' (grep apache2).
 * The first line is a program run by root. This is the mother program that creates new apache2 programs (threads) when many requests arrive.
 * The second and following lines are the child programs (threads) that do the actual work of treating a website request. As the first column indicates, it is run in the context of www-data - yeah, we found the user of apache2!
 * The last line, finally, contains the currently running program of filtering the ps aux-List. At first it may be strange that this program appear here, but when you realize ps is started at the same time than grep is, you realize why the grep process may be included in the "current" list of processes (what is "current", anyway, you can't take a snapshot of the system state).
 * So we own the files and directories of /var/www to the user www-data (without changing the group). BTW, as the command don't answer anything, you can safely assume that nothing went wrong, and thus, hopefully all went right. (Silent Programming)
 * We check the folder permissions. And ooops, he changed the user group to www-data, too! Reading the manual carefully, we discover that we ought to have written chown -R www-data /var/www (without :) So actually, he said nothing because he did as he was commanded to, but not as it was meant to.
 * To fix this, we re-apply our change-group command.
 * Everthing is fine now.

Permissions and Rights
As seen in the historical section of this article, UNIX (and thus Linux) was designed for security in multi-user environments. This mainly translates file permissions, even if recently other security applications arise (Ubuntu: apparmor). The Linux kernel, i.e. the first process that is called when starting Linux, ensures that every file acces passes through his scheme of Authorization.

Files
Files in the strict sense are like a sheet of paper: they can contain data. Additionally, each file has meta-data (data about the data): when was the file last modified, how much data has it (paper: is it handwritten or typed, how thick is the paper, etc.) This meta-data depends on the filesystem.

DOS used FAT as the file system, which only has the attributes: is it readable? system? hidden? Nowadays, Windows rarely uses FAT32 anymore, NTFS is recommended (however, UNIX doesn't support NTFS so well.)

Linux uses ext3 (soon: ext4) as his file system. Some advantages over FAT32 (most of them are incorporated in NTFS, too):
 * Hard disk write access is journalled. That means that before doing the actual changes to the file, the nature of the change is written to the journal (on the disk, too) - this way, when the power suddenly ceases, the probability of corrupt files is reduced. (fsck is the equivalent to Scandisk: they check if the file system is structured as it should. In UNIX, fsck is called automatically after a defined number of days or a defined number of mounts (i.e. boot-ups))
 * Permissions are much more granular.
 * Hard disks up to 2 TB are supported (16 TB if Block size is changed to 4kB).
 * lower- and UPPER-case filenames are distinguished. There may be a file a and another file A in the same directory.
 * Hardly any restrictions to the file name (well, as long as it does not include a '/'. (Warning: In Win-UNIX mixed environnements (e.g. file shares), only a-zA-Z0-9._ should be used.) Even a file named ... is not invalid.

Unix File Naming Philosophy

 * UNIX is not extension-based. A file may have one (a.jpg is allowed), but even if it doesn't, UNIX may still know that is an image/jpeg and should thus be opened with an image viewer.
 * Executables (*.exe in Windows) don't have an extension at all. Instead, they are marked as executable. (This is a big security feature of Unix-like systems: Files that are not marked as such cannot be executed, regardless of their extension. If you download a file, you will have to mark it as executable "by hand".)
 * Batch scripts (*.bat in Windows) are executables in Linux: An executable still can be a text file. In this case, the first line is indicating the program with which this text file will be executed. Scripts (e.g. installation) often have an extension .sh (sh is an equivalent of the DOS shell.)
 * Hidden files begin with a . (dot). Hidden is not a file permission, only a naming convention: all files (and directories) beginning with a . won't normally be listed. (ls doesn't show them, ls -a does. Simarly in graphical file manager, the viewing of hidden files can be toggled on or off.)
 * Backup files end or start with a ~ (tilde)
 * Add-on Executables (win: .dll) are called .so

Unix File Permissions
(These are the most basic permissions that you'll need.)

For each file, the permissions can be specified on three levels:


 * user : The first rwx-triplet. Permissions that you get if you match the user that owns the file.
 * group : The second rwx-triplet. Permissions that you get if you are member in the group that owns the file
 * other : The third rwx-triplet. Permissions that you get if otherwise (neither user nor group applies for you.) (Also called: world, read: ANYONE.)

For each of these levels, the following permissions may be given or not:


 * read (4): read the content of a file
 * write (2): change/overwrite the content of a file
 * excecute (1): this file is a program which can be run by users

Example:

ls -alF /var/www drwxrwxrwx 5 root     root     4096 2009-07-01 21:14 ./ drwxr-xr-x 16 root    root     4096 2009-04-27 14:00 ../ -rw-r--r-- 1 www-data www-data   45 2009-04-27 14:00 index.html

Interpretation: The file index.html is owned by the user www-data (first column) and the group www-data (second column). The user www-data may write or read the file, but not execute; all others (whether in the group www-data or not) may only read the file, but not modify it. The file's permission can be called 644 (or 0644) too: read(4)+write(2) = 6.

Note: This setting (644) is recommended, or 755 if the file should be executable. Taking 777 as permissions for a file (giving all permissions to everyone) is considered as bad style, as it contradicts the UNIX philosophy above (principle of least priviledge): if several users need write access to the file, they should be added to the group the file is owned by.

Directories
As astounding as it may sound, directories may be seen as "files". Consequently, one cannot tell if /home/user/test is a directory or a file without invesigating further. (Windows users may be tempted to write /home/user/test/ in the case of a directory, which is tolerable in most cases.)

The permission model is slightly different, but the name of the attributes remain, as does the separation user/group/other.


 * read (4): list the files and directories contained in this directory
 * write (2): create/delete files or directories inside of this directory
 * excecute (1): acces a file or directory contained in this directory

Example:

ls -alF /var/www drwxrwxrwx 5 root     root     4096 2009-07-01 21:14 ./ drwxr-xr-x 16 root    root     4096 2009-04-27 14:00 ../ -rw-r--r-- 1 www-data www-data   45 2009-04-27 14:00 index.html

Interpretation:
 * The directory . (that is, the current directory /var/www) has the rights 777: everyone may create new files, delete existing ones, and realize that the file index.html exists. (It is not recommended to have directories in 777: Everyone can delete the existing index.html-File, even 'user' that is not the owner of it.)
 * The directory .. (that is, the parent directory, /var) has the normal rights 755: only the owner (root) can create & delete, all others may only list the files&directories and maybe read/change/execute existing files depending on their permissions.
 * Be aware that, unlike files, you normally don't want your directories to have 644: in this case, nobody can acces the content of the directory, so you cannot even list them.
 * If you inadvertably set your directory to 333 (no read-acces), you can acces to the files, but only if you know their names: the listing refuses to give any help.
 * If ever your FTP-Directory suddenly goes empty, check the file permissions of the seamingly empty directory - the files may still be their, invisibly.

Everything is File
Everything? Forget Windows Drive letters, the BASIC commands for the printer output and even sound: in UNIX, it is as simple as opening a file.

Most of these "special" files are grouped in the folder /dev ("devices"). Just go ahead and try it out: how did you do a listing of files?

The CD-ROM drive, to begin with, is /dev/cdrom. As some computer have several CD-ROM-drives (DVD drives included), there can be /dev/cdrom0 and /dev/cdrom1 - in this case, /dev/cdrom is the "default" drive of both, normally pointing to /dev/cdrom0 (see Symbolic Links).

Hard disks are more complex. IDE-Drives are numbered /dev/hda (first primary IDE drive), /dev/hdb (first secondary) etc. SCSI / USB-Drives correspondently /dev/sda, /dev/sdb etc. You will also see the present partitions on each disk: the first partition of the first SCSI disk is called /dev/sda1.

Now if you think, all files on the disk will be in /dev/hda1, you're not completely right: yes, you could access to the files in /dev/hda1, but on a raw byte-level view: the first byte on the disk, the second byte, the third byte ... you would have to find the position of your files yourself. The process of making these files available to the UNIX Filesystem is called mounting: mapping the content of a disk into a currently empty folder. The system disk (which may be the only one) is mounted into the "root" /. (Yes, / is a directory.) All other files cannot be mounted anymore in /, as / won't be empty anymore; they normally are mounted into a subdirectory of /mnt or /media.

Some devices are untypical ones. For example, /dev/null is a file that does nothing: you can write into it if you like, but nothing happens. /dev/random, when read, gives random characters. /dev/dsp can be written into to play sound. And the list goes on and on ...

Similar pseudo-files exist in the directory /proc. That's where Linux properties can be read and even changed. Well, if you have the permissions to do so.

Example:

$ df -h Filesystem           Size  Used Avail Use% Mounted on /dev/sda2             8.8G  6.5G  2.0G  77% / /dev/sdb1            626M   18M  577M   3% /media/usb udev                1003M  296K 1002M   1% /dev none                1003M  652K 1002M   1% /dev/shm none                1003M  204K 1003M   1% /var/run none                1003M     0 1003M   0% /var/lock none                1003M     0 1003M   0% /lib/init/rw $ echo "asdf" &> /dev/null $ echo "asdf" > /dev/tty asdf $ cat /dev/urandom ␌Pÿæ⎻Z¯#å­¿ZÝ©ER#47ÌÖUïãñ��⎼�⎻Ñ¨UÏ�í├⎻û├¼¿<Ï�¼YæXúCL¶æÿ┐ïËÅø�÷��X·�Ü�ü=BÀV®TIC®#äó1ÍWÃ�ª9·┼¾¿V'.�:çºISXÙØû�─îõ�Cèë«6┼Äõ§é µÆÜ▒�M┴������ۇ�2�4���;QV\��]◆�ڂ������Y2:Ս�-␤ �^C $ ␌▒├ /␍␊┴/┤⎼▒┼␍⎺└

Interpretation:


 * df shows the currently mounted disks. The first disk, second partition contains Linux (the first partition may contain the windows system). The second disk, first partition is available in the directory /media/usb - it actually is an USB stick which is currently connected to the system. The remaining "disks" are purely virtual, even /dev itself is a "disk" (managed by Linux itself).
 * When writing into /dev/null, well, nothing happens. Use this if you don't want to see some output in the console from commands that do produce output. (Btw, if you wonder about &>, it includes stderr, too.)
 * The Terminal itself is a pseudo-File. If I try to write characters into /dev/tty, it is shown in the current terminal.
 * Now the funniest part of it: printing random characters (/dev/urandom is even more random than /dev/random). As randomness does not have an end (the "file" continues to be read), we have to stop it manually with Ctrl+C. And not only he was beeping once in a while (like in DOS, there is an character that does the system beep), he also refuses to write normal characters after stopping: he actually changed the charset of the terminal to chinese (in any case, it is rather cryptic). The easiest way to get the normal latin characters back is to close the terminal: type 'exit' blindly.

Links
Links are used to shortcut the path to a specified file.

In Windows, a Link actually is a file that contains, among others, the path to the file. They are of limited use, namely in the start menu and on the desktop. In UNIX, these files are not named Link, but rather Shortcut or Launcher; their filename end with .desktop.

UNIX Links are more tranparent: when the content of a link is read (or written), it's not the link-file, but the linked file that is shown (or changed).

Symbolic Links
Symbolic links (or: "soft" links, symlinks) contain the path of the linked file (or directory, or device, ...), but on file system level: it is only meta-data, behaving like the linked file itself. Consequently, a soft link do not have seperate permissions or user/group ownerships. If the original file is delete, the link becomes useless (broken link, dangling link).

Example:

$ touch test $ ln -s test test-link $ ls -lF -rw-r--r-- 1 b b 0 2010-01-27 09:54 test lrwxrwxrwx 1 b b 4 2010-01-27 09:54 test-link -> test $ chmod a+x test-link $ ls -lF -rwxr-xr-x 1 b b 0 2010-01-27 09:54 test* lrwxrwxrwx 1 b b 4 2010-01-27 09:54 test-link -> test* $ ln -s /etc/hostname hostname $ cat hostname ubuntu-laptop $ rm -i hostname rm: remove symbolic link `hostname'? y $ cat hostname cat: hostname: No such file or directory $ cat /etc/hostname ubuntu-laptop

Interpretation:


 * First, we create a file called test. touch changes the last modified date of a file, creating it if it does not yet exist.
 * Then we create a symbolic link on this file.
 * The directory listing shows that the permissions of test are 644, the link itself shows a permission of 777 and the special type 'l'.
 * We try to change the permissions of the link: all should get the right to execute (chmod, see section File Permissions)
 * The directory listing shows that as the linked file has become executable for user, group and other, the link has become executable, too (* asterisk). The link does not have any permissions.
 * Then we make a symbolic link to a file that is not owned to us. /etc/hostname is a system file, owned by root:root, and only readable to the user.
 * With cat, we show the content of the file. As hostname is a link, the content of the linked file is given.
 * We delete the symbolic link. Note that the linked file still exists, we would have gotten a "Permission denied" if we tried to delete /etc/hostname. (-i: interactive mode, ask first before executing.)
 * A second cat proves that the link has been deleted,
 * a third cat shows that the original file has not been changed.

Hard Links
Hard links are even more integrated into the file system: instead of containing a path, it contains a location of the file on the hard disk. Otherwise that, they "become" the linked file: there isn't any difference between the linked file and the link file anymore.

They have an important restriction:
 * The linked file has to be a real, existing file on the same partition of the disk.

Hard links are rarely used in reality.

Example:

$ cp /etc/hostname. $ ln hostname hostname2 $ ls -lF -rw-r--r-- 2 b b 14 2010-01-27 10:26 hostname -rw-r--r-- 2 b b 14 2010-01-27 10:26 hostname2 $ chmod u-w hostname $ ln /etc/hostname hostname_orig $ ls -lF -r--r--r-- 2 b   b    14 2010-01-27 10:26 hostname -r--r--r-- 2 b   b    14 2010-01-27 10:26 hostname2 -rw-r--r-- 2 root root 12 2009-12-31 12:53 hostname_orig $ rm hostname $ cat hostname2 ubuntu-laptop

Interpretation:


 * We copy /etc/hostname to the current working directory (. dot). As the destination file name was not specified, it is called hostname, too.
 * A hardlink on this file is created and called hostname2
 * The directory listing show both files, without any distinction.
 * If the file permission is changed, it is changed at both files (because actually, they are the same).
 * You can also create a hard link on files that don't belong to you. The hardlink will still have the same owner, though.
 * If you delete a hard-link, it leaves the original file intact. But the inverse is also true: If you delete the linked file, the hard link still contains the content of the file. This can become confusing: you delete a file without increasing the free space on the hard disk.

Conclusion
Gratulations! You just completed a tutorial which hopefully made you familiar about many basic concepts of UNIX. If you didn't already, go ahead, install Linux, and play with it!

More Reading

 * More about /etc/passwd and Co:
 * More about su and sudo and file permissions :
 * File Permissions: umask :