Access permissions and PAM
Permissions and ownership - why?
If you can't access some of the files on your very own Linux system, it's usually because of misconfigured file access permissions. If you are the only user on your Linux box, you may be wondering what's the point of having all these permissions (or lack thereof) that restrict your access to your very own penguin OS. However, before pulling your hair off, you must keep in mind Linux is designed to be a multi-user environment. In an environment with more than one users, it is crucial to have a secure system for deciding which files are yours and who can fiddle with them.
Even if you're the only user on an ordinary desktop system, file permissions help keeping your important files safe, both from outsiders and your own mistakes. :)
Understanding file ownership
Every file on your Linux system, including directories, is owned by a specific user and group. Therefore, file permissions are defined separately for users, groups, and others.
User: The username of the person who owns the file. By default, the user who creates the file will become its owner.
Group: The usergroup that owns the file. All users who belong into the group that owns the file will have the same access permissions to the file. This is useful if, for example, you have a project that requires a bunch of different users to be able to access certain files, while others can't. In that case, you'll add all the users into the same group, make sure the required files are owned by that group, and set the file's group permissions accordingly.
Other: A user who isn't the owner of the file and doesn't belong in the same group the file does. In other words, if you set a permission for the "other" category, it will affect everyone else by default. For this reason, people often talk about setting the "world" permission bit when they mean setting the permissions for "other."
Understanding file permissions
There are three types of access permissions on Linux: read, write, and execute. These permissions are defined separately for the file's owner, group and all other users.
Read permission. On a regular file, the read permission bit means the file can be opened and read. On a directory, the read permission means you can list the contents of the directory.
Write permission. On a regular file, this means you can modify the file, aka write new data to the file. In the case of a directory, the write permission means you can add, remove, and rename files in the directory. This means that if a file has the write permission bit, you are allowed to modify the file's contents, but you're allowed to rename or delete the file only if the permissions of the file's directory allow you to do so.
Execute permission. In the case of a regular file, this means you can execute the file as a program or a shell script. On a directory, the execute permission (also called the "search bit") allows you to access files in the directory and enter it, with the cd
command, for example. However, note that although the execute bit lets you enter the directory, you're not allowed to list its contents, unless you also have the read permissions to that directory.
How to view file permissions
You can view the access permissions of a file by doing the long directory listing with the ls -l
command. This is what a long directory listing might look like:
me@puter: /home/writers$ ls -l
total 17
drwxr-xr-x 3 nana writers 80 2005-09-20 21:37 dir
-rw-r----- 1 nana writers 8187 2005-09-19 13:35 file
-rwxr-xr-x 1 nana writers 10348 2005-07-17 20:31 otherfile
What does the output of ls -l
mean? The very first column, the one that looks like a bunch of mumbo jumbo, shows the file type and permissions. The second column shows the number of links (directory entries that refer to the file), the third one shows the owner of the file, and the fourth one shows the group the file belongs to. The other columns show the file's size in bytes, date and time of last modification, and the filename.
The first column, the one that shows the file's permissions and looks like mumbo jumbo, is organized into four separate groups, although it certainly doesn't look very organized.
The first group consists of only one character, and it shows the file's type. For example, d
means a directory and -
means a normal file, so if you take a look at our example output, you'll notice dir
is a directory, while file
and otherfile
are regular files.
The first character can be any of these:
d = directory
- = regular file
l = symbolic link
s = Unix domain socket
p = named pipe
c = character device file
b = block device file
The next nine characters show the file's permissions, divided into three groups, each consisting of three characters. The first group of three characters shows the read, write, and execute permissions for user, the owner of the file. The next group shows the read, write, and execute permissions for the group of the file. Similarly, the last group of three characters shows the permissions for other, everyone else. In each group, the first character means the read permission, the second one write permission, and the third one execute permission.
The characters are pretty easy to remember.
r = read permission
w = write permission
x = execute permission
- = no permission
What does this mean in practice? Let's have an example. Remember the imaginary directory listing we did at the beginning? The output looked like this:
drwxr-xr-x 3 nana writers 80 2005-09-20 21:37 dir
-rw-r----- 1 nana writers 8187 2005-09-19 13:35 file
-rwxr-xr-x 1 nana writers 10348 2005-07-17 20:31 otherfile
As we already noticed, dir
is a directory, because the first column begins with a d
. The owner of this directory is user nana
and the group owner is writers
. The first three characters, rwx
, indicate the directory's owner, nana
in this case, has full access to the directory. The user nana
is able to access, view, and modify the files in that directory. The next three characters, r-x
, indicate that all users belonging to group writers
have read and execute permissions to the directory. They can change into the directory, execute files, and view its contents. However, because they don't have write permissions, they can't make any changes to the directory content. Finally, the last three characters, r-x
, indicate that all the users who are not nana
or don't belong into group writers
, have read and execute permissions in the directory.
How about file
? Because the first column begins with a -
, the file is a regular file, owned by user nana
and group writers
, just like the directory in our example. The first three characters, rw-
, indicate the owner has read and write access to the file. According to the next three characters, r--
, the users belonging to group writers
can view the file but not modify or execute it. The final three characters, ---
, indicate no one else has any access to the file.
Similarly, you can see otherfile
is a regular file and its owner has full access to it, while everyone else can read and execute the file but not modify it.
How to set file permissions - symbolic mode
You can set file permissions with the chmod
command. Both the root user and the file's owner can set file permissions. chmod
has two modes, symbolic and numeric.
The symbolic mode is pretty easy to remember. First, you decide if you set permissions for the user (u), the group (g), others (o), or all of the three (a). Then, you either add a permission (+), remove it (-), or wipe out the previous permissions and add a new one (=). Next, you decide if you set the read permission (r), write permission (w), or execute permission (x). Last, you'll tell chmod
which file's permissions you want to change.
Let's have a couple of examples. Suppose we have a regular file called testfile
, and the file has full access permissions for all the groups (long directory listing would show -rwxrwxrwx
as the file's permissions).
Wipe out all the permissions but add read permission for everybody:
$ chmod a=r testfile
After the command, the file's permissions would be -r--r--r--
Add execute permissions for group:
$ chmod g+x testfile
Now, the file's permissions would be -r--r-xr--
Add both write and execute permissions for the file's owner. Note how you can set more than one permission at the same time:
$ chmod u+wx testfile
After this, the file permissions will be -rwxr-xr--
Remove the execute permission from both the file's owner and group. Note, again, how you can set them both at once:
$ chmod ug-x testfile
Now, the permissions are -rw-r--r--
As a summary, have a look at this quick reference for setting file permissions in symbolic mode:
Which user? | |
u | user/owner |
g | group |
o | other |
a | all |
What to do? | |
+ | add this permission |
- | remove this permission |
= | set exactly this permission |
Which permissions? | |
r | read |
w | write |
x | execute |
How to set file permissions - numeric mode
The other mode in which chmod
can be used is the numeric mode. In the numeric mode, the file permissions aren't represented by characters. Instead, they are represented by a three-digit octal number.
4 = read (r)
2 = write (w)
1 = execute (x)
0 = no permission (-)
To get the permission bits you want, you add up the numbers accordingly. For example, the rwx permissions would be 4+2+1=7, rx would be 4+1=5, and rw would be 4+2=6. Because you set separate permissions for the owner, group, and others, you'll need a three-digit number representing the permissions of all these groups.
Let's have an example.
$ chmod 755 testfile
This would change the testfile
's permissions to -rwxr-xr-x
. The owner would have full read, write, and execute permissions (7=4+2+1), the group would have read and execute permissions (5=4+1), and the world would have the read and execute permissions as well.
Let's have another example:
$ chmod 640 testfile
In this case, testfile
's permissions would be -rw-r-----
. The owner would have read and write permissions (6=4+2), the group would have read permissions only (4), and the others wouldn't have any access permissions (0).
The numeric mode may not be as straightforward as the symbolic mode, but with the numeric mode, you can more quickly and efficiently set the file permissions. This quick reference for setting file permissions in numeric mode might help:
Which number? | |
0 | --- |
1 | --x |
2 | -w- |
3 | -wx |
4 | r-- |
5 | r-x |
6 | rw- |
7 | rwx |
PAM
Linux Pluggable Authentication Modules (PAM) provide dynamic authorization for applications and services in a Linux system. Linux PAM is evolved from the Unix Pluggable Authentication Modules architecture.
There are four groups for independent management:
- Account modules check that the specified account is a valid authentication target under current conditions. This may include conditions like account expiration, time of day, and that the user has access to the requested service.
- Authentication modules verify the user's identity, for example by requesting and checking a password or other secret. They may also pass authentication information on to other systems like a keyring.
- Password modules are responsible for updating passwords, and are generally coupled to modules employed in the authentication step. They may also be used to enforce strong passwords.
- Session modules define actions that are performed at the beginning and end of sessions. A session starts after the user has successfully authenticated.
Pluggable authentication modules are at the core of user authentication in any modern linux distribution.
Why
Back in the good old days of linux, if a program, such as su, passwd, login, or xlock, needed to authenticate a user, it would simply read the necessary information from /etc/passwd. If it needed to change the users' password, it would simply edit /etc/passwd. This simple but clumsy method presented numerous problems for system administrators and application developers. As MD5 and shadow passwords became increasingly popular, each program requiring user authentication had to know how to get the proper information when dealing with a number of different schemes. If you wanted to change your user authentication scheme, all these programs had to be recompiled. PAM eliminates this mess by enabling programs to transparently authenticate users, regardless of how user information is stored.
What
Quoting from the Linux-PAM System Administrator's Guide: "It is the purpose of the Linux-PAM project to separate the development of privilege granting software from the development of secure and appropriate authentication schemes. This is accomplished by providing a library of functions that an application may use to request that a user be authenticated." With PAM, it doesn't matter whether your password is stored in /etc/passwd or on a server in Hong Kong. When a program needs to authenticate a user, PAM provides a library containing the functions for the proper authentication scheme. Because this library is loaded dynamically, changing authentication schemes can be done by simply editing a configuration file.
Flexibility is one of PAM's greatest strengths. PAM can be configured to deny certain programs the right to authenticate users, to only allow certain users to be authenticated, to warn when certain programs attempt to authenticate, or even to deprive all users of login privileges. PAM's modular design gives you complete control over how users are authenticated.
Distributions that support pam.
Nearly all popular distributions have supported PAM for some time. Here's an incomplete list of distributions that support PAM:
· Redhat since version 5.0
· Mandrake since 5.2
· Debian since version 2.1 (partial support in 2.1 -- complete support in 2.2)
· Caldera since version 1.3
· Turbolinux since version 3.6
· SuSE since version 6.2
This list is certainly incomplete and possibly inaccurate. I'd appreciate it if you sent any corrections or additions to this list to <[email protected]>.
Installing PAM
Installing PAM from scratch is long process, beyond the scope of this HOWTO. If PAM isn't installed on your system, you're probably running such an old version of your distribution that there are many other reasons to upgrade. If you really want to do it yourself, then you're certainly not the sort of person who needs any help from me. For all these reasons, I'm going to assume that you already have PAM installed.
How
Enough talk, let's dig in.
PAM configuration files
PAM configuration files are stored in the /etc/pam.d/ directory. (If you don't have /etc/pam.d/ directory, don't worry, I'll cover that in the next section) Let's go over there and take look.
~$ cd /etc/pam.d /etc/pam.d/$ ls chfn chsh login other passwd su xlock /etc/pam.d/$ |
Your system may have a few more or a few less files in this directory, depending on what's installed on your system. Whatever the details, you probably saw a file for each of the programs on your system that authenticate users. As you probably already guessed, each file contains the PAM authentication configuration for the program it's named after (except for the other file, which we'll talk about in a little bit). Let's take a look the PAM configuration file for passwd (I've condensed the file for the sake of simplicity):
/etc/pam.d/$ cat login # PAM configuration for login auth requisite pam_securetty.so auth required pam_nologin.so auth required pam_env.so auth required pam_unix.so nulok account required pam_unix.so session required pam_unix.so session optional pam_lastlog.so password required pam_unix.so nullok obscure min=4 max=8 |
Before dig into this file, I must mention a little something.
A little something
A small percentage are probably thinking, "Oh no! I don't have a /etc/pam.d directory! Your list of distributions says that my distribution includes PAM, but I can't find that directory. Without PAM, my life is empty and meaningless! What can I do?" Don't worry, all is not lost. If you know that your distribution includes PAM, but you have no /etc/pam.d/ directory, then your PAM configuration is stored in /etc/pam.conf. Rather than being spread across several files, all your PAM configuration is stored in a single file. This adds a little twist to PAM configuration, but the proper adjustments are pointed out in section 3.3.4.
Configuration syntax
PAM configuration files have the following syntax:
type control module-path module-arguments |
Using the login configuration file (see above) as an example let's take a look a the syntax for PAM configuration files:
PAM configuration tokens
type
The type token tells PAM what type of authentication is to be used for this module. Modules of the same type can be "stacked", requiring a user to meet multiple requirements to be authenticated. PAM recognizes four types:
account
· Determines whether the user is allowed to access the service, whether their passwords has expired, etc.
auth
Determines whether the user is who they claim to be, usually by a password, but perhaps by a more sophistcated means, such as biometrics.
password
Provides a mechanism for the user to change their authentication. Again, this usually their password.
session
Things that should be done before and/or after the user is authenticed. This might included things such as mounting/unmounting the user home directory, logging their login/logout, and restricting/unrestricting the services available to the user.
In the login config file, we see at least one entry for each type. Since this the program that allows user to login (hence the name :), it's understandable that it needs to access all of the different types of authentication.
control
The control token tells PAM what should be done in if authentication by this module fails. PAM recognizes four control types:
requisite
· Failure to authenticate via this module results in immediate denial of authentication.
required
· Failure also results in denial of authentication, although PAM will still call all the other modules listed for this service before denying authentication.
sufficient
If authentication by this module is successful, PAM will grant authentication, even if a previous required module failed.
optional
Whether this module succeeds or fails is only significant if it is the only module of its type for this service.
In the configuration file for login, we see nearly all of the different control types. Most of the required modules are pam_unix.so (the main authentication module), the single requisite module is pam_securetty.so (checks make sure the user is logging in on a secure console), and the only optional module is pam_lastlogin.so (the module that retrieves information on the user's most recent login).
module-path
The module-path tells PAM which module to use and (optionally) where to find it. Most configurations only contain the module's name, as is the case in our login configuration file. When this is the case, PAM looks for the modules in the default PAM module directory, normally /usr/lib/security. However, if your linux distribution conforms to the Linux Filesystem standard, PAM modules can be found in /lib/security.
module-arguments
The module-arguments are arguments to be passed to the module. Each module has its own arguments. For example, in our login configuration, the "nulok" ("null ok", argument being passed to pam_unix.so module, indicating the a blank ("null") password is acceptable ("ok").
pam.conf configuration
If your PAM configuration is stored in /etc/pam.conf rather than /etc/pam.d/, PAM configuration lines are a bit different. Rather than each service having its own configuration file, all configurations are stored in /etc/pam.conf with the service name as the first token in a configuration line. For example, the following line in /etc/pam.d/login:
auth required pam_unix.so nulok |
would become the following line in /etc/pam.conf:
login auth required pam_unix.so nulok |
Except for this minor difference, all the rest of the PAM syntax applies.