Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

Section 8.11Changing User IDs and Group IDs 257


Figure8.18 summarizes the various ways these three user IDs can be changed.

exec setuid(uid)
set-user-ID bit offset-user-ID bit on superuser unprivileged user
ID

real user ID unchanged unchanged set touid unchanged
effective user ID unchanged set from user ID of set touid set touid
program file
saved set-user ID copied from effective set touid unchanged
user ID

copied from effective
user ID

Figure 8.18Ways to change the three user IDs

Note that we can obtain only the current value of the real user ID and the effective user
ID with the functionsgetuidandgeteuidfrom Section 8.2.We have no portable way
to obtain the current value of the saved set-user-ID.

FreeBSD 8.0 and LINUX 3.2.0 provide thegetresuidandgetresgidfunctions, which can
be used to get the saved set-user-ID and saved set-group-ID, respectively.

setreuidandsetregidFunctions


Historically,BSD supported the swapping of the real user ID and the effective user ID
with thesetreuidfunction.
#include <unistd.h>
int setreuid(uid_truid,uid_teuid);
int setregid(gid_trgid,gid_tegid);
Both return: 0 if OK,−1 on error

We can supply a value of−1for any of the arguments to indicate that the corresponding
ID should remain unchanged.
The rule is simple: an unprivileged user can always swap between the real user ID
and the effective user ID. This allows a set-user-ID program to swap to the user ’s
normal permissions and swap back again later for set-user-ID operations. When the
saved set-user-ID featurewas introduced with POSIX.1, the rule was enhanced to also
allow an unprivileged user to set its effective user ID to its saved set-user-ID.

Bothsetreuidandsetregidareincluded in the XSI option in POSIX.1. As such, all UNIX
System implementations areexpected to provide support for them.

4.3BSD didn’t have the saved set-user-ID featuredescribed earlier; it usedsetreuidand
setregidinstead. This allowed an unprivileged user to swap back and forth between the
two values. Be aware, however,that when programs that used this featurespawned a shell,
they had to set the real user ID to the normal user ID beforetheexec.Ifthey didn’t do this,
the real user ID could be privileged (from the swap done bysetreuid)and the shell process
could callsetreuidto swap the two and assume the permissions of the moreprivileged user.
As a defensive programming measure to solve this problem, programs set both the real user ID
and the effective user ID to the normal user ID beforethe call toexecin the child.
Free download pdf