Add Book to My BookshelfPurchase This Book Online

Chapter 8 - Users and Groups

UNIX Systems Programming for SVR4
David A. Curry
 Copyright © 1996 O'Reilly & Associates, Inc.

The User ID Number
Each process executing on the system has associated with it two small integers called the real user ID number and the effective user ID number. The UNIX kernel uses these numbers to determine the process' access permissions, record accounting information, and so on. The real user ID always identifies the user executing the program, and is used for accounting purposes. Only the superuser may change his real user ID, thus becoming another user. The effective user ID is used to determine a process' access permissions. Normally, the effective user ID is equal to the real user ID. However, by changing its effective user ID, a process can gain the additional access permissions associated with the new user ID. It is possible for more than one login name to be associated with the same user ID, but as far as the operating system kernel is concerned, each user ID is unique and identifies one and only one person. Thus, the only purpose of multiple login names with the same user ID is to allow different people to access the same set of privileges with different passwords.
A program uses the getuid and geteuid functions to obtain its real and effective user IDs, respectively:
    #include <sys/types.h>
    #include <unistd.h>
    uid_t getuid(void);
    uid_t geteuid(void);
Both functions simply return the associated ID.
A process can change its real and/or effective user ID in two ways. The first, which changes only the effective user ID, is to execute a program that has the set-user-id permission bit set (see Chapter 5, Files and Directories). The other way is to use the setuid and seteuid functions:
    #include <sys/types.h>
    #include <unistd.h>
    int setuid(uid_t uid);
    int seteuid(uid_t euid);
The setuid function sets the real and effective user IDs of the calling process, plus a third value called the saved user ID (see below) to the value contained in uid. The seteuid function sets the effective user ID only of the calling process to the value contained in euid. Upon successful completion, both functions return 0. If an error occurs (usually the error is “permission denied”), -1 is returned and the reason for failure is stored in the external integer errno.
The seteuid function is not available in HP-UX 10.x.
At login time, the real, effective, and saved user-ids are set to the user-id of the user responsible for the creation of the login process. When a process executes a program however, the user ID associated with that new process can change. If the file containing the program has the set-user-id bit set in its permission bits, then the effective user ID and saved user ID of the process are set to the user ID of the owner of the program file (the real user ID is not changed). With that in mind, the following four rules govern the behavior of the setuid and seteuid functions:
 1.If the effective user ID of the process calling setuid is that of the superuser, the real, effective, and saved user IDs are set to the value of uid.
 2.If the effective user ID of the process calling setuid is not that of the superuser, but uid is equal to either the real user ID or the saved user ID of the calling process, the effective user ID is set to the value of uid.
 3.If the effective user ID of the process calling seteuid is that of the superuser, the effective user ID is set to the value of euid (this allows the superuser to change only the effective user ID).
 4.If the effective user ID of the process calling seteuid is not that of the superuser, but euid is equal to either the real user ID or the saved user ID of the calling process, the effective user ID is set to the value of euid (setuid and seteuid behave identically for non-privileged processes).
The saved user ID value allows a process to alternate its effective user ID between the value obtained by executing a set-user-id program and the value of the executing user's real user ID.
Porting Notes
Berkeley-based versions of UNIX do not use the saved user ID. Instead, they provide a function for changing the real and effective user IDs:
    int setreuid(int uid, int euid);
The setreuid function differs from the saved user ID approach. It allows a process to exchange its real and effective user IDs. Although this provides the same functionality as the saved user ID feature (allowing a process to alternate between its real and effective user IDs), it is also prone to error. If a process calls setreuid to exchange its real and effective user IDs (so that its effective user ID is now its real user ID and vice-versa) and then executes a subprocess (for example, a shell), that process will run with its real user ID set to the original effective user ID. This can present a serious security problem if the programmer is not careful.

Previous SectionNext Section
Books24x7.com, Inc © 2000 –  Feedback