Section "User/Group IDs of a Process" moved to user/group chapter.
authorrms <rms>
Mon, 16 Mar 1992 03:55:04 +0000 (03:55 +0000)
committerrms <rms>
Mon, 16 Mar 1992 03:55:04 +0000 (03:55 +0000)
manual/=process.texinfo

index d5ab4fe..d47a91a 100644 (file)
@@ -24,7 +24,6 @@ child processes.
 * Program Termination::                How to cause a process to terminate and
                                 return status information to its parent.
 * Creating New Processes::     Running other programs.
-* User/Group IDs of a Process::        Controlling what privileges your program has.
 @end menu
 
 
@@ -332,7 +331,6 @@ The environment variables discussed in this section are the same
 environment variables that you set using the assignments and the
 @code{export} command in the shell.  Programs executed from the shell
 inherit all of the environment variables from the shell.
-@pindex getenv
 
 @cindex environment
 Standard environment variables are used for information about the user's
@@ -1465,565 +1463,3 @@ process terminate.  Just returning a bad status code with @code{return}
 would leave two processes running the original program.  Instead, the
 right behavior is for the child process to report failure to its parent
 process.  To do this, @code{exit} is called with a failure status.
-
-@node User/Group IDs of a Process
-@section User/Group IDs of a Process
-
-@cindex process ownership
-@cindex process, user ID of
-@cindex process, group ID of
-@cindex @code{setuid} program
-@cindex @code{setgid} program
-
-When the system decides whether a process can access a file, it starts
-by comparing the user and group IDs of the process with those of the
-file.
-
-Normally, a process inherits its user and group IDs from its parent
-process, but a program can change them so that it can access resources
-that wouldn't otherwise be available to it.
-
-@menu
-* Process User and Group IDs::         Defines terms and concepts.
-* Changing the User or Group ID::      Why a program might need to change
-                                        its user and/or group IDs.
-* Controlling Process Privileges::     Restrictions on how the user and
-                                        group IDs can or should be changed.
-* User and Group ID Functions::                Detailed specification of the
-                                        interface.
-* Setuid Program Example::             A detailed example.
-@end menu
-
-@node Process User and Group IDs
-@subsection Process User and Group IDs
-
-@cindex login name
-@cindex user name
-@cindex user ID
-Each user account on a computer system is identified by a @dfn{user
-name} (or @dfn{login name}) and @dfn{user ID}.  Normally, each login
-name in the database has a unique user ID, but it is possible for
-several login names to have the same user ID.
-
-@cindex group name
-@cindex group ID
-Users are classified in @dfn{groups}.  Each user name also belongs to
-one or more groups, and has one @dfn{default group}.  Users who are
-members of the same group can share resources (such as files) that are
-not accessible to users who are not a member of that group.  Each group
-has a @dfn{group name} and @dfn{group ID}.
-
-When you log in to the computer, the processes that you create are
-assigned your user ID and your default group ID.
-
-@cindex effective user ID
-@cindex real user ID
-A particular process actually has two user IDs associated with it.  The
-@dfn{real user ID} identifies the user who created the process.  The
-@dfn{effective user ID}, on the other hand, is used to determine
-permissions for accessing resources such as files.  Both the real and
-effective user ID can be changed during the lifetime of a process.
-@xref{Changing the User or Group ID}.
-
-@cindex real group ID
-@cindex effective group ID
-@cindex supplementary group IDs
-Similarly, an individual process has both @dfn{real group ID} and
-@dfn{effective group ID} attributes.  In addition, a user can belong to
-multiple groups, so a process can have @dfn{supplementary group IDs}.
-that also contribute to access permission.
-
-For details on how a process's user IDs and group IDs affect its
-permission to access files, see @ref{Access Permission}.  For
-more information about the system user and group databases,
-see @ref{System Databases}.
-
-The user ID of a process also controls permissions for sending signals
-using the @code{kill} function.  @xref{Signaling Another Process}.
-
-
-
-@node Changing the User or Group ID
-@subsection Changing the User or Group ID
-
-The most obvious situation where it is necessary for a process to change
-its user and/or group IDs is the @code{login} program.  When
-@code{login} starts running, its user ID is @code{root}.  Its job is to
-start a shell whose user and group IDs are those of the user who is
-logging in.
-
-Some ordinary user programs also need to use an effective user or group
-ID that corresponds to something other than the user who is actually
-running the program.  This permits the program to use a resource that
-wouldn't otherwise be accessible to the user.  For example, you may have
-a file that is controlled by your program but that shouldn't be read or
-modified directly by ordinary users, either because it implements some
-kind of locking protocol, or because you want to be careful to preserve
-the integrity or privacy of the information it contains.  This kind of
-restricted access can be implemented by having the program change its
-user or group ID to be the same as the owner of the resource.
-
-Thus, imagine a game program that saves scores in a file.  The game
-program itself obviously needs to be able to update this file no matter
-who is running it, but if users can write the file without going through
-the game, they can give themselves any scores they like.  Some people
-consider this undesirable; or even reprehensible.  It can be prevented
-by creating a new user ID and login name (say, @samp{games}) to own the
-scores file, and make the file writable only by this user.  Then, when
-the game program wants to update this file, it can change its effective
-user ID to be that for @samp{games}.
-
-@comment The example of phone bills was deleted by RMS because it endorses 
-@comment a way of running a computer facility that he detests.
-
-@node Controlling Process Privileges
-@subsection Controlling Process Privileges
-@cindex restrictions on @code{setuid} programs
-
-The ability to change the user ID of a process can be a source of
-unintentional privacy violations, or even intentional abuse.  Because of
-the potential for problems, there are a number of restrictions on how
-nonprivileged programs can use the facilities, and some guidelines you
-should follow in writing such programs.
-
-You can't just arbitrarily set your user ID or group ID to anything you
-want; only privileged users can do that.  Instead, the normal way for a
-program to change its user or group ID is that it has been set up in
-advance to change to a particular user or group.  This is the function
-of the suid and sgid bits.  When the suid bit of an executable file is
-set, executing that file automatically changes the effective user ID to
-the user that owns the file.  Likewise, executing a file whose sgid bit
-is set changes the effective group ID to the group of the file.
-@xref{Executing a File}.  Creating a file that changes to a particular
-user or group ID thus requires full access to that user or group ID.
-
-@xref{File Attributes}, for a more general discussion of file modes and
-accessibility.
-
-A process can always change its effective user (or group) ID back to its
-real ID.  This is often done because the program doesn't need the
-special privileges all the time.
-
-@node Reading User and Group IDs
-@subsection Reading User and Group IDs 
-
-Here are detailed descriptions of the functions for inquiring about or
-changing the user and group IDs of a process.  To use these facilities,
-you must include the header files @file{sys/types.h} and
-@file{unistd.h}.
-@pindex unistd.h
-@pindex sys/types.h
-
-@comment sys/types.h
-@comment POSIX.1
-@deftp {Data Type} uid_t
-This is an integer data type used to represent user IDs.  In the GNU
-library, this is an alias for @code{unsigned short int}.
-@end deftp
-
-@comment sys/types.h
-@comment POSIX.1
-@deftp {Data Type} gid_t
-This is an integer data type used to represent group IDs.  In the GNU
-library, this is an alias for @code{unsigned short int}.
-@end deftp
-
-@comment unistd.h
-@comment POSIX.1
-@deftypefun uid_t getuid ()
-The @code{getuid} function returns the real user ID of the process.
-@end deftypefun
-
-@comment unistd.h
-@comment POSIX.1
-@deftypefun gid_t getgid ()
-The @code{getgid} function returns the real group ID of the process.
-@end deftypefun
-
-@comment unistd.h
-@comment POSIX.1
-@deftypefun uid_t geteuid ()
-The @code{geteuid} function returns the effective user ID of the process.
-@end deftypefun
-
-@comment unistd.h
-@comment POSIX.1
-@deftypefun gid_t getegid ()
-The @code{getegid} function returns the effective group ID of the process.
-@end deftypefun
-
-@comment unistd.h
-@comment POSIX.1
-@deftypefun int getgroups (int @var{count}, gid_t *@var{groups})
-The @code{getgroups} function is used to inquire about the supplementary
-group IDs of the process.  Up to @var{count} of these group IDs are
-stored in the array @var{groups}; the return value from the function is
-the number of group IDs actually stored.  If @var{count} is smaller than
-the total number of supplementary group IDs, then @code{getgroups}
-returns a value of @code{-1} and @code{errno} is set to @code{EINVAL}.
-
-If @var{count} is zero, then @code{getgroups} just returns the total
-number of supplementary group IDs.
-
-Here's how to use @code{getgroups} to read all the supplementary group
-IDs:
-
-@example
-gid_t *
-read_all_groups ()
-@{
-  int ngroups = getgroups (0, 0);
-  gid_t *groups = (gid_t *) xmalloc (ngroups * sizeof (gid_t));
-  int val = getgroups (ngroups, groups);
-  if (val < 0)
-    return 0;
-  return groups;
-@}
-@end example
-@end deftypefun
-
-@comment unistd.h
-@comment POSIX.1
-
-@node Setting Uids
-@subsection Setting User IDs
-
-@deftypefun int setuid (@var{newuid})
-This function sets both the real and effective user ID of the process
-to @var{newuid}, provided that the process has appropriate privileges.
-
-If the process is not privileged, then @var{newuid} must either be equal
-to the real user ID or the saved user ID from the program's image file
-(but only if the implementation supports the @code{_POSIX_SAVED_IDS}
-feature).  In this case, @code{setuid} sets only the effective user ID
-and not the real user ID.
-
-The @code{setuid} function returns a value of @code{0} to indicate
-successful completion, and a value of @code{-1} to indicate an error.
-The following @code{errno} error conditions are defined for this
-function:
-
-@table @code
-@item EINVAL
-The value of the @var{newuid} argument is invalid.
-
-@item EPERM
-The process does not have the appropriate privileges; you do not
-have permission to change to the specified ID.  @xref{Controlling Process
-Privileges}.
-@end table
-@end deftypefun
-
-@comment unistd.h
-@comment BSD
-@deftypefun int setreuid (int @var{ruid}, int @var{euid})
-This function sets the real user ID of the process to @var{ruid} and
-the effective user ID to @var{euid}.
-
-The @code{setreuid} function is provided for compatibility with 4.2 BSD
-Unix, which does not support saved IDs.  You can use this function to
-swap the effective and real user IDs of the process.  (Privileged users
-can make other changes as well.)  If saved IDs are supported, you should
-use that feature instead of this function.
-
-The return value is @code{0} on success and @code{-1} on failure.
-The following @code{errno} error conditions are defined for this
-function:
-
-@table @code
-@item EPERM
-The process does not have the appropriate privileges; you do not
-have permission to change to the specified ID.  @xref{Controlling Process
-Privileges}.
-@end table
-@end deftypefun
-
-@comment unistd.h
-@comment POSIX.1
-
-@node Setting Groups
-@subsection Setting Group IDs
-
-@deftypefun int setgid (@var{newgid})
-This function sets both the real and effective group ID of the process
-to @var{newgid}, provided that the process has appropriate privileges.
-
-If the process is not privileged, then @var{newgid} must either be equal
-to the real group ID or the saved group ID from the program's image
-file.  In this case, @code{setgid} sets only the effective group ID and
-not the real group ID.
-
-The return values and error conditions for @code{setgid} are the same
-as those for @code{setuid}.
-@end deftypefun
-
-
-@comment unistd.h
-@comment BSD
-@deftypefun int setregid (int @var{rgid}, int @var{egid})
-This function sets the real group ID of the process to @var{rgid} and
-the effective group ID to @var{egid}.
-
-The @code{setregid} function is provided for compatibility with 4.2 BSD
-Unix, which does not support saved IDs.  You can use this function to
-swap the effective and real group IDs of the process.  (Privileged users
-can make other changes.)  If saved IDs are supported, you should make use 
-of that feature instead of using this function.
-
-The return values and error conditions for @code{setregid} are the same
-as those for @code{setreuid}.
-@end deftypefun
-
-The GNU system also lets privileged processes change their supplementary 
-group IDs.  To use @code{setgroups} or @code{initgroups}, your programs
-should include the header file @file{grp.h}.
-@pindex grp.h
-
-@comment grp.h
-@comment BSD
-@deftypefun int setgroups (size_t @var{count}, gid_t *@var{groups})
-This function sets the process's supplementary group IDs.  It can only
-be called from privileged processes.  The @var{count} argument specifies
-the number of group IDs in the array @var{groups}.
-
-This function returns @code{0} if successful and @code{-1} on error.
-The following @code{errno} error conditions are defined for this
-function:
-
-@table @code
-@item EPERM
-The calling process is not privileged.
-@end table
-@end deftypefun
-
-@comment grp.h
-@comment BSD
-@deftypefun int initgroups (const char *@var{user}, gid_t @var{gid})
-The @code{initgroups} function effectively calls @code{setgroups} to
-set the process's supplementary group IDs to be the normal default for
-the user name @var{user}.  The group ID @var{gid} is also included.
-@end deftypefun
-
-@node Enable/Disable Setuid
-@subsection Turning Setuid Access On and Off
-
-You can use @code{setreuid} to swap the real and effective user IDs of
-the process, as follows:
-
-@example
-setreuid (geteuid (), getuid ());
-@end example
-
-@noindent
-This special case is always allowed---it cannot fail.  A @code{setuid}
-program can use this to turn its special access on and off.  For
-example, suppose a game program has just started, and its real user ID
-is @code{jdoe} while its effective user ID is @code{games}.  In this
-state, the game can write the scores file.  If it swaps the two uids,
-the real becomes @code{games} and the effective becomes @code{jdoe}; now
-the program has only @code{jdoe} to access.  Another swap brings
-@code{games} back to the effective user ID and restores access to the
-scores file.
-
-If the system supports the saved user ID feature, you can accomplish 
-the same job with @code{setuid}.  When the game program starts, its
-real user ID is @code{jdoe}, its effective user ID is @code{games}, and
-its saved user ID is also @code{games}.  The program should record both
-user ID values once at the beginning, like this:
-
-@example
-user_user_id = getuid ();
-game_user_id = geteuid ();
-@end example
-
-Then it can turn off game file access with 
-
-@example
-setuid (user_user_id);
-@end example
-
-@noindent
-and turn it on with 
-
-@example
-setuid (game_user_id);
-@end example
-
-@noindent
-Throughout the process, the real user ID remains @code{jdoe} and the 
-saved user ID remains @code{games}.
-
-@node Setuid Program Example
-@subsection Setuid Program Example
-
-Here's an example showing how to set up a program that changes its
-effective user ID.
-
-This is part of a game program called @code{caber-toss} that
-manipulates a file @file{scores} that should be writable only by the game
-program itself.  The program assumes that its executable
-file will be installed with the set-user-ID bit set and owned by the
-same user as the @file{scores} file.  Typically, a system
-administrator will set up an account like @samp{games} for this purpose.
-
-The executable file is given mode @code{4755}, so that doing an 
-@samp{ls -l} on it produces output like:
-
-@example
--rwsr-xr-x   1 games    184422 Jul 30 15:17 caber-toss*
-@end example
-
-@noindent
-The set-user-ID bit shows up in the file modes as the @samp{s}.
-
-The scores file is given mode @code{644}, and doing an @samp{ls -l} on
-it shows:
-
-@example
--rw-r--r--  1 games           0 Jul 31 15:33 scores
-@end example
-
-Here are the parts of the program that show how to set up the changed
-user ID.  This program is conditionalized so that it makes use of the
-saved IDs feature if it is supported, and otherwise uses @code{setreuid}
-to swap the effective and real user IDs.
-
-@example
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-
-/* @r{Save the effective and real UIDs.} */
-
-uid_t euid, ruid;
-
-
-/* @r{Restore the effective UID to its original value.} */
-
-void do_setuid (void)
-@{
-  int status;
-
-#ifdef _POSIX_SAVED_IDS
-  status = setuid (euid);
-#else
-  status = setreuid (ruid, euid);
-#endif
-  if (status < 0) @{
-    fprintf (stderr, "Couldn't set uid.\n");
-    exit (status);
-    @}
-@}
-
-
-/* @r{Set the effective UID to the real UID.} */
-
-void undo_setuid (void)
-@{
-  int status;
-
-#ifdef _POSIX_SAVED_IDS
-  status = setuid (ruid);
-#else
-  status = setreuid (euid, ruid);
-#endif
-  if (status < 0) @{
-    fprintf (stderr, "Couldn't set uid.\n");
-    exit (status);
-    @}
-@}
-
-
-/* @r{Main program.} */
-
-void main (void)
-@{
-  /* @r{Save the real and effective user IDs.}  */
-  ruid = getuid ();
-  euid = geteuid ();
-  undo_setuid ();
-
-  /* @r{Do the game and record the score.}  */
-  @dots{}
-@}
-@end example
-
-Notice how the first thing the @code{main} function does is to set the
-effective user ID back to the real user ID.  This is so that any other
-file accesses that are performed while the user is playing the game use
-the real user ID for determining permissions.  Only when the program
-needs to open the scores file does it switch back to the original
-effective user ID, like this:
-
-@example
-/* @r{Record the score.} */
-
-int record_score (int score)
-@{
-  FILE *stream;
-  char *myname;
-
-  /* @r{Open the scores file.} */
-  do_setuid ();
-  stream = fopen (SCORES_FILE, "a");
-  undo_setuid ();
-
-  /* @r{Write the score to the file.} */
-  if (stream) @{
-    myname = cuserid (NULL);
-    if (score < 0)
-      fprintf (stream, "%10s: Couldn't lift the caber.\n", myname);
-    else
-      fprintf (stream, "%10s: %d feet.\n", myname, score);
-    fclose (stream);
-    return 0;
-    @}
-  else
-    return -1;
-@}
-@end example
-
-@node Tips for Setuid
-@subsection Tips for Writing Setuid Programs
-
-It is easy for setuid programs to give the user access that isn't 
-intended--in fact, if you want to avoid this, you need to be careful.
-Here are some guidelines for preventing unintended access and
-minimizing its consequences when it does occur:
-
-@itemize @bullet
-@item
-Don't have @code{setuid} programs owned by privileged accounts such as
-@samp{root} or @samp{superuser}, unless it is absolutely necessary.  If
-the resource is specific to your particular program, it's better to
-define a new, nonprivileged user ID or group ID just to manage that
-resource.
-
-@item
-Be cautious about using the @code{system} and @code{exec} functions in
-combination with changing the effective user ID.  Don't let users of
-your program execute arbitrary programs under a changed user ID.
-Executing a shell is especially bad news.  Less obviously, the
-@code{execlp} and @code{execvp} functions are a potential risk (since
-the program they execute depends on the user's @code{PATH} environment
-variable).
-
-If you must @code{exec} another program under a changed ID, specify
-an absolute file name (@pxref{File Name Resolution}) for the executable,
-and make sure that the protections on that executable and its directory
-are such that ordinary users cannot replace it with some other program.
-
-@item
-Only use the user ID controlling the resource in the part of the program
-that actually uses that resource.  When you're finished with it, restore
-the effective user ID back to the actual user's user ID.
-
-@item
-If the @code{setuid} part of your program needs to access other files
-besides the controlled resource, it should verify that the user would
-ordinarily have permission to access those files.  You can use the
-@code{access} function (@pxref{Access Permission}) to check this; it
-uses the real user and group IDs, rather than the effective IDs.
-@end itemize