diff options
author | Melissa Weisshaus <melissa@gnu.org> | 1992-03-20 23:49:29 +0000 |
---|---|---|
committer | Melissa Weisshaus <melissa@gnu.org> | 1992-03-20 23:49:29 +0000 |
commit | 47e5c515a17caa87a788c62eac54bbb806442618 (patch) | |
tree | 4f6b95322fc33846528e7a29aa517aae9a7763fb /manual | |
parent | d5b56d2d8d86acf0864d2e693719159dee878ab6 (diff) | |
download | glibc-47e5c515a17caa87a788c62eac54bbb806442618.tar.gz glibc-47e5c515a17caa87a788c62eac54bbb806442618.tar.xz glibc-47e5c515a17caa87a788c62eac54bbb806442618.zip |
Initial revision
Diffstat (limited to 'manual')
-rw-r--r-- | manual/arith.texi | 464 | ||||
-rw-r--r-- | manual/users.texi | 1016 |
2 files changed, 1480 insertions, 0 deletions
diff --git a/manual/arith.texi b/manual/arith.texi new file mode 100644 index 0000000000..a0527f05e5 --- /dev/null +++ b/manual/arith.texi @@ -0,0 +1,464 @@ +@node Arithmetic +@chapter Low-Level Arithmetic Functions + +This chapter contains information about functions for doing basic +arithmetic operations, such as splitting a float into its integer and +fractional parts. These functions are declared in the header file +@file{math.h}. + +@menu +* Normalization Functions:: Hacks for radix-2 representations. +* Rounding and Remainder Functions:: Determinining the integer and + fractional parts of a float. +* Integer Division:: Functions for performing integer + division. +* Parsing of Numbers:: Functions for ``reading'' numbers + from strings. +* Predicates on Floats:: Some miscellaneous test functions. +@end menu + +@node Normalization Functions +@section Normalization Functions +@cindex normalization functions (floating-point) + +The functions described in this section are primarily provided as a way +to efficiently perform certain low-level manipulations on floating point +numbers that are represented internally using a binary radix; +see @ref{Floating-Point Representation}. These functions are required to +have equivalent behavior even if the representation does not use a radix +of 2, but of course they are unlikely to be particularly efficient in +those cases. + +@comment math.h +@comment GNU +@deftypefun double copysign (double @var{value}, double @var{sign}) +The @code{copysign} function returns a value whose absolute value is the +same as that of @var{value}, and whose sign matches that of @var{sign}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double frexp (double @var{value}, int *@var{exponent}) +The @code{frexp} function is used to normalize the number @var{value}. + +If the argument @var{value} is not zero, the return value is a +floating-point number with magnitude in the range 1/2 (inclusive) to 1 +(exclusive). The corresponding exponent is stored in the location +pointed at by @var{exponent}; the return value multiplied by 2 raised to +this exponent would equal the original number @var{value}. + +If @var{value} is zero, then both parts of the result are zero. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double ldexp (double @var{value}, int @var{exponent}) +This function returns the result of multiplying the floating-point +number @var{value} by 2 raised to the power @var{exponent}. (It can +be used to reassemble floating-point numbers that were taken apart +by @code{frexp}.) +@end deftypefun + +@c ??? Where does this come from? +@comment math.h +@comment GNU +@deftypefun double scalb (double @var{value}, int @var{exponent}) +The @code{scalb} function does the same thing as @code{ldexp}. +@end deftypefun + +@c ??? Where does this come from? +@comment math.h +@comment GNU +@deftypefun double logb (double @var{x}) +This function returns the integer part of the base-2 logarithm of +@var{x}, an integer value represented in type @code{double}. This is +the highest integer power of @code{2} contained in @var{x}. + +When @code{2} raised to this power is divided into @var{x}, it gives a +quotient between @code{1} (inclusive) and @code{2} (exclusive). + +@strong{Incomplete:} What happens if @var{x} is zero? +@end deftypefun + + +@node Rounding and Remainder Functions +@section Rounding and Remainder Functions +@cindex rounding functions +@cindex remainder functions +@cindex converting floats to integers + +The functions listed here perform operations such as rounding, +truncation, and remainder in division of floating point numbers. Some +of these functions convert floating point numbers to integer values. + +You can also convert floating-point numbers to integers simply by +casting them to @code{int}. This discards the fractional part, +effectively rounding towards zero. However, this only works if the +result can actually be represented as an @code{int}---for very large +numbers, this is impossible. The functions listed here return the +result as a @code{double} instead to get around this problem. + +@comment math.h +@comment ANSI +@deftypefun double ceil (double @var{x}) +The @code{ceil} function rounds @var{x} upwards to the nearest integer, +returning that value as a @code{double}. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double floor (double @var{x}) +The @code{ceil} function rounds @var{x} downwards to the nearest +integer, returning that value as a @code{double}. +@end deftypefun + +@comment math.h +@comment GNU +@deftypefun double rint (double @var{x}) +This function returns the integer nearest @var{x} according to the +current rounding mode. @xref{Floating-Point Parameters}, for information +about the @code{FLT_ROUNDS} macro. +@end deftypefun + +@comment math.h +@comment ANSI +@deftypefun double modf (double @var{value}, double *@var{integer_part}) +This function breaks the argument @var{value} into an integer part and a +fractional part (between @code{-1} and @code{1}, exclusive). The +integer part is stored at the location pointed at by @var{integer_part}, +and the fractional part is returned. Their sum equals @var{value}. +Each of the parts has the same sign as @var{value}, so the rounding of +the integer part is towards zero. +@end deftypefun + + +@comment math.h +@comment ANSI +@deftypefun double fmod (double @var{numerator}, double @var{denominator}) +This function computes the remainder of dividing @var{numerator} by +@var{denominator}. Specifically, the return value is +@code{@var{numerator} - @var{n} * @var{denominator}}, where @var{n} is +the quotient of @var{numerator} by @var{denominator}, rounded down to +the next lower integer. + +The result has the same sign as the @var{numerator} and has magnitude +less than the magnitude of the @var{denominator}. (Recall that the +built-in @samp{%} operator isn't defined on floating-point values.) + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EDOM +The @var{denominator} is zero. +@end table +@end deftypefun + +@comment math.h +@comment GNU +@deftypefun double drem (double @var{numerator}, double @var{denominator}) +This function returns the remainder from dividing @var{numerator} by +@var{denominator}. Specifically, the return value is @code{@var{numerator} +- @var{n} * @var{denominator}}, where @var{n} is the integer closest to +the exact quotient of @var{numerator} and @var{denominator}. The absolute +value of the result is less than or equal to one half the absolute value +of the @var{denominator}. + +The following @code{errno} error conditions are defined for this function: + +@table @code +@item EDOM +The @var{denominator} is zero. +@end table +@end deftypefun + + +@node Integer Division +@section Integer Division +@cindex integer division functions + +This section describes functions for performing integer division. These +functions are redundant in the GNU C library, since in GNU C the @samp{/} +operator always rounds towards zero. But in other C implementations, +@samp{/} may round differently with negative arguments. @code{div} and +@code{ldiv} are useful because they specify how to round the quotient. + +These functions are specified to return a result @var{r} such that +@code{@var{r}.quot*@var{denominator} + @var{r}.rem} equals +@var{numerator}. + +To use these facilities, you should include the header file +@file{stdlib.h} in your program. +@pindex stdlib.h + +@comment stdlib.h +@comment ANSI +@deftp {Data Type} div_t +This is a structure type used to hold the result returned by the @code{div} +function. It has the following members: + +@table @code +@item int quot +The quotient from the division. + +@item int rem +The remainder from the division. +@end table +@end deftp + +@comment stdlib.h +@comment ANSI +@deftypefun div_t div (int @var{numerator}, int @var{denominator}) +This function @code{div} computes the quotient and remainder from +the division of @var{numerator} by @var{denominator}, returning the +result in a structure of type @code{div_t}. + +If the result cannot be represented (as in a division by zero), the +behavior is undefined. +@end deftypefun + + +@comment stdlib.h +@comment ANSI +@deftp {Data Type} ldiv_t +This is a structure type used to hold the result returned by the @code{ldiv} +function. It has the following members: + +@table @code +@item long int quot +The quotient from the division. + +@item long int rem +The remainder from the division. +@end table + +(This is identical to the type @code{div_t} except that the components +are of type @code{long int} rather than @code{int}.) +@end deftp + +@comment stdlib.h +@comment ANSI +@deftypefun ldiv_t ldiv (long int @var{numerator}, long int @var{denominator}) +The @code{ldiv} function is similar to @code{div}, except that the +arguments are of type @code{long int} and the result is returned as a +structure of type @code{ldiv}. +@end deftypefun + + +@node Parsing of Numbers +@section Parsing of Numbers +@cindex parsing numbers (in formatted input) +@cindex converting strings to numbers +@cindex number syntax, parsing +@cindex syntax, for reading numbers + +This section describes functions for ``reading'' integer and +floating-point numbers from a string. In many cases, it is more +appropriate to use @code{sscanf} or one of the related functions; +see @ref{Formatted Input}. The syntax recognized by the formatted input +functions for the numeric conversions is exactly the same as the syntax +recognized by the functions described in this section. + +These functions are declared in @file{stdlib.h}. +@pindex stdlib.h + +@menu +* Parsing of Integers:: Functions for conversion of integer values. +* Parsing of Floats:: Functions for conversion of floating-point + values. +@end menu + +@node Parsing of Integers +@subsection Parsing of Integers + +@comment stdlib.h +@comment ANSI +@deftypefun {long int} strtol (const char *@var{string}, char **@var{tailptr}, int @var{base}) +The @code{strtol} (``string-to-long'') function converts the initial +part of @var{string} to a signed integer, which is returned as a value +of type @code{long int}. + +This function attempts to decompose @var{string} as follows: + +@itemize @bullet +@item +A (possibly empty) sequence of whitespace characters. Which characters +are whitespace is determined by the @code{isspace} function +(@pxref{Classification of Characters}). These are discarded. + +@item +An optional plus or minus sign (@samp{+} or @samp{-}). + +@item +A nonempty sequence of digits in the radix specified by @var{base}. If +@var{base} is zero, decimal radix is assumed unless the series of digits +begins with @samp{0} (specifying octal radix), or @samp{0x} or @samp{0X} +(specifying hexadecimal radix); in other words, the same syntax that is +used for integer constants in the C language is recognized. Otherwise +@var{base} must have a value between @code{2} and @code{35}. If +@var{base} is @code{16}, the digits may optionally be preceeded by +@samp{0x} or @samp{0X}. + +@item +Any remaining characters in the string. If @var{tailptr} is not a null +pointer, a pointer to this tail of the string is stored in +@code{*@var{tailptr}}. +@end itemize + +If the string is empty, contains only whitespace, or does not contain an +initial substring that has the expected syntax for an integer in the +specified @var{base}, no conversion is performed. In this case, +@code{strtol} returns a value of zero and the value returned in +@code{*@var{tailptr}} is the value of @var{string}. + +In a locale other than the standard @code{"C"} locale, this function +may recognize additional implementation-dependent syntax. + +If the string has valid syntax for an integer but the value is not +representable because of overflow, @code{strtol} returns either +@code{LONG_MAX} or @code{LONG_MIN} (@pxref{Integer Representation +Limits}), as appropriate for the sign of the value. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item ERANGE +An overflow condition was detected. +@end table +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun {unsigned long int} strtoul (const char *@var{string}, char **@var{tailptr}, int @var{base}) +The @code{strtoul} (``string-to-unsigned-long'') function is similar to +@code{strtol} except that it returns its value as an object of type +@code{unsigned long int}. The value returned in case of overflow is +@code{ULONG_MAX} (@pxref{Integer Representation Limits}). +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun {long int} atol (const char *@var{string}) +This function is similar to the @code{strtol} function with a @var{base} +argument of @code{10}, except that it need not detect overflow errors. +The @code{atol} function is provided mostly for compatibility with +existing code; using @code{strtol} is more robust. +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun int atoi (const char *@var{string}) +This function is similar to the @code{atol} function, except that +returns its value as an @code{int} rather than @code{long int}. The +@code{atoi} function is also considered obsolete; use @code{strtol} +instead. +@end deftypefun + + +@node Parsing of Floats +@subsection Parsing of Floats + +@comment stdlib.h +@comment ANSI +@deftypefun double strtod (const char *@var{string}, char **@var{tailptr}) +The @code{strtod} (``string-to-double'') function converts the initial +part of @var{string} to a floating-point number, which is returned as a +value of type @code{double}. + +This function attempts to decompose @var{string} as follows: + +@itemize @bullet +@item +A (possibly empty) sequence of whitespace characters. Which characters +are whitespace is determined by the @code{isspace} function +(@pxref{Classification of Characters}). These are discarded. + +@item +An optional plus or minus sign (@samp{+} or @samp{-}). + +@item +A nonempty sequence of digits optionally containing a decimal-point +character (@samp{.}). + +@item +An optional exponent part, consisting of a character @samp{e} or +@samp{E}, an optional sign, and a sequence of digits. + +@item +Any remaining characters in the string. If @var{tailptr} is not a null +pointer, a pointer to this tail of the string is stored in +@code{*@var{tailptr}}. +@end itemize + +If the string is empty, contains only whitespace, or does not contain an +initial substring that has the expected syntax for a floating-point +number, no conversion is performed. In this case, @code{strtod} returns +a value of zero and the value returned in @code{*@var{tailptr}} is the +value of @var{string}. + +In a locale other than the standard @code{"C"} locale, this function may +recognize additional locale-dependent syntax. + +If the string has valid syntax for a floating-point number but the value +is not representable because of overflow, @code{strtod} returns either +positive or negative @code{HUGE_VAL} (@pxref{Mathematics}), depending on +the sign of the value. Similarly, if the value is not representable +because of underflow, @code{strtod} returns zero. + +The following @code{errno} error conditions are defined for this +function: + +@table @code +@item ERANGE +An overflow or underflow condition was detected. +@end table +@end deftypefun + +@comment stdlib.h +@comment ANSI +@deftypefun double atof (const char *@var{string}) +This function is similar to the @code{strtod} function, except that it +need not detect overflow and underflow errors. The @code{atof} function +is provided mostly for compatibility with existing code; using +@code{strtod} is more robust. +@end deftypefun + +@node Predicates on Floats +@section Predicates on Floats +@cindex predicates on floats + +This section describes some miscellaneous test functions on doubles. +Prototypes for these functions appear in @file{math.h}. +@pindex math.h + +@comment math.h +@comment GNU +@deftypefun int isinf (double @var{x}) +This function returns @code{-1} if @var{x} represents negative infinity, +@code{1} if @var{x} represents positive infinity, and @code{0} otherwise. +@end deftypefun + +@comment math.h +@comment GNU +@deftypefun int isnan (double @var{x}) +This function returns a nonzero value if @var{x} is a ``not a number'' +value, and zero otherwise. +@end deftypefun + +@comment math.h +@comment GNU +@deftypefun int finite (double @var{x}) +This function returns a nonzero value if @var{x} is finite or a ``not a +number'' value, and zero otherwise. +@end deftypefun + +@comment math.h +@comment GNU +@deftypefun double infnan (int @var{error}) +@strong{Incomplete:} I don't understand what this function does. +@end deftypefun + +@strong{Portability Note:} The functions listed in this section are GNU +extensions. + + diff --git a/manual/users.texi b/manual/users.texi new file mode 100644 index 0000000000..92aa86d07d --- /dev/null +++ b/manual/users.texi @@ -0,0 +1,1016 @@ +@node Users and Groups +@chapter Users and Groups +@cindex persona + +Every user who can log in on the system is identified by a unique number +called the @dfn{user ID}. Each process has an effective user ID which +says which user's access permissions it has. + +Users are classified into @dfn{groups} for access control purposes. Each +process has one or more @dfn{group ID values} which say which groups the +process can use for access to files. + +The effective user and group IDs of a process collectively form its +@dfn{persona}. This determines which files the process can access. +Normally, a process inherits its persona from the parent process, but +under special circumstances a process can change its persona and thus +change its access permissions. + +Each file in the system also has a user ID and a group ID. Access +control works by comparing the user and group IDs of the file with those +of the running process. + +The system keeps a database of all the registered users, and another +database of all the defined groups. There are library functions you +can use to examine these databases. + +@menu +* User and Group IDs:: Each user has a unique numeric ID; likewise for groups. +* Process Persona:: The user IDs and group IDs of a process. +* Why Change Persona:: Why a program might need to change + its user and/or group IDs. +* How Change Persona:: Restrictions on changing the user and group IDs. +* Reading Persona:: How to examine the process's user and group IDs. +* Setting User ID:: +* Setting Groups:: +* Enable/Disable Setuid:: +* Setuid Example:: A program designed to use setuid. + +* Tips for Setuid:: + +* Who Logged In:: Getting the name of the user who logged in, + or of the real user ID of the current process. + +* User Database:: Functions and data structures for + accessing the user database. +* Group Database:: Functions and data structures for + accessing the group database. +* Database Example:: Example program showing use of database + inquiry functions. +@end menu + +@node User and Group IDs +@section 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 user name +has a unique user ID, but it is possible for several login names to have +the same user ID. The user names and corresponding user IDs are stored +in a data base which you can access as described in @ref{User Database}. + +@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}. @xref{Group Database}, +for how to find information about a group ID or group name. + +@node Process Persona +@section The Persona of a Process + +@cindex effective user ID +@cindex effective group ID +At any time, each process has a single user ID and a group ID which +determine the privileges of the process. These are collectively called +the @dfn{persona} of the process, because they determine ``who it is'' +for purposes of access control. These IDs are also called the +@dfn{effective user ID} and @dfn{effective group ID} of the process. + +Your login shell starts out with a persona which consists of your user +ID and your default group ID. In normal circumstances. all your other +processes inherit these values. + +@cindex real user ID +@cindex real group ID +A process also has a @dfn{real user ID} which identifies the user who +created the process, and a @dfn{real group ID} which identifies that +user's default group. These values do not play a role in access +control, so we do not consider them part of the persona. But they are +also important. + +Both the real and effective user ID can be changed during the lifetime +of a process. @xref{Changing Persona}. + +@cindex supplementary group IDs +In addition, a user can belong to multiple groups, so the persona +includes have @dfn{supplementary group IDs} that also contribute to +access permission. + +For details on how a process's effective user IDs and group IDs affect +its permission to access files, see @ref{Access Permission}. + +The user ID of a process also controls permissions for sending signals +using the @code{kill} function. @xref{Signaling Another Process}. + +@node Why Change Persona +@section Why Change the Persona of a Process? + +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. In fact, @code{login} must set the real user and group IDs +as well as its persona. But this is a special case. + +The more common case of changing persona is when an ordinary user +programs needs access to a resource that wouldn't ordinarily be +accessible to the user actually running it. + +For example, you may have a file that is controlled by your program but +that shouldn't be read or modified directly by other users, either +because it implements some kind of locking protocol, or because you want +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 effective user or group ID to match that of the resource. + +Thus, imagine a game program that saves scores in a file. The game +program itself 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}. In effect, the program must +adopt the persona of @samp{games} so it can write the scores file. + +@node How Change Persona +@section How an Application can Change Persona +@cindex @code{setuid} programs + +The ability to change the persona of a process can be a source of +unintentional privacy violations, or even intentional abuse. Because of +the potential for problems, changing persona is restricted to special +circumstances. + +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 persona 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 of a file's access mode. + +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. Programs do this so as to turn off their special privileges +when they are not needed, which makes for more robustness. + +@node Reading Persona +@section Reading the Persona of a Process + +Here are detailed descriptions of the functions for reading the user and +group IDs of a process, both real and effective. 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 + +@node Setting User ID +@section Setting the User ID + +This section describes the functions for altering the user ID +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 unistd.h +@comment POSIX.1 +@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 (but only if the system +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 + +@node Setting Groups +@section Setting the Group IDs + +@comment unistd.h +@comment POSIX.1 +@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. 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 +@section 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 +@section 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 () +@{ + 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 () +@{ + 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 () +@{ + /* @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 +@section 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 with privileged user IDs such as +@samp{root} 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 @emph{all} +containing directories 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. +@xref{Enable/Disable Setuid}. + +@item +If the @code{setuid} part of your program needs to access other files +besides the controlled resource, it should verify that the real 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 + +@node Who Logged In +@section Identifying Who Logged In +@cindex login name, determining +@cindex user ID, determining + +You can use the functions listed in this section to determine the login +name of the user who is running a process, and the name of the user who +logged in the current session. See also the function @code{getuid} and +friends (@pxref{User and Group ID Functions}). + +The @code{getlogin} function is declared in @file{unistd.h}, while +@code{cuserid} and @code{L_cuserid} are declared in @file{stdio.h}. +@pindex stdio.h +@pindex unistd.h + +@comment unistd.h +@comment POSIX.1 +@deftypefun {char *} getlogin () +The @code{getlogin} function returns a pointer to string containing the +name of the user logged in on the controlling terminal of the process, +or a null pointer if this information cannot be determined. The string +is statically allocated and might be overwritten on subsequent calls to +this function or to @code{cuserid}. +@end deftypefun + +@comment stdio.h +@comment POSIX.1 +@deftypefun {char *} cuserid (@var{string}) +The @code{cuserid} function returns a pointer to a string containing a +user name associated with the effective ID of the process. If +@var{string} is not a null pointer, it should be an array that can hold +at least @code{L_cuserid} characters; the string is returned in this +array. Otherwise, a pointer to a string in a static area is returned. +This string is statically allocated and might be overwritten on +subsequent calls to this function or to @code{getlogin}. +@end deftypefun + +@comment stdio.h +@comment POSIX.1 +@deftypevr Macro int L_cuserid +An integer constant that indicates how long an array you might need to +store a user name. +@end deftypevr + +These functions let your program identify positively the user who is +running or the user who logged in this session. (These can differ when +setuid programs are involved; @xref{Controlling Access Privileges}.) +The user cannot do anything to fool these functions. + +For most purposes, it is more useful to use the environment variable +@code{LOGNAME} to find out who the user is. This is more flexible +precisely because the user can set @code{LOGNAME} arbitrarily. +@xref{Environment Variables}. + +@node User Database +@section User Database +@cindex user database +@cindex password database +@pindex /etc/passwd + +This section describes all about now to search and scan the database of +registered users. The database itself is kept in the file +@file{/etc/passwd} on most systems, but on some systems a special +network server gives access to it. + +@menu +* User Data Structure:: +* Lookup User:: +* Scan All Users:: +* Writing a User Entry:: +@end menu + +@node User Data Structure +@subsection The Data Structure that Describes a User + +The functions and data structures for accessing the system user database +are declared in the header file @file{pwd.h}. +@pindex pwd.h + +@comment pwd.h +@comment POSIX.1 +@deftp {struct Type} passwd +The @code{passwd} data structure is used to hold information about +entries in the system user data base. It has at least the following members: + +@table @code +@item char *pw_name +The user's login name. + +@item char *pw_passwd. +The encrypted password string. + +@item uid_t pw_uid +The user ID number. + +@item gid_t pw_gid +The user's default group ID number. + +@item char *pw_gecos +A string typically containing the user's real name, and possibly other +information such as a phone number. + +@item char *pw_dir +The user's home directory, or initial working directory. This might be +a null pointer, in which case the interpretation is system-dependent. + +@item char *pw_shell +The user's default shell, or the initial program run when the user logs in. +This might be a null pointer, indicating that the system default should +be used. +@end table +@end deftp + +@node Lookup User +@subsection Looking Up One User +@cindex converting user ID to user name +@cindex converting user name to user ID + +You can search the system user database for information about a +specific user using @code{getpwuid} or @code{getpwnam}. These +functions are declared in @file{pwd.h}. + +@comment pwd.h +@comment POSIX.1 +@deftypefun {struct passwd *} getpwuid (uid_t @var{uid}) +This function returns a pointer to a statically-allocated structure +containing information about the user whose user ID is @var{uid}. This +structure may be overwritten on subsequent calls to @code{getpwuid}. + +A null pointer value indicates there is no user in the data base with +user ID @var{uid}. +@end deftypefun + +@comment pwd.h +@comment POSIX.1 +@deftypefun {struct passwd *} getpwnam (const char *@var{name}) +This function returns a pointer to a statically-allocated structure +containing information about the user whose user name is @var{name}. +This structure may be overwritten on subsequent calls to +@code{getpwnam}. + +A null pointer value indicates there is no user named @var{name}. +@end deftypefun + +@node Scanning All Users +@subsection Scanning the List of All Users +@cindex scanning the user list + +This section explains how a program can read the list of all users in +the system, one user at a time. The functions described here are +declared in @file{pwd.h}. + +The recommended way to scan the users is to open the user file and +then call @code{fgetgrent} for each successive user: + +@comment pwd.h +@comment SVID +@deftypefun {struct passwd *} fgetpwent (FILE *@var{stream}) +This function reads the next user entry from @var{stream} and returns a +pointer to the entry. The structure is statically allocated and is +rewritten on subsequent calls to @code{getpwent}. You must copy the +contents of the structure if you wish to save the information. + +This stream must correspond to a file in the same format as the standard +password database file. This function comes from System V. +@end deftypefun + +Another way to scan all the entries in the group database is with +@code{setpwent}, @code{getpwent}, and @code{endpwent}. But this method +is less robust than @code{fgetpwent}, so we provide it only for +compatibility with SVID. In particular, these functions are not +reentrant and are not suitable for use in programs with multiple threads +of control. Calling @code{getpwgid} or @code{getpwnam} can also confuse +the internal state of these functions. + +@comment pwd.h +@comment SVID, GNU +@deftypefun void setpwent () +This function initializes a stream which @code{getpwent} uses to read +the user database. +@end deftypefun + +@comment pwd.h +@comment SVID, GNU +@deftypefun {struct passwd *} getpwent () +The @code{getpwent} function reads the next entry from the stream +initialized by @code{setpwent}. It returns a pointer to the entry. The +structure is statically allocated and is rewritten on subsequent calls +to @code{getpwent}. You must copy the contents of the structure if you +wish to save the information. +@end deftypefun + +@comment pwd.h +@comment SVID, GNU +@deftypefun void endpwent () +This function closes the internal stream used by @code{getpwent}. +@end deftypefun + +@node Writing a User Entry +@subsection Writing a User Entry + +@comment pwd.h +@comment SVID +@deftypefun int putpwent (const struct passwd *@var{p}, FILE *@var{stream}) +This function writes the user entry @code{*@var{p}} to the stream +@var{stream}, in the format used for the standard user database +file. The return value is zero on success and non-zero on failure. + +This function exists for compatibility with SVID. We recommend that you +avoid using it, because it makes sense only on the assumption that the +@code{struct passwd} structure has no members except the standard ones; +on a system which merges the traditional Unix data base with other +extended information about users, adding an entry using this function +would inevitably leave out much of the important information. + +The function @code{putpwent} is declared in @file{pwd.h}. +@end deftypefun + +@node Group Database +@section Group Database +@cindex group database +@pindex /etc/group + +This section describes all about now to search and scan the database of +registered groups. The database itself is kept in the file +@file{/etc/group} on most systems, but on some systems a special network +service provides access to it. + +@menu +* Group Data Structure:: +* Lookup Group:: +* Scan All Groups:: +@end menu + +@node Group Data Structure +@subsection The Data Structure for a Group + +The functions and data structures for accessing the system group +database are declared in the header file @file{grp.h}. +@pindex grp.h + +@comment grp.h +@comment POSIX.1 +@deftp {Data Type} {struct group} +The @code{group} structure is used to hold information about an entry in +the system group database. It has at least the following members: + +@table @code +@item char *gr_name +The name of the group. + +@item gid_t gr_gid +The group ID of the group. + +@item char **gr_mem +A vector of pointers to the names of users in the group. Each user name +is a null-terminated string, and the vector itself is terminated by a +null pointer. +@end table +@end deftp + +@node Lookup Group +@subsection Looking Up One Group +@cindex converting group name to group ID +@cindex converting group ID to group name + +You can search the group database for information about a specific +group using @code{getgrgid} or @code{getgrnam}. These functions are +declared in @file{grp.h}. + +@comment grp.h +@comment POSIX.1 +@deftypefun {struct group *} getgrgid (gid_t @var{gid}) +This function returns a pointer to a statically-allocated structure +containing information about the group whose group ID is @var{gid}. +This structure may be overwritten by subsequent calls to +@code{getgrgid}. + +A null pointer indicates there is no group with ID @var{gid}. +@end deftypefun + +@comment grp.h +@comment POSIX.1 +@deftypefun {struct group *} getgrnam (const char *@var{name}) +This function returns a pointer to a statically-allocated structure +containing information about the group whose group name is @var{name}. +This structure may be overwritten by subsequent calls to +@code{getgrnam}. + +A null pointer indicates there is no group named @var{name}. +@end deftypefun + +@node Scanning All Groups +@subsection Scanning the List of All Groups +@cindex scanning the group list + +This section explains how a program can read the list of all groups in +the system, one group at a time. The functions described here are +declared in @file{grp.h}. + +The recommended way to scan the groups is to open the group file and +then call @code{fgetgrent} for each successive group: + +@comment grp.h +@comment SVID +@deftypefun {struct group *} fgetgrent (FILE *@var{stream}) +The @code{fgetgrent} function reads the next entry from @var{stream}. +It returns a pointer to the entry. The structure is statically +allocated and is rewritten on subsequent calls to @code{getgrent}. You +must copy the contents of the structure if you wish to save the +information. + +The stream must correspond to a file in the same format as the standard +group database file. +@end deftypefun + +Another way to scan all the entries in the group database is with +@code{setgrent}, @code{getgrent}, and @code{endgrent}. But this method +is less robust than @code{fgetgrent}, so we provide it only for +compatibility with SVID. In particular, these functions are not +reentrant and are not suitable for use in programs with multiple threads +of control. Calling @code{getgrgid} or @code{getgrnam} can also confuse +the internal state of these functions. + +@comment grp.h +@comment SVID, GNU +@deftypefun void setgrent () +This function initializes a stream for reading from the group data base. +You use this stream by calling @code{getgrent}. +@end deftypefun + +@comment grp.h +@comment SVID, GNU +@deftypefun {struct group *} getgrent () +The @code{getgrent} function reads the next entry from the stream +initialized by @code{setgrent}. It returns a pointer to the entry. The +structure is statically allocated and is rewritten on subsequent calls +to @code{getgrent}. You must copy the contents of the structure if you +wish to save the information. +@end deftypefun + +@comment grp.h +@comment SVID, GNU +@deftypefun void endgrent () +This function closes the internal stream used by @code{getgrent}. +@end deftypefun + +@node Database Example +@section User and Group Database Example + +Here is an example program showing the use of the system database inquiry +functions. The program prints some information about the user running +the program. + +@example +#include <grp.h> +#include <pwd.h> +#include <sys/types.h> +#include <unistd.h> +#include <stdlib.h> + +void +main () +@{ + uid_t me; + struct passwd *my_passwd; + struct group *my_group; + char **members; + + /* @r{Get information about the user ID.} */ + me = getuid (); + my_passwd = getpwuid (me); + if (!my_passwd) @{ + printf ("Couldn't find out about user %d.\n", me); + exit (EXIT_FAILURE); + @} + + /* @r{Print the information.} */ + printf ("My login name is %s.\n", my_passwd->pw_name); + printf ("My uid is %d.\n", my_passwd->pw_uid); + printf ("My home directory is %s.\n", my_passwd->pw_dir); + printf ("My default shell is %s.\n", my_passwd->pw_shell); + + /* @r{Get information about the default group ID.} */ + my_group = getgrgid (my_passwd->pw_gid); + if (!my_group) @{ + printf ("Couldn't find out about group %d.\n", + my_passwd->pw_gid); + exit (EXIT_FAILURE); + @} + + /* @r{Print the information.} */ + printf ("My default group is %s (%d).\n", + my_group->gr_name, my_passwd->pw_gid); + printf ("The members of this group are:\n"); + members = my_group->gr_mem; + while (*members) + printf (" %s\n", *members++); + + exit (EXIT_SUCCESS); +@} +@end example + +Here is some output from this program: + +@example +My login name is snurd. +My uid is 31093. +My home directory is /home/fsg/snurd. +My default shell is /bin/sh. +My default group is guest (12). +The members of this group are: + friedman + @dots{} +@end example |