- The basics of file and directory protection using users and groups on Ubuntu systems,
- How users perform tasks that require system privileges on Ubuntu systems using the sudo command.
- Access Control Lists, a more powerful and modern mechanism for enabling or denying access to specific files and directories.
Managing Users, Groups, Authentication, and Advanced PermissionsThough many people install and use Ubuntu as the operating system on a truly personal computer, Linux is designed and implemented as a multiuser computer system from the group up. Even if you’re the only user of an Ubuntu system, that system still has multiple user and group accounts and runs many processes using the rights granted to those accounts. Similarly, the login process seems simple, but actually invokes several user and group checks under the hood, as do other commands that require specific permissions.
I explains how authentication works when a user logs in, which should be of interest to Ubuntu system administrators in enterprise or academic environments that may require changes to the standard authentication process to support custom authentication mechanisms. I also discuss the details of how Ubuntu handles the execution of privileged commands, which is a slight departure from how other Linux and Unix-like systems work. The final & in this section discusses ACLs, which provide fine-grained control over who can access selected files, and includes an ACL-to-earth dictionary to understand the cryptic ACL commands, their obscure output, and their motto, which seems to be, “Is that gibberish on the screen, or are you just glad to see me?”
Creating and Managing Users and Groups
Users and groups are primarily ways of granting different permissions to different individuals or sets of individuals, respectively. These permissions include
- the ability to read, write, and access specific files and directories,
- the ability to access specific devices in different ways, and
- the ability to read or write special-purpose resources such as filesystems, portions of memory, and kernel resources.
A vademecum to the Old school
Permissions come in three types:
- Read permission: Enables you to look at a file or directory. You can use cat or a text editor to see what’s in a file that has read permission. You also can copy this type of a file. Read permission for a directory enables you to list the directory’s contents.
- Write permission: Enables you to make changes to a file. Even if you can write (change) a file, you can’t necessarily delete it or rename it; for those actions, you must be able to write in the directory in which the file resides. If you have write permission in a directory, you can create new files in the directory and delete files from it.
- Execute permission: Enables you to run the program contained in the file. The program can be a real program or a shell script. If the file doesn’t contain a program, execute permission doesn’t do you much good and can provoke the shell to complain bitterly as it tries (from its rather dim point of view) to make sense of your file. For a directory, execute permission enables you to open files in the directory and use cd to get to the directory to make it your working directory.
$id uid=1000(harrykar) gid=1000(harrykar) groups=4(adm),20(dialout),24(cdrom),46(plugdev),106(lpadmin),121(admin),122(sambashare),123(vboxusers),1000(harrykar)
Groups usually indicate the kind of work you do. UNIX uses groups to give a bunch of people the same permissions to use a set of files. All the people who work on a particular project are usually in the same group so that they can look at and perhaps change each other’s files.
If you are part of the accounting department, for example (it’s a dirty job, but someone has to do it), you and the other accounting staff members may need read, write, and execute access to basically the same files. People in other departments should not have the same access to accounting programs and data. The system administrator probably made a group called something like acctg and put all you accounting boys and girls in it.In Linux and BSD, you can be in several groups at a time, which is handy if you’re working on several projects. To find out what groups you’re in, type groups:
$ groups harrykar adm dialout cdrom plugdev lpadmin admin sambashare vboxusersEvery file and directory has an owner and a group owner. The owner is usually the person who made the file or directory, although the owner can sometimes change the ownership of the file to someone else. The group owner is usually the group to which the owner belongs, although the owner can change a file’s group owner to another group. If you use Linux or System V, you can change who owns a file with the chown command.
To see who can do what to a file, use the ls command with the -l option. Type this line:
$ ls -l myfile -rw-r--r-- 1 margy staff 335 Jan 22 13:23 myfileIf you don’t specify a filename (in this case, myfile), UNIX lists all the files in the directory, which is often more useful. For every file, this listing shows all the following information:
- Whether it’s a file, symbolic link, or directory, other. The first character in the line is a hyphen (-) if it’s a file, an l if it’s a symbolic link, and a d if it’s a directory.
- Whether the owner can read, write, or execute it (as shown by the next three characters, 2 through 4, on the line). The first character is an r if the owner has read permission or a hyphen (-) if not. The second character is a w if the owner has write permission or a hyphen (-) if not. The third character is an x (or sometimes an s) if the owner has execute permission or a hyphen (-) if not.
- Whether the members of the group owner can read, write, or execute the file or directory (as indicated by the next three characters, 5 through 7). An r, w, or x appears if that permission is granted; a hyphen (-) appears if that permission is not granted.
- Whether everyone else can read, write, or execute the file or directory (as indicated by the next three characters, 8 through 10). An r, w, or x appears if that permission is granted; a hyphen (-) appears if that permission is not granted.
- The link count, that is, how many links (names) this file has. For directories, this number is the number of subdirectories the directory contains plus 2.
- The owner of the file or directory.
- The group to which the file or directory belongs (group owner).
- The size of the file in bytes (characters).
- The date and time the file was last modified.
- The filename — at last!
Sometimes permissions are written another way, however: with numbers. Only UNIX programmers could have thought of this method. (It’s an example of lazy typists at their finest.) Numbered permissions are sometimes called absolute permissions (perhaps because they are absolutely impossible to remember).
All this makes sense if you think in binary (base 2). Think of every permission digit as a three digit binary number, like 010 (that’s binary for 2). The first digit is 1 if you have read permission, or 0 if you don’t. The second digit is 1 if you have write permission, or 0 if you don’t. The third digit is 1 if you have read permission, or 0 if you don’t. So, the permission digit 6, which is 110 in binary, means that you can read and write, but not execute.
When permissions are expressed as a number, it’s a three-digit number. The first digit is the owner’s permissions, the second digit is the group’s permissions, and the third digit is everyone else’s permissions. Every octal digit is a number from 0 to 7. Table below lists what the digits mean:
Digit PermissionsIf you own a file or directory, you can change its permissions. You use the chmod (for change mode) command to do it. You tell chmod the name of the file or directory to change and the new permissions you want the file to have for yourself (the owner), your group, and everyone else. You can either type the numerical absolute permissions (such as 440) or use letters. To use letters to type the new permissions, you use a cryptic collection of letters and symbols that consists of the following:
1 Execute only
2 Write only
3 Write and execute
4 Read only
5 Read and execute
6 Read and write
7 Read, write, and execute
- Whose permissions you are changing: u for user (the file’s owner), g for the group, o for other (everyone else), or a for all three.
- If the permission should be on or off: + (on, yes, OK) or - (off, no, don’t let them).
- The type of permission you’re dealing with: r for read, w for write, and x for execute.
$ chmod a+r announcements
This line says that the user or owner, the group, and everyone else can read the file. To not let anyone except the user or owner change the file, type:
$ chmod go-w announcements
You can also use numeric (absolute) permissions with chmod. To let the user or owner and associated group read or change the file, type:
$ chmod 660 announcements
This line sets the owner permission to 6 (read and write), the group permission to 6 too, and everyone else’s permission to 0 (can’t do anything).
You can change the permissions for a directory in exactly the same way you do for a file. Keep in mind that read, write, and execute mean somewhat different things for a directory.
When someone gives you a file, he usually copies it to your home directory. As far as UNIX is concerned, the person who copied the file is still the file’s owner. In Linux and System V, you can change the ownership of a file you own by using the chown command. (BSD users have to get the system manager’s help to change a file’s owner.) You tell chown the new owner for the file and the filename or filenames whose ownership you are changing, as shown in this example:
$ chown john chapter6This command changes the ownership of the file named chapter6 to john.
Keep in mind that only you can give away files you own; if you put a file in someone else’s directory, it’s polite to chown the file to that user.Another way to change the owner of a file is to make a copy of the file.
Suppose that Fred puts a file in your home directory, and he still owns it. You can’t use chown to change the ownership because only the owner can do that (we have a chicken-before-the-egg problem here). You can get ownership of a file if you copy the file. When you copy a file, you own the new copy. Then delete the original.
If you own a file or directory, you can change the group that can access it. The chgrp command enables you to change the name of the group associated with the file, as shown in this example:
$ chgrp acctg billing.listThis command changes the group associated with the file billing.list to the group called acctg.
Go back to new order
Ubuntu provides a convenient graphical tool for creating users, creating groups, and adding users to groups. Select the System ➪ Administration ➪ Users and Groups menu entry to execute this tool. After you supply your password, a dialog displays.
Ubuntu also provides command-line tools for quick user and group creation, modification, and removal. For more information about these tools, see the online reference information for the:
- adduser or useradd
- groupdel and
commands. I prefer to use the graphical Users and Groups tool when creating single users to take advantage of capabilities such as its default privilege settings and associated group memberships. The command-line tools are quite useful in scripts, but they are also well documented. One tip, though — when you’re using these commands to add users to existing groups, either use the adduser command (adduser user-name group-name) or make sure that you specify the -a option when using the usermod command (usermod -a -G group-name user-name). Forgetting to use the -a option with usermod will make the specified user-name a member of group-name and only that group — it will remove user-name from all other groups. I can personally attest to the fact that it is painful to remember and add back all of the other group memberships that most desktop users require.In the Users Settings window you can see the list of users and the buttons Add user, Properties, Delete and Manage Groups. For information about using the Users and Groups tool beyond what is discussed in the next few &s, see its online manual, which you can access at any time by clicking Help on any panel of the main Users and Groups dialog.
Creating New Users
To add a new user using the Users and Groups tool, click Add User to display the New User Account Editor dialog. In Account and Contact Information tabs only the Username and Password fields are mandatory on this dialogs, but you should generally provide as much information as possible when creating a user account — you may not be the only administrator of the system that you’re working on, so you should be kind to your fellow sysadmins who may one day wonder, “Who is this person?”. But its most interesting capability is the ability to associate a specific profile with that user.
Each of these profiles specifies things such as:A profile (not the same thing as the Bash'es .profile file) is a complete group of environment and privilege settings that are used when a new user is created.The standard profiles provided by the Users and Groups tool are named Desktop User (as default), Unprivileged, and Administrator.
- the devices that a user has access to,
- basic user capabilities, and
- the default groups that the user belongs to.
This tab displays the default privileges associated with a standard, unprivileged, administrator Ubuntu user. As you can see from this tab, all privileges and capabilities are enabled for a desktop user with the exception of the ability to execute system administration tasks.
After populating the fields of the 2 dialogs, click the Advanced tab to display the dialog. This dialog enables you to define some basic settings for the new account that you’re creating, such as the way in which a user’s home directory is constructed (/home/username), the user’s default login group (the same as the username), and how the user’s UID is derived (the first available UID in the range that is specified).The ability to associate several settings with a specific type of user is convenient for home users, where the basic profiles provided with Ubuntu installation are probably sufficient. However, the ability to create your own profiles can be very handy in enterprise or academic environments where you may want to create large numbers of users with similar capabilities.
The Users and Group tool also enables you to customize privileges on a per-user basis, using the User Privileges tab.
Once you have customized the account settings for the user account that you are creating, click OK on the main User Account Editor dialog to create the new account. The User Account Editor dialog closes, all system files (such as /etc/passwd, /etc/group, and /etc/shadow) are updated, and the new account is added to the list in the main Users and Groups dialog.
Managing Existing Users
In addition to simplifying the creation of new accounts, the tool also simplifies updating (or deleting) an existing account. To update or delete an existing account, start the Users and Groups tool by selecting the System ➪ Administration ➪ Users and Groups menu entry to execute this tool. After supplying your password, the dialog displays.
The most common administrative task done after an account has been created is to add that account to other groups or remove it from groups of which it is currently a member. This is not done by modifying the settings for the account using the dialogs described in this section, but is done using the procedures described later ---in the section entitled “Managing Existing Groups.”--
To modify or delete an existing account, scroll through the list of available accounts and select the account that you want to update or delete. Selecting the name of an existing account activates the Properties and Delete buttons.
To delete the selected account, click Delete. The Users and Groups tool displays a dialog that requests confirmation that you actually want to delete the account, and which also explains that deleting an account just removes the entries for that user from the password, group, and shadow files — it does not remove any files and directories that are associated with the user, such as the user’s home directory. To delete the selected user, click Delete in the dialog. To return to the Users and Groups tool without deleting the account, click Cancel. This also deselects the account that you had selected in the Users and Groups tool.
To modify an existing account, click Properties. This displays essentially the same dialogs as those used by the User Account Editor in the previous section, with a few differences:
- All dialogs are now titled “account "username" Properties” rather than “User Account Editor.”
- Fields that cannot be edited, such as the username and user ID (in Advanced tab), are disabled.
- You cannot change the profile associated with this account, because the profile is only used to provide default settings during account creation.
Creating New Groups
Creating a new system group is usually done as a part of the installation process for any software that requires a group that does not yet exist on your Ubuntu system. System groups is the term used to refer to groups that are created to support a specific software subsystem or application, such as groups that control access to printers, databases, and various types of hardware. On (Ubuntu) Linux, the group IDs of system groups are less than 1000.
You may want to create your own groups to do things like identify project members, to limit access to selected directories to a group, or to use a group to limit the people who can execute selected binaries.
Ubuntu’s Users and Groups tool provides a graphical interface to simplify both group creation and group management (the latter is discussed in the next section). To start this tool, select the System ➪ Administration ➪ Users and Groups menu entry. After supplying your password, the dialog displays. To access the group-oriented portions of this tool, click the Manage Groups tab, which displays a dialog.
To create a new group, click Add Group. The dialog displays. Enter the name of the new group that you want to create in the Group name box. Next, you can optionally modify the group ID associated with this group, which you may want to do in NFS file-sharing environments that do not use NIS. At this point, you can also add selected users to the group that you are creating by clicking their names in the Group Members list and clicking Add to add them to the list of Group members for the new group. If you change your mind about adding a specific user to your new group, simply deselect their name in the Group members list and click Remove to remove them from the list.
Once you are finished changing settings and adding members to your new group, click OK to create that group and return to the Groups tab of the Users and Groups application. If you are finished creating or modifying groups, you can click OK to exit the application.
Managing Existing Groups
In addition to simplifying the creation of new groups, the Users and Groups tool also simplifies adding and removing users from those groups. To update groups memberships, start the Users and Groups tool by selecting the System ➪ Administration ➪ Users and Groups menu entry to execute this tool. After supplying your password, the dialog displays as usual. Click the Manage Groups tab to display the dialog. In this dialog, click the name of the group that you want to add or remove users from and click Properties. This displays the dialog.
As you can see, this dialog is essentially identical to the settings dialog that is provided when you create a new group, down to the fact that you can change its name and group ID. However, its primary purpose is to enable you to add and remove group members.
You should rarely, if ever, use the group settings dialog to change group IDs. Changing the group ID in this dialog changes the entry for this group in the file /etc/group, but does not change the group ID of any files that may happen to already be owned by that group. This could prevent any per-group protections that are already in use from working correctly, preventing users that should be authorized from accessing files or directories associated with their group.
To add a user to an existing group, select that user’s username in the scrollable list at the left of the dialog. Selecting a user in this list activates the Add button, which you can click to add that user to the current group. Similarly, to remove a user from an existing group, select that user’s username in the scrollable list of group member at the right of the dialog. Selecting a user in this list activates the Remove button, which you can click to remove that user from the current group.
Any membership, name or group ID changes that you make in the dialog are not written to the /etc/group file (and updated in the /etc/passwd file, if necessary) until you click OK. You can click Cancel at any time to discard your changes. Clicking either of these buttons closes the group settings dialog and returns you to Manage Groups portion of the main Users and Groups dialog. Once you have finished making any changes to group memberships or other properties, click OK to close the Users and Groups tool.
PAMs and the Linux Authentication Process
Many different Linux and Unix applications require authentication or special privileges of one type or another to access special devices, files, or to start processes as a specific user and group. In the early days of Linux/Unix, each authentication-aware application was compiled with hardwired information about the authentication mechanism that it required. Changing or enhancing a system’s authentication mechanism therefore required that all such applications be updated and recompiled, which is tedious at best even if you have the source code for all of the relevant applications on your system. To resolve this problem, the folks at Sun Microsystems developed the idea of Pluggable Authentication Modules (PAMs), which provide a flexible and dynamic mechanism for authenticating any application or service that uses them. This model has since been adopted by most Linux and Unix-like operating systems, including Ubuntu Linux. Applications or services compiled with the Linux-PAM library use text-format configuration files to identify and describe their authentication requirements and the specific shared library modules used to implement them. The PAM model lets you modify the authentication requirements of existing applications by simply adding entries to the PAM configuration file that is used by a specific application or service. Applications that use PAMs are typically referred to as PAM-aware applications, and PAMs are usually simply referred to as PAM modules.
PAMs satisfy different parts of the authentication requirements for PAM-aware applications, much like reusable code and libraries do for applications in general. For example, a PAM-aware version of the login program can invoke several PAMs that check things such as whether the user logging in as root is on a terminal listed as a secure terminal, whether users are allowed to log in on the system at the moment, and other similar, authentication requirements. Because PAMs are shared library modules, a PAM-aware version of the ssh command can reuse the same “are users allowed to log in on the system now” PAM as the PAM-
aware version of login, but then apply other rules that are more relevant to ssh than to login.
The files that describe the sequence of PAMs associated with specific applications or services are located in the directory /etc/pam.d. The shared-library PAM modules themselves are stored in the directory /lib/security. In older PAM implementations, the PAM modules used by all applications on a system were defined in a central configuration file, /etc/pam.conf. This file is still used, but only as a fall-back if no PAM configuration file for a specific application is found in /etc/pam.d.
Many different PAM libraries are available in the Ubuntu repositories, some of which are installed by default and many that are associated with specific authentication mechanisms such as LDAP or Kerberos. Searching the repository for packages that match the string “libpam” and extracting the names of unique package names shows that there are (currently) 51 PAM-related packages, as the following example shows:
$ apt-file search libpam | sed -e 's;:.*;;' | grep libpam | grep -v dev | sort | uniq
apt-file search libpam | sed -e 's;:.*;;' | grep libpam | grep -v dev | sort | uniq |wc -lThe PAM modules used by specific, nonstandard authentication mechanisms are identified as requirements for the packages that provide the applications and daemons associated with those authentication mechanisms, and are therefore only installed when those authentication mechanisms are installed.
PAM Configuration Files for Applications and Services
- The PAM configuration files in /etc/pam.d/ have the same name as the PAM-aware application or service that they are associated with, and define the sequence of PAM modules invoked, in order, during the authentication and validation process for that application or service.
- In addition to PAM rules and related statements, the files in /etc/pam.d/ can contain blank lines (which are ignored) and comments — any characters on a line that follow the traditional hash mark (#) are interpreted as a comment.
- Each noncomment line in one of the files in /etc/pam.d is either an @include statement that includes (inserts) the contents of another PAM definition file at this point, or is an actual PAM rule for how a specific PAM module is used as part of the authentication process for the associated application or service. Included files are used to simplify PAM configuration files, enabling a common set of PAM rules to be included by other PAM configuration files.
- Each PAM rule can consist of four fields separated by white space, the first three of which are mandatory. These fields have the following meaning and content:
module-type: The type of PAM module defined on that line. A module’s type defines how a specific PAM module is used during the authentication process. Valid values are the following:
auth: Identifies modules that verify user identity or that system requirements have been met. Common system requirements are that a service can be started at the current time (for example, that /etc/nologin does not exist when a user is trying to log in), that an acceptable device is being used (the device is listed in the file /etc/securetty), that the user is already the root user, and so on.
account: Identifies modules that verify if the user can authenticate based on system requirements such as having a valid account that is able to log in at the current time (based on per-account policies, not general system constraints), has access to the requested application or service, and so on.
password: Identifies modules that verify that a user can authenticate to the system.
session: Identifies modules associated with tasks that must be done before the associated service or application is activated, or just before the termination of that service or application. Modules of this type typically perform system functions such as mounting directories, logging audit trail information, or guaranteeing that system resources are available.
control-flag: The control-flag specifies the implications of different return values from the specified PAM module. Valid values are the following:
optional: Indicates that success of the PAM module is not critical to the application or service unless this PAM is the only PAM for a specified module type. If it is, its success or failure determines the success or failure of the specified module type.
required: Indicates that success of the PAM module is mandatory for the specified module type. The failure of any PAM marked as required for a specific module type (such as all modules labeled as auth) is reported only after all required PAMs for that module type have been executed.
requisite: Indicates that failure of the PAM module immediately returns failure to the associated application or service.
sufficient: Indicates that success of the PAM module satisfies the authentication requirements of this module type. If no previous required PAM has failed, no other PAMs for the associated module type are executed after a module labeled as sufficient has succeeded.
Failure of a PAM identified as sufficient is ignored as long as any subsequent modules that are identified as required for that module type return success. If a previous required PAM has failed, the success of a PAM marked as sufficient is ignored.
module-name: The name of the PAM module associated with this entry. By default, PAM modules are located in /lib/security, but this field can also identify modules located in other directories by specifying the absolute path and filename of a PAM module.Below reside an example of the structure and organization of a PAM configuration file by examining the PAM configuration file used by the login process on Ubuntu systems.
arguments: Optional, module-specific arguments.
Example: PAMs Used by the Login Process
To see how a PAM file actually works, let’s look at an actual example. The configuration file for the PAMs used by the login program is the file /etc/pam.d/login. After removing blank lines and comments, the meaningful parts of this file on an Ubuntu system are the following:
1: auth requisite pam_securetty.so
2: auth requisite pam_nologin.so
3: session required pam_env.so readenv=1
4: @include common-auth
5: auth optional pam_group.so
6: @include common-account
7: @include common-session
8: session required pam_limits.so
9: session optional pam_lastlog.so
10: session optional pam_motd.so
11: session optional pam_mail.so standard
12: @include common-password
The actual /etc/pam.d/login file does not include line numbers (and cannot). I’ve added the line numbers to make it easier to match up the PAM entries with the explanations that follow.
Each line of this sequence of PAMs does the following:
- Invokes the PAM module pam_securetty.so to check whether the user is logged in on a secure terminal as defined in the file /etc/securetty. This check must succeed, but is not sufficient to enable a user to log in.
- Invokes the pam_nologin.so PAM module to check whether logins are allowed on the system at the current time, which is usually done by checking for the file /etc/nologin. If this file is present, the system is in a maintenance state or in the process of being shut down, and logins are disabled. This check must succeed (i.e., the file must not exist), but is not sufficient to enable a user to log in.
- Invokes the pam_env.so module, which reads a list of environment variables to set or unset from the file /etc/security/pam.conf (which does not contain any noncommented entries on an Ubuntu system, and is therefore somewhat meaningless). This PAM must succeed (i.e., be able to read its configuration file), but is not sufficient to enable a user to log in.
- Includes the contents of the file /etc/pam.d/common-auth, which provides a common set of PAM rules for system authentication. On Ubuntu 6.06 systems that use standard /etc/passwd and /etc/shadow password authentication, this file contains the following PAM rule: auth required pam_unix.so nullok_secure .This rule invokes the pam_unix.so to verify that the user has a valid entry in the /etc/shadow file. The nullok_secure argument indicates that null (empty) passwords are acceptable on this system when coming from the terminals listed in /etc/securetty. This PAM must succeed, but is not sufficient to enable a user to log in. On Ubuntu systems where other authentication mechanisms, such as LDAP or Kerberos, have been installed, this file would invoke the PAMs specific to checking authentication as required by those services.
- Invokes the pam_group.so module, which verifies that the user is a member of one or more groups and that a group with the numeric identifier for the user’s login group actually exist in the /etc/group file. This PAM module is executed but is optional — its success or failure does not matter unless it was the only auth module for the login service (which it is not), and is therefore not sufficient to enable a user to log in.
- Includes the contents of the file /etc/pam.d/common-account, which provides a common set of PAM rules for verifying that the user has a valid account on the system. On Ubuntu 6.06 systems that use standard /etc/passwd and /etc/shadow password authentication, this file contains the following PAM rule: account required pam_unix.so This rule invokes the pam_unix.so module to perform the traditional Linux authentication mechanism check that the user’s account is not marked as expired in the file /etc/shadow. This PAM must succeed, but is not sufficient to enable a user to log in. On Ubuntu systems where other authentication mechanisms, such as LDAP or Kerberos, have been installed, this file would invoke the PAMs specific to verifying accounts as required by those services.
- Includes the contents of the file /etc/pam.d/common-session, which provides a common set of PAM rules for interactive and noninteractive login sessions. On Ubuntu 6.06 systems that use standard /etc/passwd and /etc/shadow password authentication, this file contains the following PAM rules: session required pam_unix.so, session optional pam_foreground.so The first rule invokes the pam_unix.so module to create a log entry to the syslog service identifying the beginning of a user’s login session on the current system. This PAM must succeed, but is not sufficient to enable a user to log in. The second rule invokes the pam_foreground.so module to create a lock file named /var/run/console/user:tty-number for the user that is logging in. This file identifies the user as the owner of the specified console and enables software such as the GNOME Volume manager to determine if the user is logged in on the current foreground console. This PAM module is executed but is optional — its success or failure does not matter unless it was the only session module for the login service (which it is not), and is therefore not sufficient to enable a user to log in.
- Invokes the pam_limits.so module to set user limits specified in the configuration file /etc/security/limits.conf (which does not contain any non-commented entries on an Ubuntu system, and is therefore somewhat meaningless). This PAM must succeed (i.e., be able to read its configuration file), but is not sufficient to enable a user to log in.
- Invokes the pam_lastlog.so module to add an entry for the user to the file /var/log/lastlog, adding an entry when opening a session and terminating that entry when a session is closed. This PAM module is executed but is optional — its success or failure does not matter unless it was the only session module for the login service (which it is not), and is therefore not sufficient to enable a user to log in.
- Invokes the pam_motd.so module to display the contents of the /etc/motd file on the login console. This PAM module is executed but is optional — its success or failure does not matter unless it was the only session module for the login service (which it is not), and is therefore not sufficient to enable a user to log in.
- Invokes the pam_mail.so module to examine the user’s mail directory and display a message if there is any pending mail. This PAM module is executed but is optional — its success or failure does not matter unless it was the only session module for the login service (which it is not), and is therefore not sufficient to enable a user to log in.
- Includes the contents of the file /etc/pam.d/common-password, which provides a common set of PAM rules for actually checking a password. On Ubuntu 6.06 systems that use standard /etc/passwd and /etc/shadow password authentication, this file contains the following PAM rules: password required pam_unix.so nullok obscure min=4 max=8 md5 This rule invokes the pam_unix.so module to check /etc/passwd for a valid user and test the password for that user against the encrypted password entry found in the file /etc/shadow. The nullok argument indicates that null (empty) passwords are acceptable on this system. The obscure argument specifies that, when changing a password, certain checks will be performed, such as verifying that the new password is not a palindrome or rotated version of the old password, that the new password does not differ from the old one simply in terms of case, that the new password is of the length specified by the min and max arguments, and that the new password is not “too similar” to the old one. I personally have never looked at the code to see how similarity is determined, but its rules seem to be fairly obscure themselves.) This PAM must succeed, but is not sufficient by itself to enable a user to log in.
Once all of the PAMs specified in the /etc/pam.d/login file (and files that it included) have completed successfully, the login process continues, the user’s login shell is created, and any other startup actions specified in the user’s login configuration files are executed.
The PAM authentication process can be complex and conducive to migraine headaches. Even though it is a pain, security is one of any sysadmin’s most important responsibilities. You will rarely, if ever, want to muck with the PAM configuration files on a home Linux system, but you may want to modify them and should certainly understand them) when using Ubuntu in an enterprise or academic environment. If it’s any consolation, think how complex the code to implement all of this would have been without the flexibility that PAMs provide.
Configuration Files for Various PAMs
The text-format files in /etc/pam.d control the PAMs associated with each authentication-aware application or service. As mentioned when exploring the /etc/pam.d/login file in the previous section, some of these PAMs use optional configuration files to further refine their behavior. The configuration files for individual PAMs are located in the directory /etc/security. Though these files must exist, they do not need to contain any useful information — they are there in case you want to take advantage of the advanced configuration options that they provide. Here is a list of the files in this directory which are found on a default Ubuntu 6.06 system:
- access.conf: Provides fine-grained access control for logins, and is used by the pam_access.so module.
- group.conf: Provides per-session group membership control, and is used by the pam_group.so module.
- limits.conf: Provides a per-user mechanism for setting system resource limits, used by the pam_limits.so module.
- pam_env.conf: Provides a mechanism for setting environment variables to specific values, used by the pam_env.so module.
- time.conf: Provides a mechanism for imposing general or user-specific time restrictions for system services and applications, used by the pam_time.so module.
What If PAM Configuration Files Are Missing?
PAMs provide a very powerful mechanism for authenticating various applications and making sure that only the right users are running them from the right devices. It is therefore easy to see that the correct configuration of application-specific PAMs is very important. But what if an application uses PAMs and you forget to create its PAM configuration file or that file is somehow accidentally deleted? To cover these cases, the Linux-PAM library provides a default configuration file for any applications and services that do not have their own configuration files. This is the file /etc/pam.d/other, which has the following valid entries on a standard Ubuntu 6.06 system:
The contents of each of these included files was discussed earlier in this section, in the section entitled “Example: PAMs Used by the Login Process.” On Ubuntu systems, by default, the /etc/pam.d/other PAM configuration file provides a reasonable set of defaults for verifying that random applications are at least being executed by someone who can successfully log in and authenticate to the system, and guarantees that various log entries for that user are created.
Because a missing PAM configuration file generally indicates a misconfigured system or that someone has imported a PAM-aware binary without thinking things through, you can use the /etc/pam.d/other file to disallow access and impose extremely paranoid security, by changing it to contain the following entries:
auth required pam_deny.so
auth required pam_warn.so
account required pam_deny.so
account required pam_warn.so
password required pam_deny.so
password required pam_warn.so
session required pam_deny.so
session required pam_warn.so
Because subsequent required entries for a given module type are still executed, each module-type entry first executes the pam_deny.so PAM, which denies access to the requested service, and then also executes the pam_warn.so PAM, which enters a warning message to the system log. These log entries will help you identify the problem if a cranky user hasn’t already surfaced and asked why they can no longer run some obscure binary that they’ve imported.
Customizing the sudo Command on Ubuntu Systems
Ubuntu does not use the traditional root account to perform privileged operations, but instead enables users who are members of the admin group to perform all privileged operations by specifying their own passwords.
The rationale for why the root account (and it’s traditional friend, the su root command) are disabled on Ubuntu systems is discussed in the official online Ubuntu documentation. To save you a Web lookup, this is basically viewed as a security improvement, which it certainly can be. Regardless of whether you like this approach, hate it, or are simply puzzled by it, that’s the way that Ubuntu Linux works. Even if you passionately believe that this is an odd approach, you are probably not going to be able to persuade the entire Ubuntu community that it is wrong. Save your breath.
The page just mentioned explains how to change an Ubuntu system to re-enable the traditional root account. Although this is possible, I strongly suggest that you do not do this unless you have an excellent, site-specific reason to do so and are willing to have your Ubuntu system(s) be fundamentally different than all other Ubuntu systems in the known universe.This section explains the internals of the sudo command, its configuration file, and discusses how to grant administrative privileges to other users in various forms.
The following list highlights some of the ways in which the sudo command works and should be used on Ubuntu systems:
- sudo is a command that enables you to execute privileged command-line utilities, such as apt-get, aptitude, dpkg, and so on. If you want to execute graphical commands with administrative privileges on a standard Ubuntu system, you should use the gksudo command instead. The problem with running graphical applications using sudo rather than gksudo is that they may change the ownership of the .ICEauthority file in your home directory, which many KDE, GNOME, and Standard X Window system applications use to track the applications that are authorized to access a specific X Window system display. If you accidentally use sudo to start a graphical application and cannot execute subsequent graphical apps, you can remove the .ICEauthority file in your home directory using the command sudo rm .ICEauthority, and then use gksudo to start your graphical applications.
- Once you have executed the sudo or gksudo commands to run any privileged commands, your authorization is stored for 15 minutes, so that you don’t have to provide your password over and over for each privileged command that you want to execute. During this time, you must still supply the sudo or gksudo commands, but you will not be prompted for a password. After 15 minutes, using sudo or gksudo again will prompt you for a password again, and the cycle repeats.
The operation of the sudo command is controlled by the file /etc/sudoers, which is a text file that cannot be viewed by mere mortals for security reasons. To view this file, you should therefore use the visudo command to display it using a command like the following:If you are really lazy (as I have been known to be), a quick hack for using sudo is to use the sudo command to execute the bash shell, as in the command sudo bash. After supplying your password, this will give you a root shell in which you no longer have to specify the sudo or gksudo command to execute privileged operations. This is convenient, but is bad form and will generate verbal abuse from any other Ubuntu fans that see you doing this. Please be clandestine if you should ever want to do this.
$ sudo visudoThe visudo command is a special version of the vi command that ensures that only one person is modifying the /etc/sudoers file at a time. You therefore do not need to identify the file /etc/sudoers as an argument — the command knows what file it is designed to edit. You can, of course, open this file in any text editor, but you won’t get the protection against simultaneous edits that the visudo command provides.
As you will see, the /etc/sudoers file can contain blank lines (which are ignored) and comments- — any characters on a line that follow the traditional hash mark (#) are interpreted as a comment. The meaningful entries in the /etc/sudoers file on a standard Ubuntu 6.06 system are the following:
Defaults !lecture,tty_tickets,!fqdnThe first of these lines specifies settings that identify default values for how the sudo command behaves. The entries in Ubuntu’s /etc/sudoers file for the following;
root ALL=(ALL) ALL
%admin ALL=(ALL) ALL
- !lecture: Turns off the display of a short lecture explaining the use and implications for the sudo command. This would truly be a pain on an Ubuntu system, so this default behavior is disabled.
- tty_tickets: Specifies that users must authenticate on a per-tty or per-pty basis. For example, if you are logged in and running the Terminal application, this flag requires that you must separate sudo from each shell that you are running as a separate tab. In other words, the authentication information that is cached by the sudo command is only valid within the context of a specific shell.
- fqdn: Disables support for fully-qualified domain names in the /etc/sudoers file, which would otherwise enable this file to contain references to specific hosts from which users could execute privileged commands. Using fully-qualified domain names in the /etc/sudoers file would make the sudo command rely on successful DNS name lookups, which could be a bad thing for a system, such as Ubuntu, that uses sudo as its primary administrative interface if your DNS server goes down.
root ALL=(ALL) ALLThe following line states that all members of the admin group (as defined in the /etc/group file) can also do anything (i.e., run any command as root):
%admin ALL=(ALL) ALLTo enable other users to perform privileged operations, all you have to do is add them to the admin group in the /etc/group file using the Users and Groups utility or by using the sudo command to execute a command-line utility such as adduser, as in the following example:
$ sudo adduser djf adminThis command would add the user djf to the admin group and enable that user to execute any commands using sudo or gksudo.
Fixing a Broken sudo Command : Installing some versions of Ubuntu in expert mode uses the standard root mechanism, which can leave your system in a state where normal users cannot use the sudo command to execute privileged commands.
Similarly, even on a normal Ubuntu system, somehow losing the contents of your /etc/group or /etc/sudoers files can leave anyone unable to perform any privileged operation. In the latter case, you can reboot your system, press the Escape key to see the GRUB boot menus, and select the Recovery Mode entry from the GRUB menu. This will reboot your system and bring up a root shell. Once you are logged in as root on your Ubuntu system, check to see that your /etc/group file contains the admin group and that any users who you want to be able to perform administrative operations are indeed members of that group. If you do not have an admin group, you can add it using the Users and Groups tool
explained earlier or by a command-line command (as the root user) such as the following:
# addgroup --system adminNext, make sure that the /etc/sudoers file contains the entry that grants administrative privileges to the admin group, which is:
%admin ALL=(ALL) ALLIf this entry is not present in your /etc/sudoers command, you can use the visudo command to edit that file and add the entry.
After making sure that the admin group exists and is referenced in the /etc/sudoers file, all you have to do is add any user that you want to be able to run protected applications to the admin group. You can do this using the Users and Groups tool discussed earlier or from the command-line using a command
such as the following:
# adduser djf admin
This command would add the user djf to the admin group, enabling them to run privileged operations using sudo and gksudo in the future.
Using ACLs for Sophisticated File Sharing
Standard Linux/Unix file permissions are fine if you have a relatively small number of users with limited requirements for sharing and working on the same files.
Linux groups are the traditional way of enabling access to selected files and directories by multiple users. Unfortunately, using groups to control shared access requires the intervention of a system administrator every time you want to add a new user to the group or remove an existing user, as well as set up the initial shared directories.
Access Control Lists (ACLs), which are supported in most modern versions of Linux including Ubuntu Linux, eliminate this hassle by providing a fine-grained set of permissions that users can impose on their own directories, and which go far beyond the permissions and protections provided by standard Linux groups. ACLs have been around for a long time on Linux and other Unix-like systems, but
have never become as popular as they might be because of the arcane syntax of the command-line tools that are traditionally used to view and manage them. As you’ll see later, graphical tools for working with ACLs are now available, and Ubuntu users can now set and modify ACLs with ease.
Simply put, an ACL is a list of Linux users and/or groups and the access rights that they have to a specific file or directory. ACLs enable you to define totally granular permissions such as “only the users wvh and djf can write this file, but the user juser can at least read it” without requiring that you create any special-
purpose Linux groups. The key item of interest about ACLs is that you can set and manage the ACLs on any files that you own, giving random users and groups access to those files without requiring the intervention of anyone with administrative privileges. ACLs truly put you in the driver’s seat as far as file and directory access goes.
If you’re playing a round of acronym bingo, Access Control Lists (ACLs) as implemented on Linux systems today are defined by the draft Portable Operating System Interface (POSIX) standard 1003.1e, draft 17,
from the Institute of Electrical and Electronics Engineers (IEEE). This is not an official standard, but it is publicly available and has become the foundation for ACL implementations for modern operating systems such as Linux.
Here i explain how to install the commands necessary to use ACLs, other system requirements that may be associated with using ACLs on your systems, and how to use various command-line and graphical tools to examine, set, update, and remove ACLs from your files and directories. I don't discuss extended file attributes, which are often presented as a companion topic to ACLs, though they do something completely different.
Overview of Linux ACLs
Linux supports two basic types of ACLs:
- ACLs used to control access to specific files and directories
- Per-directory ACLs known as mask ACLs that define the default ACLs that are assigned to any files created within that directory
- The first field of an ACL entry is the entry type, which can be one of user (u), group (g), other (o), or mask (m).
- The second field of an ACL entry is a username, numeric UID, group name, or numeric GID, depending on the value of the first field. If this field is empty, the ACL refers to the user or group that owns the file or directory. This field is empty for ACLs of the mask and other types.
- The third field is the access permissions for this ACL. These are represented in two forms:
A standard Unix-like permissions string rwx (Read, Write, and eXecute permissions, where eXecute permissions on directories indicate the ability to search that directory). Each letter may be replaced by a - (dash), indicating that no access of that type is permitted). These three permissions must appear in this order.
When listed or stored in files, different ACL entries are separated by white space or new lines. Everything after a # character to the end of a line is a comment and is ignored.A relative symbolic form that is preceded by a + (plus) sign or a ^ (caret) symbol, much like the symbolic permissions that are designed for use with the chmod command by people who are octally challenged. In this ACL representation, the + or ^ symbols are followed by single r, w, or x permission characters, indicating that these permissions should be added to the current set for a file or directory (the plus symbol) or that these permissions should be removed from the current set (the caret) for a given file or directory.
Installing ACL Commands on Ubuntu
Special-purpose commands such as those used to create and manage ACLs aren’t installed as part of a default Ubuntu installation because, let’s face it, not everybody needs (or wants) to use ACLs. However, as with all software packages on Ubuntu, they can easily be installed using apt-get or aptitude on systems without a graphical user interface or using Synaptic on a standard Ubuntu Desktop system. The user-level commands for ACL support are located in the acl package. To install this package using apt-get or aptitude, use the commands
sudo apt-get install acl or sudo aptitude –r install acl.To install this package using Synatpic, start the Synaptic Package Manager from the System ➪ Administration menu and supply your password to start Synaptic. Once the Synaptic application starts, click Search to display the search dialog. Make sure that Description and Name are the selected items to search through, enter Access Control Lists as the string to search for, and click Search. After the search completes, scroll down in the search results until you see the acl package, right-click its name, and select Mark for Installation to select that package for installation from the pop-up menu.
After you have selected the acl package, begin another search, this time for the term ACLs. After the search completes, scroll down in the search results until you see the eiciel package, which is a graphical utility for setting and managing ACLs. Right-click its name, and select Mark for Installation to select that package for installation from the pop-up menu.
After selecting eiciel for installation, click Apply in the Synaptic toolbar to install the user-level commands necessary to set and manage Access Control Lists on your files and directories. When the installation completes, you can exit from Synaptic. Almost there!
Activating Filesystem Support for ACLs
To use ACLs to enhance the granularity of permissions on your system, any filesystems that contain files and directories with which you want to use ACLs must be mounted with ACL support. This is not done by default on Ubuntu systems, but is easy enough to change. Filesystems mounted with support for ACLs will have the acl keyword in the mount options portion of your /etc/fstab file. Because this is not enabled by default on Ubuntu systems, the entry in /etc/fstab for your filesystems will probably look something like the following:
/dev/hda1 / ext3 defaults,errors=remount-ro 0 0You can edit this file to enable ACL support when that filesystem is mounted by adding the acl keyword to the mount options for that filesystem. You can do this using your favorite text editor and a command like the following:
$ sudo emacs /etc/fstabChanging this entry to add support for ACLs would look like the following:
/dev/hda1 / ext3 defaults,acl,errors=remount-ro 0 0Updating this file only means that support for ACLs will be enabled the next time your system automatically mounts that filesystem, which is typically the next time that you reboot your system. If you want to get started using ACLs right away, you can enable ACL support in the currently mounted version of the filesystem on /dev/hda1 without rebooting your system, by executing a command such as the following, which would remount the example ext3 filesystem /dev/hda1, activating ACL support:
$ sudo mount -o remount,acl /dev/hda1Now, as they say in the Worldwide Wrestling Federation, “Get ready to ACL!”
Working with ACLs from the Command Line
As you’ll see in this $, ACLs are ugly on the command line, often being indistinguishable from typing on a broken keyboard or displaying the contents of a binary file in a terminal window. Regardless of this, it is useful to understand their command-line representation and the command-line commands used to manipulate them. If you ever need to write a shell script to perform ACL manipulation, you’ll be proud to say, “Of course I know how to use ACLs from a shell prompt.”
Overview of Command-Line Utilities for ACLs
The Linux acl package provides the following three utilities for ACL creation, modification, and examination:
- chacl: lets you change, examine, or remove user, group, mask, or other ACLs on files or directories
- getfacl: lets you examine file access control lists for files and directories
- setfacl: lets you set file and directory access control lists
Displaying Current ACLs from the Command Line
As an example of using ACLs, let’s use a directory with the following contents and permissions:
ls -alThe default ACL for this directory is the following:
drwxr-xr-x 2 wvh wvh 80 2006-06-26 04:59 .
drwxr-xr-x 106 wvh wvh 5288 2006-06-26 23:11 ..
-rw-r----- 1 wvh wvh 44032 2006-06-26 04:58 resume.xml
$ getfacl .The default ACL for the file resume.xml is the following:
# file: .
# owner: wvh
# group: wvh
$ getfacl resume.xmlThe default ACL for a file in a directory for which no default ACL has explicitly been set is derived from the default file protections associated with the user that created the file. A user’s default file protections are derived from the user’s umask.
# file: resume.xml
# owner: wvh
# group: wvh
Setting ACLs from the Command Line
There are three common ways to change the ACL of a file or directory:
- By explicitly setting it to a specific value using the setfacl command, which overwrites any existing ACL settings
- By using the setfacl command with the -m (modify) option to modify an existing ACL
- By using the chacl command to modify an existing ACL
For example, to add the user djf as someone who could read the file resume.xml, I would use a chacl (change ACL) command like the following:
$ chacl u::rw-,g::r--,o::---,u:djf:r--,m::rw- resume.xmlNo, that isn’t a typo or misprint — that’s the way that ACLs look in real life. You wanted power, didn’t you? It comes at a price. As mentioned previously, ACLs consist of three colon-separated fields that represent the permission of the user (owner of the file), group (the group ownership to the file), and others. When changing an ACL with the chacl command, you need to specify the ACL of the file, and then append the changes that you want to make to that ACL. The
u::rw-,g::r--,o::---portion of the ACL in this example is the existing ACL of the file; and the
u:djf:r--,m::rw-portion specifies the new user that I wanted to add to the ACL for that file and the effective rights mask to be used when adding that user’s ACL.
The effective rights mask is the union of all of the existing user, group, and other permissions for a file or directory. You must specify a mask when adding a new user to the ACL for a file.
Note that the name of the user that I am adding to this ACL appears between the two colons in the u portion of the ACL entry. Using the getfacl command to retrieve the ACL for my resume.xml file shows that the user djf has indeed been added to the list of people who have access to the file:
$ getfacl resume.xmlUsing the ls -al command shows that the visible, standard Unix file and directory permissions haven’t changed:
# file: resume.xml
# owner: wvh
# group: wvh
$ ls -alEven more interesting and useful than just giving specific individuals read access to files is the ability to give specific users the ability to write specific files. For example, to add the user djf as someone who could both read and write the file resume.xml, I would use a chacl command like the following:
drwxr-xr-x 2 wvh wvh 80 2006-06-26 04:59 .
drwxr-xr-x 106 wvh wvh 5288 2006-06-26 23:11 ..
-rw-r----- 1 wvh wvh 44032 2006-06-26 04:58 resume.xml
$ chacl u::rw-,g::r--,o::---,u:djf:rw-,m::rw- resume.xmlNote, again, that the name of the user that I am adding to this ACL appears between the two colons in the u portion of the ACL entry. Using the getfacl command shows that the user djf now has both read and write access to the file:
$ getfacl resume.xmlIt’s unfortunate that ACLs are so ugly, but that’s because there is a fair amount of information packed into them. You may not find it odd that typos are common when typing ACLs. Now if there were only a friendly, graphical tool for ACL control...
# file: resume.xml
# owner: wvh
# group: wvh
Working with ACLs Using Graphical Tools
There is a Santa Claus, and in this case his name is Roger Ferrer Ibanez. Roger is the primary author of the eiciel GNOME File ACL editor. What does eiciel mean? Try pronouncing it slowly with a fake French accent, and you’ll hear that it sounds like Maurice Chevalier discussing his favorite computer science topic, the ACL.
The eiciel ACL editor provides a graphical interface for setting, updating, and removing ACLs in ext2, ext3, XFS, JFS, and ReiserFS filesystems, and should work equally well with any other filesystems that support POSIX ACLs. You installed eiciel as part of the installation of your ACL software earlier, in the & entitled “Installing ACL Commands on Ubuntu.” Unfortunately, installing eiciel doesn’t also create a menu item for it, so you must initially start eiciel from any GNOME command line, such as the GNOME Terminal or an xterm window, or by creating a desktop launcher for it. You can always create your own menu item for eiciel.
If you are starting eiciel from the command line, you can supply the name of the file or directory for the ACLs you want to set or modify as a command-line argument. To open a file or directory manually, click Open in eiciel’s upper-right-hand corner, navigate to the file or directory of the ACLs you want to set or modify, and click Open to open the ACLs for that file or directory.
The top portion of the Eiciel dialog displays the current ACLs for the file or directory that you opened in eiciel. By default, the bottom half of the Eiciel dialog provides a list of all of the nonsystem users on your system. If you want to add a group to an ACL rather than a single user, select the Group radio button. To add system users and groups (i.e., those with UIDs and GIDs less than 1000), select the Also show system participants checkbox near the bottom of the Eiciel dialog. To add a specific user or group to the ACLs for the file or directory that is currently displayed in eiciel, select the name of that user or group from the list in the bottom half of the Eiciel dialog. This activates the Add button.
To add the user to the ACL, click Add. The name of that user is added to the list in the top of the Eiciel dialog, and is immediately added to the ACL for the file or directory that you are editing.
If you look closely at the ACL that I just added, you’ll note that the Execute bit is labeled as being an ineffective permission. This is because the file itself isn’t executable.
At this point, you can select the various settings for any user on the ACL displayed in the window at the top half of the Eiciel dialog. Any changes that you make to the ACL take place immediately — there is no need to explicitly save them. When you are finished using eiciel, click Quit to exit.
The eiciel editor is an excellent piece of software, and a great example of how the latest generation of Linux tools can remove much of the wizardry, typos, and barriers-to-use that are often the companions of complex command-line tools and twisted syntax. For more information about using eiciel, click Help in the Eiciel dialog to see its online manual. For information about the latest and greatest eiciel developments, see its home page. Thanks for a great piece of software, Roger!
- Ubuntu Linux Bible by William von Hagen ISBN-13: 978-0-470-03899-4