I conclude my discussion of Advanced Linux Programming by summarizing Chapter 10 of ALP. In this chapter, we take an introductory look at Linux security through the use of its users and and groups mechanism. This article is intentionally brief, primarily because Linux, more or less, is POSIX compliant and behaves similarly to other POSIX-like systems.
Users and Groups
Each Linux user is assigned a unique number, called a user ID or UID. When you login using a username, the system converts the username internally to a user ID. As a result, it’s entirely possible to have more than one username that refers to the same user. To share resources among multiple users, Linux provides the concept of groups. Like a UID, a group is also a unique number, called a group ID, or GID. Every group can contain multiple user IDs, and a single user can be a member of multiple groups. Groups cannot have subgroups. You can use the id command to view information the user and groups that you belong to.
The Superuser
The superuser has a user ID of 0, and is usually named root. This account can basically do anything, and should be well guarded. In particular, programs running as root must be written very carefully.
Process User IDs and Process Group IDs
Users and groups also reveal themselves when working with processes. Every process has an associated user ID and a group ID. Thus, when we say that a user performs an operation, we are really saying that a process with a corresponding user ID performs that operation.
If a program needs to modify user and group permissions, then it should use the uit_t and gid_t types. Even though user and group IDs are essentially integers, treat these fields as opaque handles for user and group identity.
File System Permissions
Each file has exactly one owning user and exactly one owning group. In general, when you create a file, the file is owned by the user and group of the creating process. The basic things that you can do with files are read, write, and execute. There are some nuances involving directories and their behavior, but it’s not worth discussing them here.
Sticky Bits
In addition to read, write, and execute permissions, there is a magic bit called the sticky bit. It applies only to directories. A directory that has the sticky bit set allows you to delete a file only if you are the owner of that file. A few directories, such as /tmp, have the stick bit set.
Real and Effective IDs
Processes aren’t really as simple as I made them out to be earlier. Every process actually hast wo user IDs. An effective user ID and a real user ID. Most of the time, the kernel only checks the effective ID. This is done using the geteuid and getegid functions. A user without root priveleges can only perform the operations with effective and real IDs:
- set its effective user ID to be the same as its real user ID
- set its real user ID to be the same as its effective user ID
- swap the two user IDs
Programs like login use real and effective IDs to transfer control from one username to another.
Setuid Programs
There exists a special class of setuid programs. When a setuid program is run, the effective user ID of the process will that of the file’s owner rather than the effective user ID of the process that performed the exec call. To use setuid, use chmod +s on the command line, or the S_ISUID flag if calling chmod programmatically.
Authenticating Users
If you writing a program that requires authentication, it’s typically best to allow the system administrator to decide what kind of authentication mechanism he or she will use. Consequently, Linux uses the pluggable authentication module, or PAM to authenticate their users as a system administrator sees fit. Thus, always use PAM if developing an application that requires authentication.