diff options
Diffstat (limited to 'manual/users.texi')
-rw-r--r-- | manual/users.texi | 2837 |
1 files changed, 0 insertions, 2837 deletions
diff --git a/manual/users.texi b/manual/users.texi deleted file mode 100644 index 47e28febdc..0000000000 --- a/manual/users.texi +++ /dev/null @@ -1,2837 +0,0 @@ -@node Users and Groups, System Management, Name Service Switch, Top -@c %MENU% How users are identified and classified -@chapter Users and Groups - -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:: Changing the user and group IDs. -* Reading Persona:: How to examine the user and group IDs. - -* Setting User ID:: Functions for setting the user ID. -* Setting Groups:: Functions for setting the group IDs. - -* Enable/Disable Setuid:: Turning setuid access on and off. -* Setuid Program Example:: The pertinent parts of one sample program. -* Tips for Setuid:: How to avoid granting unlimited access. - -* Who Logged In:: Getting the name of the user who logged in, - or of the real user ID of the current process. - -* User Accounting Database:: Keeping information about users and various - actions in databases. - -* 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 the use of database - inquiry functions. -* Netgroup Database:: Functions for accessing the netgroup database. -@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 belongs to one -@dfn{default group} and may also belong to any number of -@dfn{supplementary groups}. 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 persona -@cindex effective user ID -@cindex effective group ID -@cindex supplementary group IDs - -@c When Hurd is more widely used, explain multiple effective user IDs -@c here. -zw -At any time, each process has an @dfn{effective user ID}, a @dfn{effective -group ID}, and a set of @dfn{supplementary group IDs}. These IDs -determine the privileges of the process. They are collectively -called the @dfn{persona} of the process, because they determine ``who it -is'' for purposes of access control. - -Your login shell starts out with a persona which consists of your user -ID, your default group ID, and your supplementary group IDs (if you are -in more than one group). 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{Why Change Persona}. - -For details on how a process's effective user ID and group IDs affect -its permission to access files, see @ref{Access Permission}. - -The effective user ID of a process also controls permissions for sending -signals using the @code{kill} function. @xref{Signaling Another -Process}. - -Finally, there are many operations which can only be performed by a -process whose effective user ID is zero. A process with this user ID is -a @dfn{privileged process}. Commonly the user name @code{root} is -associated with user ID 0, but there may be other user names with this -ID. -@c !!! should mention POSIX capabilities here. - -@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. (To accomplish this fully, @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 -program 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, @code{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 @code{games}. In effect, the program must -adopt the persona of @code{games} so it can write to the scores file. - -@node How Change Persona -@section How an Application Can Change Persona -@cindex @code{setuid} programs -@cindex saved set-user-ID -@cindex saved set-group-ID -@cindex @code{_POSIX_SAVED_IDS} - -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 arbitrarily set your user ID or group ID to anything you want; -only privileged processes 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 setuid -and setgid bits of a file's access mode. @xref{Permission Bits}. - -When the setuid bit of an executable file is on, executing that file -gives the process a third user ID: the @dfn{file user ID}. This ID is -set to the owner ID of the file. The system then changes the effective -user ID to the file user ID. The real user ID remains as it was. -Likewise, if the setgid bit is on, the process is given a @dfn{file -group ID} equal to the group ID of the file, and its effective group ID -is changed to the file group ID. - -If a process has a file ID (user or group), then it can at any time -change its effective ID to its real ID and back to its file ID. -Programs use this feature to relinquish their special privileges except -when they actually need them. This makes it less likely that they can -be tricked into doing something inappropriate with their privileges. - -@strong{Portability Note:} Older systems do not have file IDs. -To determine if a system has this feature, you can test the compiler -define @code{_POSIX_SAVED_IDS}. (In the POSIX standard, file IDs are -known as saved IDs.) - -@xref{File Attributes}, for a more general discussion of file modes and -accessibility. - -@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 -@theglibc{}, this is an alias for @code{unsigned 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 -@theglibc{}, this is an alias for @code{unsigned int}. -@end deftp - -@comment unistd.h -@comment POSIX.1 -@deftypefun uid_t getuid (void) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -@c Atomic syscall, except on hurd, where it takes a lock within a hurd -@c critical section. -The @code{getuid} function returns the real user ID of the process. -@end deftypefun - -@comment unistd.h -@comment POSIX.1 -@deftypefun gid_t getgid (void) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -The @code{getgid} function returns the real group ID of the process. -@end deftypefun - -@comment unistd.h -@comment POSIX.1 -@deftypefun uid_t geteuid (void) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -The @code{geteuid} function returns the effective user ID of the process. -@end deftypefun - -@comment unistd.h -@comment POSIX.1 -@deftypefun gid_t getegid (void) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -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}) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -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. On systems that do not support -supplementary groups, this will always be zero. - -Here's how to use @code{getgroups} to read all the supplementary group -IDs: - -@smallexample -@group -gid_t * -read_all_groups (void) -@{ - int ngroups = getgroups (0, NULL); - gid_t *groups - = (gid_t *) xmalloc (ngroups * sizeof (gid_t)); - int val = getgroups (ngroups, groups); - if (val < 0) - @{ - free (groups); - return NULL; - @} - return groups; -@} -@end group -@end smallexample -@end deftypefun - -@node Setting User ID -@section Setting the User ID - -This section describes the functions for altering the user ID (real -and/or effective) 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 seteuid (uid_t @var{neweuid}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -@c seteuid @asulock @aculock -@c INLINE_SETXID_SYSCALL @asulock @aculock -@c This may be just a unix syscall, or the ugliness below used by -@c nptl to propagate the syscall to all cloned processes used to -@c implement threads. -@c nptl_setxid @asulock @aculock -@c while holding the stack_alloc_lock, mark with SETXID_BITMASK all -@c threads that are not exiting, signal them until no thread remains -@c marked, clear the marks and run the syscall, then release the lock. -@c lll_lock @asulock @aculock -@c list_for_each ok -@c list_entry ok -@c setxid_mark_thread ok -@c if a thread is initializing, wait for it to be cloned. -@c mark it with SETXID_BITMASK if it's not exiting -@c setxid_signal_thread ok -@c if a thread is marked with SETXID_BITMASK, -@c send it the SIGSETXID signal -@c setxid_unmark_thread ok -@c clear SETXID_BITMASK and release the futex if SETXID_BITMASK is -@c set. -@c <syscall> ok -@c lll_unlock @aculock -@c -@c sighandler_setxid ok -@c issue the syscall, clear SETXID_BITMASK, release the futex, and -@c wake up the signaller loop if the counter reached zero. -This function sets the effective user ID of a process to @var{neweuid}, -provided that the process is allowed to change its effective user ID. A -privileged process (effective user ID zero) can change its effective -user ID to any legal value. An unprivileged process with a file user ID -can change its effective user ID to its real user ID or to its file user -ID. Otherwise, a process may not change its effective user ID at all. - -The @code{seteuid} 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{neweuid} argument is invalid. - -@item EPERM -The process may not change to the specified ID. -@end table - -Older systems (those without the @code{_POSIX_SAVED_IDS} feature) do not -have this function. -@end deftypefun - -@comment unistd.h -@comment POSIX.1 -@deftypefun int setuid (uid_t @var{newuid}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -@c setuid @asulock @aculock -@c INLINE_SETXID_SYSCALL dup @asulock @aculock -If the calling process is privileged, this function sets both the real -and effective user IDs of the process to @var{newuid}. It also deletes -the file user ID of the process, if any. @var{newuid} may be any -legal value. (Once this has been done, there is no way to recover the -old effective user ID.) - -If the process is not privileged, and the system supports the -@code{_POSIX_SAVED_IDS} feature, then this function behaves like -@code{seteuid}. - -The return values and error conditions are the same as for @code{seteuid}. -@end deftypefun - -@comment unistd.h -@comment BSD -@deftypefun int setreuid (uid_t @var{ruid}, uid_t @var{euid}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -@c setreuid @asulock @aculock -@c INLINE_SETXID_SYSCALL dup @asulock @aculock -This function sets the real user ID of the process to @var{ruid} and the -effective user ID to @var{euid}. If @var{ruid} is @code{-1}, it means -not to change the real user ID; likewise if @var{euid} is @code{-1}, it -means not to change the effective user ID. - -The @code{setreuid} function exists for compatibility with 4.3 BSD Unix, -which does not support file IDs. You can use this function to swap the -effective and real user IDs of the process. (Privileged processes are -not limited to this particular usage.) If file IDs are supported, you -should use that feature instead of this function. @xref{Enable/Disable -Setuid}. - -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. -@end table -@end deftypefun - -@node Setting Groups -@section Setting the Group IDs - -This section describes the functions for altering the group IDs (real -and effective) 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 setegid (gid_t @var{newgid}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -@c setegid @asulock @aculock -@c INLINE_SETXID_SYSCALL dup @asulock @aculock -This function sets the effective group ID of the process to -@var{newgid}, provided that the process is allowed to change its group -ID. Just as with @code{seteuid}, if the process is privileged it may -change its effective group ID to any value; if it isn't, but it has a -file group ID, then it may change to its real group ID or file group ID; -otherwise it may not change its effective group ID. - -Note that a process is only privileged if its effective @emph{user} ID -is zero. The effective group ID only affects access permissions. - -The return values and error conditions for @code{setegid} are the same -as those for @code{seteuid}. - -This function is only present if @code{_POSIX_SAVED_IDS} is defined. -@end deftypefun - -@comment unistd.h -@comment POSIX.1 -@deftypefun int setgid (gid_t @var{newgid}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -@c setgid @asulock @aculock -@c INLINE_SETXID_SYSCALL dup @asulock @aculock -This function sets both the real and effective group ID of the process -to @var{newgid}, provided that the process is privileged. It also -deletes the file group ID, if any. - -If the process is not privileged, then @code{setgid} behaves like -@code{setegid}. - -The return values and error conditions for @code{setgid} are the same -as those for @code{seteuid}. -@end deftypefun - -@comment unistd.h -@comment BSD -@deftypefun int setregid (gid_t @var{rgid}, gid_t @var{egid}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -@c setregid @asulock @aculock -@c INLINE_SETXID_SYSCALL dup @asulock @aculock -This function sets the real group ID of the process to @var{rgid} and -the effective group ID to @var{egid}. If @var{rgid} is @code{-1}, it -means not to change the real group ID; likewise if @var{egid} is -@code{-1}, it means not to change the effective group ID. - -The @code{setregid} function is provided for compatibility with 4.3 BSD -Unix, which does not support file IDs. You can use this function to -swap the effective and real group IDs of the process. (Privileged -processes are not limited to this usage.) If file IDs are supported, -you should use that feature instead of using this function. -@xref{Enable/Disable Setuid}. - -The return values and error conditions for @code{setregid} are the same -as those for @code{setreuid}. -@end deftypefun - -@code{setuid} and @code{setgid} behave differently depending on whether -the effective user ID at the time is zero. If it is not zero, they -behave like @code{seteuid} and @code{setegid}. If it is, they change -both effective and real IDs and delete the file ID. To avoid confusion, -we recommend you always use @code{seteuid} and @code{setegid} except -when you know the effective user ID is zero and your intent is to change -the persona permanently. This case is rare---most of the programs that -need it, such as @code{login} and @code{su}, have already been written. - -Note that if your program is setuid to some user other than @code{root}, -there is no way to drop privileges permanently. - -The 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}, const gid_t *@var{groups}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -@c setgroups @asulock @aculock -@c INLINE_SETXID_SYSCALL dup @asulock @aculock -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{group}) -@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}} -@c initgroups @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c sysconf(_SC_NGROUPS_MAX) dup @acsfd -@c MIN dup ok -@c malloc @ascuheap @acsmem -@c internal_getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nscd_getgrouplist @ascuheap @acsfd @acsmem -@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem -@c nscd_cache_search dup ok -@c nscd_open_socket dup @acsfd -@c realloc dup @ascuheap @acsmem -@c readall dup ok -@c memcpy dup ok -@c close_not_cancel_no_status dup @acsfd -@c nscd_drop_map_ref dup @ascuheap @acsmem -@c nscd_unmap dup @ascuheap @acsmem -@c nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock -@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c compat_call @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c sysconf(_SC_GETGR_R_SIZE_MAX) ok -@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *getgrent_fct @ascuplugin -@c *setgrent_fct @ascuplugin -@c *endgrent_fct @ascuplugin -@c realloc dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c *initgroups_dyn_fct @ascuplugin -@c nss_next_action dup ok -@c setgroups dup @asulock @aculock -@c free dup @ascuheap @acsmem -The @code{initgroups} function sets the process's supplementary group -IDs to be the normal default for the user name @var{user}. The group -@var{group} is automatically included. - -This function works by scanning the group database for all the groups -@var{user} belongs to. It then calls @code{setgroups} with the list it -has constructed. - -The return values and error conditions are the same as for -@code{setgroups}. -@end deftypefun - -If you are interested in the groups a particular user belongs to, but do -not want to change the process's supplementary group IDs, you can use -@code{getgrouplist}. To use @code{getgrouplist}, your programs should -include the header file @file{grp.h}. -@pindex grp.h - -@comment grp.h -@comment BSD -@deftypefun int getgrouplist (const char *@var{user}, gid_t @var{group}, gid_t *@var{groups}, int *@var{ngroups}) -@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}} -@c getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c MAX dup ok -@c malloc dup @ascuheap @acsmem -@c internal_getgrouplist dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c memcpy dup ok -@c free dup @ascuheap @acsmem -The @code{getgrouplist} function scans the group database for all the -groups @var{user} belongs to. Up to *@var{ngroups} group IDs -corresponding to these groups are stored in the array @var{groups}; the -return value from the function is the number of group IDs actually -stored. If *@var{ngroups} is smaller than the total number of groups -found, then @code{getgrouplist} returns a value of @code{-1} and stores -the actual number of groups in *@var{ngroups}. The group @var{group} is -automatically included in the list of groups returned by -@code{getgrouplist}. - -Here's how to use @code{getgrouplist} to read all supplementary groups -for @var{user}: - -@smallexample -@group -gid_t * -supplementary_groups (char *user) -@{ - int ngroups = 16; - gid_t *groups - = (gid_t *) xmalloc (ngroups * sizeof (gid_t)); - struct passwd *pw = getpwnam (user); - - if (pw == NULL) - return NULL; - - if (getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups) < 0) - @{ - groups = xrealloc (ngroups * sizeof (gid_t)); - getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups); - @} - return groups; -@} -@end group -@end smallexample -@end deftypefun - -@node Enable/Disable Setuid -@section Enabling and Disabling Setuid Access - -A typical setuid program does not need its special access all of the -time. It's a good idea to turn off this access when it isn't needed, -so it can't possibly give unintended access. - -If the system supports the @code{_POSIX_SAVED_IDS} feature, you can -accomplish this with @code{seteuid}. 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: - -@smallexample -user_user_id = getuid (); -game_user_id = geteuid (); -@end smallexample - -Then it can turn off game file access with - -@smallexample -seteuid (user_user_id); -@end smallexample - -@noindent -and turn it on with - -@smallexample -seteuid (game_user_id); -@end smallexample - -@noindent -Throughout this process, the real user ID remains @code{jdoe} and the -file user ID remains @code{games}, so the program can always set its -effective user ID to either one. - -On other systems that don't support file user IDs, you can -turn setuid access on and off by using @code{setreuid} to swap the real -and effective user IDs of the process, as follows: - -@smallexample -setreuid (geteuid (), getuid ()); -@end smallexample - -@noindent -This special case is always allowed---it cannot fail. - -Why does this have the effect of toggling the setuid access? 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} access. Another swap brings @code{games} back to -the effective user ID and restores access to the scores file. - -In order to handle both kinds of systems, test for the saved user ID -feature with a preprocessor conditional, like this: - -@smallexample -#ifdef _POSIX_SAVED_IDS - seteuid (user_user_id); -#else - setreuid (geteuid (), getuid ()); -#endif -@end smallexample - -@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 setuid bit set and owned by the same user as the @file{scores} -file. Typically, a system administrator will set up an account like -@code{games} for this purpose. - -The executable file is given mode @code{4755}, so that doing an -@samp{ls -l} on it produces output like: - -@smallexample --rwsr-xr-x 1 games 184422 Jul 30 15:17 caber-toss -@end smallexample - -@noindent -The setuid 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: - -@smallexample --rw-r--r-- 1 games 0 Jul 31 15:33 scores -@end smallexample - -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 -file IDs feature if it is supported, and otherwise uses @code{setreuid} -to swap the effective and real user IDs. - -@smallexample -#include <stdio.h> -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> - - -/* @r{Remember the effective and real UIDs.} */ - -static uid_t euid, ruid; - - -/* @r{Restore the effective UID to its original value.} */ - -void -do_setuid (void) -@{ - int status; - -#ifdef _POSIX_SAVED_IDS - status = seteuid (euid); -#else - status = setreuid (ruid, euid); -#endif - if (status < 0) @{ - fprintf (stderr, "Couldn't set uid.\n"); - exit (status); - @} -@} - - -@group -/* @r{Set the effective UID to the real UID.} */ - -void -undo_setuid (void) -@{ - int status; - -#ifdef _POSIX_SAVED_IDS - status = seteuid (ruid); -#else - status = setreuid (euid, ruid); -#endif - if (status < 0) @{ - fprintf (stderr, "Couldn't set uid.\n"); - exit (status); - @} -@} -@end group - -/* @r{Main program.} */ - -int -main (void) -@{ - /* @r{Remember the real and effective user IDs.} */ - ruid = getuid (); - euid = geteuid (); - undo_setuid (); - - /* @r{Do the game and record the score.} */ - @dots{} -@} -@end smallexample - -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 file user ID, -like this: - -@smallexample -/* @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 (); - -@group - /* @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 group -@end smallexample - -@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 -@code{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. -It's better if you can write your program to use a special group than a -special user. - -@item -Be cautious about using the @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. - -You should also check the arguments passed to the program to make sure -they do not have unexpected effects. Likewise, you should examine the -environment variables. Decide which arguments and variables are safe, -and reject all others. - -You should never use @code{system} in a privileged program, because it -invokes a shell. - -@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{Reading Persona}). How this information is collected by -the system and how to control/add/remove information from the background -storage is described in @ref{User Accounting Database}. - -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 (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:getlogin} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getlogin (linux) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c getlogin_r_loginuid dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c getlogin_fd0 (unix) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem -@c uses static buffer name => @mtasurace:getlogin -@c ttyname_r dup @ascuheap @acsmem @acsfd -@c strncpy dup ok -@c setutent dup @mtasurace:utent @asulock @aculock @acsfd -@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c endutent dup @mtasurace:utent @asulock @aculock -@c libc_lock_unlock dup ok -@c strlen dup ok -@c memcpy dup ok -@c -@c getlogin_r (linux) @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c getlogin_r_loginuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c open_not_cancel_2 dup @acsfd -@c read_not_cancel dup ok -@c close_not_cancel_no_status dup @acsfd -@c strtoul @mtslocale -@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c realloc dup @asulock @aculock @acsfd @acsmem -@c strlen dup ok -@c memcpy dup ok -@c free dup @asulock @aculock @acsfd @acsmem -@c getlogin_r_fd0 (unix) @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd -@c ttyname_r dup @ascuheap @acsmem @acsfd -@c strncpy dup ok -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd -@c *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer -@c *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock -@c libc_lock_unlock dup ok -@c strlen dup ok -@c memcpy dup ok -The @code{getlogin} function returns a pointer to a 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 (char *@var{string}) -@safety{@prelim{}@mtunsafe{@mtasurace{:cuserid/!string} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c cuserid @mtasurace:cuserid/!string @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c if string is NULL, cuserid will overwrite and return a static buffer -@c geteuid dup ok -@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c strncpy dup ok -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}. - -The use of this function is deprecated since it is marked to be -withdrawn in XPG4.2 and has already been removed from newer revisions of -POSIX.1. -@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; see @ref{Process Persona}.) 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{Standard Environment}. - - -@node User Accounting Database -@section The User Accounting Database -@cindex user accounting database - -Most Unix-like operating systems keep track of logged in users by -maintaining a user accounting database. This user accounting database -stores for each terminal, who has logged on, at what time, the process -ID of the user's login shell, etc., etc., but also stores information -about the run level of the system, the time of the last system reboot, -and possibly more. - -The user accounting database typically lives in @file{/etc/utmp}, -@file{/var/adm/utmp} or @file{/var/run/utmp}. However, these files -should @strong{never} be accessed directly. For reading information -from and writing information to the user accounting database, the -functions described in this section should be used. - - -@menu -* Manipulating the Database:: Scanning and modifying the user - accounting database. -* XPG Functions:: A standardized way for doing the same thing. -* Logging In and Out:: Functions from BSD that modify the user - accounting database. -@end menu - -@node Manipulating the Database -@subsection Manipulating the User Accounting Database - -These functions and the corresponding data structures are declared in -the header file @file{utmp.h}. -@pindex utmp.h - -@comment utmp.h -@comment SVID -@deftp {Data Type} {struct exit_status} -The @code{exit_status} data structure is used to hold information about -the exit status of processes marked as @code{DEAD_PROCESS} in the user -accounting database. - -@table @code -@item short int e_termination -The exit status of the process. - -@item short int e_exit -The exit status of the process. -@end table -@end deftp - -@deftp {Data Type} {struct utmp} -The @code{utmp} data structure is used to hold information about entries -in the user accounting database. On @gnusystems{} it has the following -members: - -@table @code -@item short int ut_type -Specifies the type of login; one of @code{EMPTY}, @code{RUN_LVL}, -@code{BOOT_TIME}, @code{OLD_TIME}, @code{NEW_TIME}, @code{INIT_PROCESS}, -@code{LOGIN_PROCESS}, @code{USER_PROCESS}, @code{DEAD_PROCESS} or -@code{ACCOUNTING}. - -@item pid_t ut_pid -The process ID number of the login process. - -@item char ut_line[] -The device name of the tty (without @file{/dev/}). - -@item char ut_id[] -The inittab ID of the process. - -@item char ut_user[] -The user's login name. - -@item char ut_host[] -The name of the host from which the user logged in. - -@item struct exit_status ut_exit -The exit status of a process marked as @code{DEAD_PROCESS}. - -@item long ut_session -The Session ID, used for windowing. - -@item struct timeval ut_tv -Time the entry was made. For entries of type @code{OLD_TIME} this is -the time when the system clock changed, and for entries of type -@code{NEW_TIME} this is the time the system clock was set to. - -@item int32_t ut_addr_v6[4] -The Internet address of a remote host. -@end table -@end deftp - -The @code{ut_type}, @code{ut_pid}, @code{ut_id}, @code{ut_tv}, and -@code{ut_host} fields are not available on all systems. Portable -applications therefore should be prepared for these situations. To help -do this the @file{utmp.h} header provides macros -@code{_HAVE_UT_TYPE}, @code{_HAVE_UT_PID}, @code{_HAVE_UT_ID}, -@code{_HAVE_UT_TV}, and @code{_HAVE_UT_HOST} if the respective field is -available. The programmer can handle the situations by using -@code{#ifdef} in the program code. - -The following macros are defined for use as values for the -@code{ut_type} member of the @code{utmp} structure. The values are -integer constants. - -@vtable @code -@comment utmp.h -@comment SVID -@item EMPTY -This macro is used to indicate that the entry contains no valid user -accounting information. - -@comment utmp.h -@comment SVID -@item RUN_LVL -This macro is used to identify the system's runlevel. - -@comment utmp.h -@comment SVID -@item BOOT_TIME -This macro is used to identify the time of system boot. - -@comment utmp.h -@comment SVID -@item OLD_TIME -This macro is used to identify the time when the system clock changed. - -@comment utmp.h -@comment SVID -@item NEW_TIME -This macro is used to identify the time after the system clock changed. - -@comment utmp.h -@comment SVID -@item INIT_PROCESS -This macro is used to identify a process spawned by the init process. - -@comment utmp.h -@comment SVID -@item LOGIN_PROCESS -This macro is used to identify the session leader of a logged in user. - -@comment utmp.h -@comment SVID -@item USER_PROCESS -This macro is used to identify a user process. - -@comment utmp.h -@comment SVID -@item DEAD_PROCESS -This macro is used to identify a terminated process. - -@comment utmp.h -@comment SVID -@item ACCOUNTING -??? -@end vtable - -The size of the @code{ut_line}, @code{ut_id}, @code{ut_user} and -@code{ut_host} arrays can be found using the @code{sizeof} operator. - -Many older systems have, instead of an @code{ut_tv} member, an -@code{ut_time} member, usually of type @code{time_t}, for representing -the time associated with the entry. Therefore, for backwards -compatibility only, @file{utmp.h} defines @code{ut_time} as an alias for -@code{ut_tv.tv_sec}. - -@comment utmp.h -@comment SVID -@deftypefun void setutent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -@c Besides the static variables in utmp_file.c, there's the jump_table. -@c They're both modified while holding a lock, but other threads may -@c cause the variables to be modified between calling this function and -@c others that rely on the internal state it sets up. - -@c setutent @mtasurace:utent @asulock @aculock @acsfd -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->setutent @mtasurace:utent @acsfd -@c setutent_unknown @mtasurace:utent @acsfd -@c *libc_utmp_file_functions.setutent = setutent_file @mtasurace:utent @acsfd -@c open_not_cancel_2 dup @acsfd -@c fcntl_not_cancel dup ok -@c close_not_cancel_no_status dup @acsfd -@c lseek64 dup ok -@c libc_lock_unlock dup ok -This function opens the user accounting database to begin scanning it. -You can then call @code{getutent}, @code{getutid} or @code{getutline} to -read entries and @code{pututline} to write entries. - -If the database is already open, it resets the input to the beginning of -the database. -@end deftypefun - -@comment utmp.h -@comment SVID -@deftypefun {struct utmp *} getutent (void) -@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasurace{:utentbuf} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} -@c The static buffer that holds results is allocated with malloc at -@c the first call; the test is not thread-safe, so multiple concurrent -@c calls could malloc multiple buffers. - -@c getutent @mtuinit @mtasurace:utent @mtasurace:utentbuf @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem -@c malloc @asulock @aculock @acsfd @acsmem -@c getutent_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -The @code{getutent} function reads the next entry from the user -accounting database. It returns a pointer to the entry, which is -statically allocated and may be overwritten by subsequent calls to -@code{getutent}. You must copy the contents of the structure if you -wish to save the information or you can use the @code{getutent_r} -function which stores the data in a user-provided buffer. - -A null pointer is returned in case no further entry is available. -@end deftypefun - -@comment utmp.h -@comment SVID -@deftypefun void endutent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -@c endutent @mtasurace:utent @asulock @aculock @acsfd -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->endutent @mtasurace:utent @acsfd -@c endutent_unknown ok -@c endutent_file @mtasurace:utent @acsfd -@c close_not_cancel_no_status dup @acsfd -@c libc_lock_unlock dup ok -This function closes the user accounting database. -@end deftypefun - -@comment utmp.h -@comment SVID -@deftypefun {struct utmp *} getutid (const struct utmp *@var{id}) -@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} -@c Same caveats as getutline. -@c -@c getutid @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd -@c uses a static buffer malloced on the first call -@c malloc dup @ascuheap @acsmem -@c getutid_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -This function searches forward from the current point in the database -for an entry that matches @var{id}. If the @code{ut_type} member of the -@var{id} structure is one of @code{RUN_LVL}, @code{BOOT_TIME}, -@code{OLD_TIME} or @code{NEW_TIME} the entries match if the -@code{ut_type} members are identical. If the @code{ut_type} member of -the @var{id} structure is @code{INIT_PROCESS}, @code{LOGIN_PROCESS}, -@code{USER_PROCESS} or @code{DEAD_PROCESS}, the entries match if the -@code{ut_type} member of the entry read from the database is one of -these four, and the @code{ut_id} members match. However if the -@code{ut_id} member of either the @var{id} structure or the entry read -from the database is empty it checks if the @code{ut_line} members match -instead. If a matching entry is found, @code{getutid} returns a pointer -to the entry, which is statically allocated, and may be overwritten by a -subsequent call to @code{getutent}, @code{getutid} or @code{getutline}. -You must copy the contents of the structure if you wish to save the -information. - -A null pointer is returned in case the end of the database is reached -without a match. - -The @code{getutid} function may cache the last read entry. Therefore, -if you are using @code{getutid} to search for multiple occurrences, it -is necessary to zero out the static data after each call. Otherwise -@code{getutid} could just return a pointer to the same entry over and -over again. -@end deftypefun - -@comment utmp.h -@comment SVID -@deftypefun {struct utmp *} getutline (const struct utmp *@var{line}) -@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} -@c The static buffer that holds results is allocated with malloc at -@c the first call; the test is not thread-safe, so multiple concurrent -@c calls could malloc multiple buffers. - -@c getutline @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem -@c malloc @asulock @aculock @acsfd @acsmem -@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -This function searches forward from the current point in the database -until it finds an entry whose @code{ut_type} value is -@code{LOGIN_PROCESS} or @code{USER_PROCESS}, and whose @code{ut_line} -member matches the @code{ut_line} member of the @var{line} structure. -If it finds such an entry, it returns a pointer to the entry which is -statically allocated, and may be overwritten by a subsequent call to -@code{getutent}, @code{getutid} or @code{getutline}. You must copy the -contents of the structure if you wish to save the information. - -A null pointer is returned in case the end of the database is reached -without a match. - -The @code{getutline} function may cache the last read entry. Therefore -if you are using @code{getutline} to search for multiple occurrences, it -is necessary to zero out the static data after each call. Otherwise -@code{getutline} could just return a pointer to the same entry over and -over again. -@end deftypefun - -@comment utmp.h -@comment SVID -@deftypefun {struct utmp *} pututline (const struct utmp *@var{utmp}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -@c pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd -@c pututline_unknown @mtasurace:utent @acsfd -@c setutent_unknown dup @mtasurace:utent @acsfd -@c pututline_file @mtascusig:ALRM @mtascutimer @acsfd -@c TRANSFORM_UTMP_FILE_NAME ok -@c strcmp dup ok -@c acesss dup ok -@c open_not_cancel_2 dup @acsfd -@c fcntl_not_cancel dup ok -@c close_not_cancel_no_status dup @acsfd -@c llseek dup ok -@c dup2 dup ok -@c utmp_equal dup ok -@c internal_getut_r dup @mtascusig:ALRM @mtascutimer -@c LOCK_FILE dup @mtascusig:ALRM @mtasctimer -@c LOCKING_FAILED dup ok -@c ftruncate64 dup ok -@c write_not_cancel dup ok -@c UNLOCK_FILE dup @mtasctimer -@c libc_lock_unlock dup @aculock -The @code{pututline} function inserts the entry @code{*@var{utmp}} at -the appropriate place in the user accounting database. If it finds that -it is not already at the correct place in the database, it uses -@code{getutid} to search for the position to insert the entry, however -this will not modify the static structure returned by @code{getutent}, -@code{getutid} and @code{getutline}. If this search fails, the entry -is appended to the database. - -The @code{pututline} function returns a pointer to a copy of the entry -inserted in the user accounting database, or a null pointer if the entry -could not be added. The following @code{errno} error conditions are -defined for this function: - -@table @code -@item EPERM -The process does not have the appropriate privileges; you cannot modify -the user accounting database. -@end table -@end deftypefun - -All the @code{get*} functions mentioned before store the information -they return in a static buffer. This can be a problem in multi-threaded -programs since the data returned for the request is overwritten by the -return value data in another thread. Therefore @theglibc{} -provides as extensions three more functions which return the data in a -user-provided buffer. - -@comment utmp.h -@comment GNU -@deftypefun int getutent_r (struct utmp *@var{buffer}, struct utmp **@var{result}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -@c getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd -@c getutent_r_unknown @mtasurace:utent @acsfd -@c setutent_unknown dup @mtasurace:utent @acsfd -@c getutent_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer -@c LOCK_FILE @mtascusig:ALRM @mtascutimer -@c alarm dup @mtascutimer -@c sigemptyset dup ok -@c sigaction dup ok -@c memset dup ok -@c fcntl_not_cancel dup ok -@c LOCKING_FAILED ok -@c read_not_cancel dup ok -@c UNLOCK_FILE @mtascutimer -@c fcntl_not_cancel dup ok -@c alarm dup @mtascutimer -@c sigaction dup ok -@c memcpy dup ok -@c libc_lock_unlock dup ok -The @code{getutent_r} is equivalent to the @code{getutent} function. It -returns the next entry from the database. But instead of storing the -information in a static buffer it stores it in the buffer pointed to by -the parameter @var{buffer}. - -If the call was successful, the function returns @code{0} and the -pointer variable pointed to by the parameter @var{result} contains a -pointer to the buffer which contains the result (this is most probably -the same value as @var{buffer}). If something went wrong during the -execution of @code{getutent_r} the function returns @code{-1}. - -This function is a GNU extension. -@end deftypefun - -@comment utmp.h -@comment GNU -@deftypefun int getutid_r (const struct utmp *@var{id}, struct utmp *@var{buffer}, struct utmp **@var{result}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -@c getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd -@c getutid_r_unknown @mtasurace:utent @acsfd -@c setutent_unknown dup @mtasurace:utent @acsfd -@c getutid_r_file @mtascusig:ALRM @mtascutimer -@c internal_getut_r @mtascusig:ALRM @mtascutimer -@c LOCK_FILE dup @mtascusig:ALRM @mtascutimer -@c LOCKING_FAILED dup ok -@c read_not_cancel dup ok -@c utmp_equal ok -@c strncmp dup ok -@c UNLOCK_FILE dup @mtascutimer -@c memcpy dup ok -@c libc_lock_unlock dup @aculock -This function retrieves just like @code{getutid} the next entry matching -the information stored in @var{id}. But the result is stored in the -buffer pointed to by the parameter @var{buffer}. - -If successful the function returns @code{0} and the pointer variable -pointed to by the parameter @var{result} contains a pointer to the -buffer with the result (probably the same as @var{result}. If not -successful the function return @code{-1}. - -This function is a GNU extension. -@end deftypefun - -@comment utmp.h -@comment GNU -@deftypefun int getutline_r (const struct utmp *@var{line}, struct utmp *@var{buffer}, struct utmp **@var{result}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -@c getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd -@c getutline_r_unknown @mtasurace:utent @acsfd -@c setutent_unknown dup @mtasurace:utent @acsfd -@c getutline_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer -@c LOCK_FILE @mtascusig:ALRM @mtascutimer -@c alarm dup @mtascutimer -@c sigemptyset dup ok -@c sigaction dup ok -@c memset dup ok -@c fcntl_not_cancel dup ok -@c LOCKING_FAILED ok -@c read_not_cancel dup ok -@c strncmp dup ok -@c UNLOCK_FILE @mtascutimer -@c fcntl_not_cancel dup ok -@c alarm dup @mtascutimer -@c sigaction dup ok -@c memcpy dup ok -@c libc_lock_unlock dup ok -This function retrieves just like @code{getutline} the next entry -matching the information stored in @var{line}. But the result is stored -in the buffer pointed to by the parameter @var{buffer}. - -If successful the function returns @code{0} and the pointer variable -pointed to by the parameter @var{result} contains a pointer to the -buffer with the result (probably the same as @var{result}. If not -successful the function return @code{-1}. - -This function is a GNU extension. -@end deftypefun - - -In addition to the user accounting database, most systems keep a number -of similar databases. For example most systems keep a log file with all -previous logins (usually in @file{/etc/wtmp} or @file{/var/log/wtmp}). - -For specifying which database to examine, the following function should -be used. - -@comment utmp.h -@comment SVID -@deftypefun int utmpname (const char *@var{file}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} -@c utmpname @mtasurace:utent @asulock @ascuheap @aculock @acsmem -@c libc_lock_lock dup @asulock @aculock -@c *libc_utmp_jump_table->endutent dup @mtasurace:utent -@c strcmp dup ok -@c free dup @ascuheap @acsmem -@c strdup dup @ascuheap @acsmem -@c libc_lock_unlock dup @aculock -The @code{utmpname} function changes the name of the database to be -examined to @var{file}, and closes any previously opened database. By -default @code{getutent}, @code{getutid}, @code{getutline} and -@code{pututline} read from and write to the user accounting database. - -The following macros are defined for use as the @var{file} argument: - -@deftypevr Macro {char *} _PATH_UTMP -This macro is used to specify the user accounting database. -@end deftypevr - -@deftypevr Macro {char *} _PATH_WTMP -This macro is used to specify the user accounting log file. -@end deftypevr - -The @code{utmpname} function returns a value of @code{0} if the new name -was successfully stored, and a value of @code{-1} to indicate an error. -Note that @code{utmpname} does not try to open the database, and that -therefore the return value does not say anything about whether the -database can be successfully opened. -@end deftypefun - -Specially for maintaining log-like databases @theglibc{} provides -the following function: - -@comment utmp.h -@comment SVID -@deftypefun void updwtmp (const char *@var{wtmp_file}, const struct utmp *@var{utmp}) -@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}} -@c updwtmp @mtascusig:ALRM @mtascutimer @acsfd -@c TRANSFORM_UTMP_FILE_NAME dup ok -@c *libc_utmp_file_functions->updwtmp = updwtmp_file @mtascusig:ALRM @mtascutimer @acsfd -@c open_not_cancel_2 dup @acsfd -@c LOCK_FILE dup @mtascusig:ALRM @mtascutimer -@c LOCKING_FAILED dup ok -@c lseek64 dup ok -@c ftruncate64 dup ok -@c write_not_cancel dup ok -@c UNLOCK_FILE dup @mtascutimer -@c close_not_cancel_no_status dup @acsfd -The @code{updwtmp} function appends the entry *@var{utmp} to the -database specified by @var{wtmp_file}. For possible values for the -@var{wtmp_file} argument see the @code{utmpname} function. -@end deftypefun - -@strong{Portability Note:} Although many operating systems provide a -subset of these functions, they are not standardized. There are often -subtle differences in the return types, and there are considerable -differences between the various definitions of @code{struct utmp}. When -programming for @theglibc{}, it is probably best to stick -with the functions described in this section. If however, you want your -program to be portable, consider using the XPG functions described in -@ref{XPG Functions}, or take a look at the BSD compatible functions in -@ref{Logging In and Out}. - - -@node XPG Functions -@subsection XPG User Accounting Database Functions - -These functions, described in the X/Open Portability Guide, are declared -in the header file @file{utmpx.h}. -@pindex utmpx.h - -@deftp {Data Type} {struct utmpx} -The @code{utmpx} data structure contains at least the following members: - -@table @code -@item short int ut_type -Specifies the type of login; one of @code{EMPTY}, @code{RUN_LVL}, -@code{BOOT_TIME}, @code{OLD_TIME}, @code{NEW_TIME}, @code{INIT_PROCESS}, -@code{LOGIN_PROCESS}, @code{USER_PROCESS} or @code{DEAD_PROCESS}. - -@item pid_t ut_pid -The process ID number of the login process. - -@item char ut_line[] -The device name of the tty (without @file{/dev/}). - -@item char ut_id[] -The inittab ID of the process. - -@item char ut_user[] -The user's login name. - -@item struct timeval ut_tv -Time the entry was made. For entries of type @code{OLD_TIME} this is -the time when the system clock changed, and for entries of type -@code{NEW_TIME} this is the time the system clock was set to. -@end table -In @theglibc{}, @code{struct utmpx} is identical to @code{struct -utmp} except for the fact that including @file{utmpx.h} does not make -visible the declaration of @code{struct exit_status}. -@end deftp - -The following macros are defined for use as values for the -@code{ut_type} member of the @code{utmpx} structure. The values are -integer constants and are, in @theglibc{}, identical to the -definitions in @file{utmp.h}. - -@vtable @code -@comment utmpx.h -@comment XPG4.2 -@item EMPTY -This macro is used to indicate that the entry contains no valid user -accounting information. - -@comment utmpx.h -@comment XPG4.2 -@item RUN_LVL -This macro is used to identify the system's runlevel. - -@comment utmpx.h -@comment XPG4.2 -@item BOOT_TIME -This macro is used to identify the time of system boot. - -@comment utmpx.h -@comment XPG4.2 -@item OLD_TIME -This macro is used to identify the time when the system clock changed. - -@comment utmpx.h -@comment XPG4.2 -@item NEW_TIME -This macro is used to identify the time after the system clock changed. - -@comment utmpx.h -@comment XPG4.2 -@item INIT_PROCESS -This macro is used to identify a process spawned by the init process. - -@comment utmpx.h -@comment XPG4.2 -@item LOGIN_PROCESS -This macro is used to identify the session leader of a logged in user. - -@comment utmpx.h -@comment XPG4.2 -@item USER_PROCESS -This macro is used to identify a user process. - -@comment utmpx.h -@comment XPG4.2 -@item DEAD_PROCESS -This macro is used to identify a terminated process. -@end vtable - -The size of the @code{ut_line}, @code{ut_id} and @code{ut_user} arrays -can be found using the @code{sizeof} operator. - -@comment utmpx.h -@comment XPG4.2 -@deftypefun void setutxent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -This function is similar to @code{setutent}. In @theglibc{} it is -simply an alias for @code{setutent}. -@end deftypefun - -@comment utmpx.h -@comment XPG4.2 -@deftypefun {struct utmpx *} getutxent (void) -@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} -The @code{getutxent} function is similar to @code{getutent}, but returns -a pointer to a @code{struct utmpx} instead of @code{struct utmp}. In -@theglibc{} it simply is an alias for @code{getutent}. -@end deftypefun - -@comment utmpx.h -@comment XPG4.2 -@deftypefun void endutxent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} -This function is similar to @code{endutent}. In @theglibc{} it is -simply an alias for @code{endutent}. -@end deftypefun - -@comment utmpx.h -@comment XPG4.2 -@deftypefun {struct utmpx *} getutxid (const struct utmpx *@var{id}) -@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} -This function is similar to @code{getutid}, but uses @code{struct utmpx} -instead of @code{struct utmp}. In @theglibc{} it is simply an alias -for @code{getutid}. -@end deftypefun - -@comment utmpx.h -@comment XPG4.2 -@deftypefun {struct utmpx *} getutxline (const struct utmpx *@var{line}) -@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} -This function is similar to @code{getutid}, but uses @code{struct utmpx} -instead of @code{struct utmp}. In @theglibc{} it is simply an alias -for @code{getutline}. -@end deftypefun - -@comment utmpx.h -@comment XPG4.2 -@deftypefun {struct utmpx *} pututxline (const struct utmpx *@var{utmp}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} -The @code{pututxline} function is functionally identical to -@code{pututline}, but uses @code{struct utmpx} instead of @code{struct -utmp}. In @theglibc{}, @code{pututxline} is simply an alias for -@code{pututline}. -@end deftypefun - -@comment utmpx.h -@comment XPG4.2 -@deftypefun int utmpxname (const char *@var{file}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} -The @code{utmpxname} function is functionally identical to -@code{utmpname}. In @theglibc{}, @code{utmpxname} is simply an -alias for @code{utmpname}. -@end deftypefun - -You can translate between a traditional @code{struct utmp} and an XPG -@code{struct utmpx} with the following functions. In @theglibc{}, -these functions are merely copies, since the two structures are -identical. - -@comment utmp.h utmpx.h -@comment GNU -@deftypefun int getutmp (const struct utmpx *@var{utmpx}, struct utmp *@var{utmp}) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -@code{getutmp} copies the information, insofar as the structures are -compatible, from @var{utmpx} to @var{utmp}. -@end deftypefun - -@comment utmp.h utmpx.h -@comment GNU -@deftypefun int getutmpx (const struct utmp *@var{utmp}, struct utmpx *@var{utmpx}) -@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -@code{getutmpx} copies the information, insofar as the structures are -compatible, from @var{utmp} to @var{utmpx}. -@end deftypefun - - -@node Logging In and Out -@subsection Logging In and Out - -These functions, derived from BSD, are available in the separate -@file{libutil} library, and declared in @file{utmp.h}. -@pindex utmp.h - -Note that the @code{ut_user} member of @code{struct utmp} is called -@code{ut_name} in BSD. Therefore, @code{ut_name} is defined as an alias -for @code{ut_user} in @file{utmp.h}. - -@comment utmp.h -@comment BSD -@deftypefun int login_tty (int @var{filedes}) -@safety{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} -@c If this function is canceled, it may have succeeded in redirecting -@c only some of the standard streams to the newly opened terminal. -@c Should there be a safety annotation for this? -@c login_tty @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd -@c setsid dup ok -@c ioctl dup ok -@c ttyname dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd -@c close dup @acsfd -@c open dup @acsfd -@c dup2 dup ok -This function makes @var{filedes} the controlling terminal of the -current process, redirects standard input, standard output and -standard error output to this terminal, and closes @var{filedes}. - -This function returns @code{0} on successful completion, and @code{-1} -on error. -@end deftypefun - -@comment utmp.h -@comment BSD -@deftypefun void login (const struct utmp *@var{entry}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsfd{} @acsmem{}}} -@c login @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acucorrupt @acsfd @acsmem -@c getpid dup ok -@c tty_name @ascuheap @acucorrupt @acsmem @acsfd -@c ttyname_r dup @ascuheap @acsmem @acsfd -@c memchr dup ok -@c realloc dup @ascuheap @acsmem -@c malloc dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c strncmp dup ok -@c basename dup ok -@c strncpy dup ok -@c utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem -@c setutent dup @mtasurace:utent @asulock @aculock @acsfd -@c pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c endutent dup @mtasurace:utent @asulock @aculock -@c free dup @ascuheap @acsmem -@c updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd -The @code{login} functions inserts an entry into the user accounting -database. The @code{ut_line} member is set to the name of the terminal -on standard input. If standard input is not a terminal @code{login} -uses standard output or standard error output to determine the name of -the terminal. If @code{struct utmp} has a @code{ut_type} member, -@code{login} sets it to @code{USER_PROCESS}, and if there is an -@code{ut_pid} member, it will be set to the process ID of the current -process. The remaining entries are copied from @var{entry}. - -A copy of the entry is written to the user accounting log file. -@end deftypefun - -@comment utmp.h -@comment BSD -@deftypefun int logout (const char *@var{ut_line}) -@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} -@c logout @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acsfd @acsmem -@c utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem -@c setutent dup @mtasurace:utent @asulock @aculock @acsfd -@c strncpy dup ok -@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c bzero dup ok -@c gettimeofday dup ok -@c time dup ok -@c pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd -@c endutent dup @mtasurace:utent @asulock @aculock -This function modifies the user accounting database to indicate that the -user on @var{ut_line} has logged out. - -The @code{logout} function returns @code{1} if the entry was successfully -written to the database, or @code{0} on error. -@end deftypefun - -@comment utmp.h -@comment BSD -@deftypefun void logwtmp (const char *@var{ut_line}, const char *@var{ut_name}, const char *@var{ut_host}) -@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}} -@c logwtmp @mtascusig:ALRM @mtascutimer @acsfd -@c memset dup ok -@c getpid dup ok -@c strncpy dup ok -@c gettimeofday dup ok -@c time dup ok -@c updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd -The @code{logwtmp} function appends an entry to the user accounting log -file, for the current time and the information provided in the -@var{ut_line}, @var{ut_name} and @var{ut_host} arguments. -@end deftypefun - -@strong{Portability Note:} The BSD @code{struct utmp} only has the -@code{ut_line}, @code{ut_name}, @code{ut_host} and @code{ut_time} -members. Older systems do not even have the @code{ut_host} member. - - -@node User Database -@section User Database -@cindex user database -@cindex password database -@pindex /etc/passwd - -This section describes how 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:: What each user record contains. -* Lookup User:: How to look for a particular user. -* Scanning All Users:: Scanning the list of all users, one by one. -* Writing a User Entry:: How a program can rewrite a user's record. -@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 {Data Type} {struct 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}) -@safety{@prelim{}@mtunsafe{@mtasurace{:pwuid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getpwuid @mtasurace:pwuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock dup @asulock @aculock -@c malloc dup @ascuheap @acsmem -@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c realloc dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c libc_lock_unlock dup @aculock -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.1c -@deftypefun int getpwuid_r (uid_t @var{uid}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) -@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nscd_getpwuid_r @ascuheap @acsfd @acsmem -@c itoa_word dup ok -@c nscd_getpw_r @ascuheap @acsfd @acsmem -@c nscd_get_map_ref @ascuheap @acsfd @acsmem -@c nscd_acquire_maplock ok -@c nscd_get_mapping @ascuheap @acsfd @acsmem -@c open_socket dup @acsfd -@c memset dup ok -@c wait_on_socket dup ok -@c recvmsg dup ok -@c strcmp dup ok -@c fstat64 dup ok -@c mmap dup @acsmem -@c munmap dup @acsmem -@c malloc dup @ascuheap @acsmem -@c close dup ok -@c nscd_unmap dup @ascuheap @acsmem -@c nscd_cache_search ok -@c nis_hash ok -@c memcmp dup ok -@c nscd_open_socket @acsfd -@c open_socket @acsfd -@c socket dup @acsfd -@c fcntl dup ok -@c strcpy dup ok -@c connect dup ok -@c send dup ok -@c gettimeofday dup ok -@c poll dup ok -@c close_not_cancel_no_status dup @acsfd -@c wait_on_socket dup ok -@c read dup ok -@c close_not_cancel_no_status dup @acsfd -@c readall ok -@c read dup ok -@c wait_on_socket ok -@c poll dup ok -@c gettimeofday dup ok -@c memcpy dup ok -@c close_not_cancel_no_status dup @acsfd -@c nscd_drop_map_ref @ascuheap @acsmem -@c nscd_unmap dup @ascuheap @acsmem -@c nscd_unmap @ascuheap @acsmem -@c munmap dup ok -@c free dup @ascuheap @acsmem -@c nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_database_lookup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock -@c libc_lock_lock @asulock @aculock -@c libc_lock_unlock @aculock -@c nss_parse_file @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock -@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock -@c fsetlocking dup ok [no concurrent uses] -@c malloc dup @asulock @aculock @acsfd @acsmem -@c fclose dup @ascuheap @asulock @acsmem @acsfd @aculock -@c getline dup @ascuheap @aculock @acucorrupt @acsmem -@c strchrnul dup ok -@c nss_getline @mtslocale @ascuheap @acsmem -@c isspace @mtslocale^^ -@c strlen dup ok -@c malloc dup @asulock @aculock @acsfd @acsmem -@c memcpy dup ok -@c nss_parse_service_list dup @mtslocale^, @ascuheap @acsmem -@c feof_unlocked dup ok -@c free dup @asulock @aculock @acsfd @acsmem -@c strcmp dup ok -@c nss_parse_service_list @mtslocale^, @ascuheap @acsmem -@c isspace @mtslocale^^ -@c malloc dup @asulock @aculock @acsfd @acsmem -@c mempcpy dup ok -@c strncasecmp dup ok -@c free dup @asulock @aculock @acsfd @acsmem -@c malloc dup @asulock @aculock @acsfd @acsmem -@c nss_lookup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_lookup_function @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock @asulock @aculock -@c tsearch @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking] -@c known_compare ok -@c strcmp dup ok -@c malloc dup @ascuheap @acsmem -@c tdelete @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking] -@c free dup @ascuheap @acsmem -@c nss_load_library @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem -@c nss_new_service @ascuheap @acsmem -@c strcmp dup ok -@c malloc dup @ascuheap @acsmem -@c strlen dup ok -@c stpcpy dup ok -@c libc_dlopen @ascudlopen @ascuheap @asulock @aculock @acsfd @acsmem -@c libc_dlsym dup @asulock @aculock @acsfd @acsmem -@c *ifct(*nscd_init_cb) @ascuplugin -@c stpcpy dup ok -@c libc_dlsym dup @asulock @aculock @acsfd @acsmem -@c libc_lock_unlock dup ok -@c nss_next_action ok -@c *fct.l -> _nss_*_getpwuid_r @ascuplugin -@c nss_next2 @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_next_action dup ok -@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem - -@c _nss_files_getpwuid_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd -@c libc_lock_lock dup @asulock @aculock -@c internal_setent @ascuheap @asulock @aculock @acsmem @acsfd -@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock -@c fileno dup ok -@c fcntl dup ok -@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd -@c rewind dup @aculock [stream guarded by non-recursive pwent lock] -@c internal_getent @mtslocale^ -@c fgets_unlocked dup ok [stream guarded by non-recursive pwent lock] -@c isspace dup @mtslocale^^ -@c _nss_files_parse_pwent = parse_line ok -@c strpbrk dup ok -@c internal_endent @ascuheap @asulock @aculock @acsmem @acsfd -@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd -@c libc_lock_unlock dup @aculock - -@c _nss_nis_getpwuid_r ... not fully reviewed (assumed) @asuinit @asulock @acucorrupt @aculock -@c yp_get_default_domain @asulock @aculock -@c libc_lock_lock dup @asulock @aculock -@c getdomainname dup ok -@c strcmp dup ok -@c libc_lock_unlock dup @aculock -@c snprintf dup @ascuheap @acsmem -@c yp_match -@c do_ypcall_tr(xdr_ypreq_key,xdr_ypresp_val) -@c do_ypcall(xdr_ypreq_key,xdr_ypresp_val) -@c libc_lock_lock @asulock @aculock -@c strcmp -@c yp_bind -@c ypclnt_call -@c clnt_call -@c clnt_perror -@c libc_lock_unlock @aculock -@c yp_unbind_locked -@c yp_unbind -@c strcmp dup ok -@c calloc dup @asulock @aculock @acsfd @acsmem -@c yp_bind_file -@c strlen dup ok -@c snprintf dup @ascuheap @acsmem -@c open dup @acsfd [cancelpt] -@c pread dup [cancelpt] -@c yp_bind_client_create -@c close dup @acsfd [cancelpt] -@c yp_bind_ypbindprog -@c clnttcp_create -@c clnt_destroy -@c clnt_call(xdr_domainname,xdr_ypbind_resp) -@c memset dup ok -@c yp_bind_client_create -@c free dup @asulock @aculock @acsfd @acsmem -@c calloc dup @asulock @aculock @acsfd @acsmem -@c free dup @asulock @aculock @acsfd @acsmem -@c ypprot_err -@c memcpy dup ok -@c xdr_free(xdr_ypresp_val) -@c xdr_ypresp_val -@c xdr_ypstat -@c xdr_enum -@c XDR_PUTLONG -@c *x_putlong -@c XDR_GETLONG -@c *x_getlong -@c xdr_long -@c XDR_PUTLONG dup -@c XDR_GETLONG dup -@c xdr_short -@c XDR_PUTLONG dup -@c XDR_GETLONG dup -@c xdr_valdat -@c xdr_bytes -@c xdr_u_int -@c XDR_PUTLONG dup -@c XDR_GETLONG dup -@c mem_alloc @ascuheap @acsmem -@c malloc dup @ascuheap @acsmem -@c xdr_opaque -@c XDR_GETBYTES -@c *x_getbytes -@c XDR_PUTBYTES -@c *x_putbytes -@c mem_free @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c yperr2nss ok -@c strchr dup ok -@c _nls_default_nss @asuinit @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock -@c init @asuinit^, @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock -@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock -@c fsetlocking ok [no concurrent uses] -@c feof_unlocked dup ok -@c getline dup @ascuheap @aculock @acucorrupt @acsmem -@c isspace dup @mtslocale^^ -@c strncmp dup ok -@c free dup @asulock @acsmem @acsfd @aculock -@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd -@c free dup @asulock @acsmem @acsfd @aculock -@c mempcpy dup ok -@c strncpy dup ok -@c isspace dup @mtslocale^^ -@c _nss_files_parse_pwent ok -This function is similar to @code{getpwuid} in that it returns -information about the user whose user ID is @var{uid}. However, it -fills the user supplied structure pointed to by @var{result_buf} with -the information instead of using a static buffer. The first -@var{buflen} bytes of the additional buffer pointed to by @var{buffer} -are used to contain additional information, normally strings which are -pointed to by the elements of the result structure. - -If a user with ID @var{uid} is found, the pointer returned in -@var{result} points to the record which contains the wanted data (i.e., -@var{result} contains the value @var{result_buf}). If no user is found -or if an error occurred, the pointer returned in @var{result} is a null -pointer. The function returns zero or an error code. If the buffer -@var{buffer} is too small to contain all the needed information, the -error code @code{ERANGE} is returned and @var{errno} is set to -@code{ERANGE}. -@end deftypefun - - -@comment pwd.h -@comment POSIX.1 -@deftypefun {struct passwd *} getpwnam (const char *@var{name}) -@safety{@prelim{}@mtunsafe{@mtasurace{:pwnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getpwnam @mtasurace:pwnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock dup @asulock @aculock -@c malloc dup @ascuheap @acsmem -@c getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c realloc dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c libc_lock_unlock dup @aculock -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 return indicates there is no user named @var{name}. -@end deftypefun - -@comment pwd.h -@comment POSIX.1c -@deftypefun int getpwnam_r (const char *@var{name}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) -@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getpwnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nscd_getpwnam_r @ascuheap @asulock @aculock @acsfd @acsmem -@c strlen dup ok -@c nscd_getpw_r dup @ascuheap @asulock @aculock @acsfd @acsmem -@c nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct.l @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c -@c _nss_files_getpwnam_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd -@c libc_lock_lock dup @asulock @aculock -@c internal_setent dup @ascuheap @asulock @aculock @acsmem @acsfd -@c internal_getent dup @mtslocale^ -@c strcmp dup ok -@c internal_endent dup @ascuheap @asulock @aculock @acsmem @acsfd -@c libc_lock_unlock dup @aculock -@c -@c _nss_*_getpwnam_r (assumed) @asuinit @asulock @acucorrupt @aculock - -This function is similar to @code{getpwnam} in that it returns -information about the user whose user name is @var{name}. However, like -@code{getpwuid_r}, it fills the user supplied buffers in -@var{result_buf} and @var{buffer} with the information instead of using -a static buffer. - -The return values are the same as for @code{getpwuid_r}. -@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}. - -You can use the @code{fgetpwent} function to read user entries from a -particular file. - -@comment pwd.h -@comment SVID -@deftypefun {struct passwd *} fgetpwent (FILE *@var{stream}) -@safety{@prelim{}@mtunsafe{@mtasurace{:fpwent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}} -@c fgetpwent @mtasurace:fpwent @asucorrupt @asulock @acucorrupt @aculock -@c fgetpos dup @asucorrupt @aculock @acucorrupt -@c libc_lock_lock dup @asulock @aculock -@c malloc dup @ascuheap @acsmem -@c fgetpwent_r dup @asucorrupt @acucorrupt @aculock -@c realloc dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c fsetpos dup @asucorrupt @aculock @acucorrupt -@c libc_lock_unlock dup @aculock -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{fgetpwent}. 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 -password database file. -@end deftypefun - -@comment pwd.h -@comment GNU -@deftypefun int fgetpwent_r (FILE *@var{stream}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} -@c fgetpwent_r @asucorrupt @acucorrupt @aculock -@c flockfile dup @aculock -@c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking] -@c feof_unlocked dup ok -@c funlockfile dup @aculock -@c isspace dup @mtslocale^^ -@c parse_line dup ok -This function is similar to @code{fgetpwent} in that it reads the next -user entry from @var{stream}. But the result is returned in the -structure pointed to by @var{result_buf}. The -first @var{buflen} bytes of the additional buffer pointed to by -@var{buffer} are used to contain additional information, normally -strings which are pointed to by the elements of the result structure. - -The stream must correspond to a file in the same format as the standard -password database file. - -If the function returns zero @var{result} points to the structure with -the wanted data (normally this is in @var{result_buf}). If errors -occurred the return value is nonzero and @var{result} contains a null -pointer. -@end deftypefun - -The way to scan all the entries in the user database is with -@code{setpwent}, @code{getpwent}, and @code{endpwent}. - -@comment pwd.h -@comment SVID, BSD -@deftypefun void setpwent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c setpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock @asulock @aculock -@c nss_setent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c ** resolv's res_maybe_init not called here -@c setup(nss_passwd_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *lookup_fct = nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct.f @mtasurace:pwent @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_unlock @aculock -This function initializes a stream which @code{getpwent} and -@code{getpwent_r} use to read the user database. -@end deftypefun - -@comment pwd.h -@comment POSIX.1 -@deftypefun {struct passwd *} getpwent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtasurace{:pwentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getpwent @mtasurace:pwent @mtasurace:pwentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock dup @asulock @aculock -@c nss_getent(getpwent_r) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c malloc dup @ascuheap @acsmem -@c *func = getpwent_r dup @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c realloc dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c libc_lock_unlock dup @aculock -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. - -A null pointer is returned when no more entries are available. -@end deftypefun - -@comment pwd.h -@comment GNU -@deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) -@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c The static buffer here is not the result_buf, but rather the -@c variables that keep track of what nss backend we've last used, and -@c whatever internal state the nss backend uses to keep track of the -@c last read entry. -@c getpwent_r @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock dup @asulock @aculock -@c nss_getent_r(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct.f @mtasurace:pwent @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *sfct.f @mtasurace:pwent @ascuplugin -@c libc_lock_unlock dup @aculock -This function is similar to @code{getpwent} in that it returns the next -entry from the stream initialized by @code{setpwent}. Like -@code{fgetpwent_r}, it uses the user-supplied buffers in -@var{result_buf} and @var{buffer} to return the information requested. - -The return values are the same as for @code{fgetpwent_r}. - -@end deftypefun - -@comment pwd.h -@comment SVID, BSD -@deftypefun void endpwent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c endpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock @asulock @aculock -@c nss_endent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c ** resolv's res_maybe_init not called here -@c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct.f @mtasurace:pwent @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_unlock @aculock -This function closes the internal stream used by @code{getpwent} or -@code{getpwent_r}. -@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}) -@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} -@c putpwent @mtslocale @asucorrupt @aculock @acucorrupt -@c fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem] -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 nonzero 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. -@c Then how are programmers to modify the password file? -zw - -The group and user ID fields are left empty if the group or user name -starts with a - or +. - -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 how 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:: What each group record contains. -* Lookup Group:: How to look for a particular group. -* Scanning All Groups:: Scanning the list of 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}) -@safety{@prelim{}@mtunsafe{@mtasurace{:grgid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getgrgid =~ getpwuid dup @mtasurace:grgid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c getgrgid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -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.1c -@deftypefun int getgrgid_r (gid_t @var{gid}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) -@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getgrgid_r =~ getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nscd_getgrgid_r @ascuheap @acsfd @acsmem -@c itoa_word dup ok -@c nscd_getgr_r @ascuheap @acsfd @acsmem -@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem -@c nscd_cache_search dup ok -@c nscd_open_socket dup @acsfd -@c readvall ok -@c readv dup ok -@c memcpy dup ok -@c wait_on_socket dup ok -@c memcpy dup ok -@c readall dup ok -@c close_not_cancel_no_status dup @acsfd -@c nscd_drop_map_ref dup @ascuheap @acsmem -@c nscd_unmap dup @ascuheap @acsmem -@c nss_group_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct.l -> _nss_*_getgrgid_r @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -This function is similar to @code{getgrgid} in that it returns -information about the group whose group ID is @var{gid}. However, it -fills the user supplied structure pointed to by @var{result_buf} with -the information instead of using a static buffer. The first -@var{buflen} bytes of the additional buffer pointed to by @var{buffer} -are used to contain additional information, normally strings which are -pointed to by the elements of the result structure. - -If a group with ID @var{gid} is found, the pointer returned in -@var{result} points to the record which contains the wanted data (i.e., -@var{result} contains the value @var{result_buf}). If no group is found -or if an error occurred, the pointer returned in @var{result} is a null -pointer. The function returns zero or an error code. If the buffer -@var{buffer} is too small to contain all the needed information, the -error code @code{ERANGE} is returned and @var{errno} is set to -@code{ERANGE}. -@end deftypefun - -@comment grp.h -@comment SVID, BSD -@deftypefun {struct group *} getgrnam (const char *@var{name}) -@safety{@prelim{}@mtunsafe{@mtasurace{:grnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getgrnam =~ getpwnam dup @mtasurace:grnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c getgrnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -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 - -@comment grp.h -@comment POSIX.1c -@deftypefun int getgrnam_r (const char *@var{name}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) -@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getgrnam_r =~ getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nscd_getgrnam_r @ascuheap @asulock @aculock @acsfd @acsmem -@c strlen dup ok -@c nscd_getgr_r dup @ascuheap @asulock @aculock @acsfd @acsmem -@c nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct.l @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -This function is similar to @code{getgrnam} in that it returns -information about the group whose group name is @var{name}. Like -@code{getgrgid_r}, it uses the user supplied buffers in -@var{result_buf} and @var{buffer}, not a static buffer. - -The return values are the same as for @code{getgrgid_r}. -@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}. - -You can use the @code{fgetgrent} function to read group entries from a -particular file. - -@comment grp.h -@comment SVID -@deftypefun {struct group *} fgetgrent (FILE *@var{stream}) -@safety{@prelim{}@mtunsafe{@mtasurace{:fgrent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}} -@c fgetgrent @mtasurace:fgrent @asucorrupt @asulock @acucorrupt @aculock -@c fgetpos dup @asucorrupt @aculock @acucorrupt -@c libc_lock_lock dup @asulock @aculock -@c malloc dup @ascuheap @acsmem -@c fgetgrent_r dup @asucorrupt @acucorrupt @aculock -@c realloc dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c fsetpos dup @asucorrupt @aculock @acucorrupt -@c libc_lock_unlock dup @aculock -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 overwritten on subsequent calls to @code{fgetgrent}. 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 - -@comment grp.h -@comment GNU -@deftypefun int fgetgrent_r (FILE *@var{stream}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) -@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} -@c fgetgrent_r @asucorrupt @acucorrupt @aculock -@c flockfile dup @aculock -@c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking] -@c feof_unlocked dup ok -@c funlockfile dup @aculock -@c isspace dup @mtslocale^^ -@c parse_line dup ok -This function is similar to @code{fgetgrent} in that it reads the next -user entry from @var{stream}. But the result is returned in the -structure pointed to by @var{result_buf}. The first @var{buflen} bytes -of the additional buffer pointed to by @var{buffer} are used to contain -additional information, normally strings which are pointed to by the -elements of the result structure. - -This stream must correspond to a file in the same format as the standard -group database file. - -If the function returns zero @var{result} points to the structure with -the wanted data (normally this is in @var{result_buf}). If errors -occurred the return value is non-zero and @var{result} contains a null -pointer. -@end deftypefun - -The way to scan all the entries in the group database is with -@code{setgrent}, @code{getgrent}, and @code{endgrent}. - -@comment grp.h -@comment SVID, BSD -@deftypefun void setgrent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c setgrent =~ setpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c ...*lookup_fct = nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -This function initializes a stream for reading from the group data base. -You use this stream by calling @code{getgrent} or @code{getgrent_r}. -@end deftypefun - -@comment grp.h -@comment SVID, BSD -@deftypefun {struct group *} getgrent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtasurace{:grentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getgrent =~ getpwent dup @mtasurace:grent @mtasurace:grentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *func = getgrent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -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 overwritten 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 GNU -@deftypefun int getgrent_r (struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) -@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getgrent_r =~ getpwent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -This function is similar to @code{getgrent} in that it returns the next -entry from the stream initialized by @code{setgrent}. Like -@code{fgetgrent_r}, it places the result in user-supplied buffers -pointed to by @var{result_buf} and @var{buffer}. - -If the function returns zero @var{result} contains a pointer to the data -(normally equal to @var{result_buf}). If errors occurred the return -value is non-zero and @var{result} contains a null pointer. -@end deftypefun - -@comment grp.h -@comment SVID, BSD -@deftypefun void endgrent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c endgrent =~ endpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -This function closes the internal stream used by @code{getgrent} or -@code{getgrent_r}. -@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. - -@smallexample -@include db.c.texi -@end smallexample - -Here is some output from this program: - -@smallexample -I am Throckmorton Snurd. -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 - tami -@end smallexample - -@node Netgroup Database -@section Netgroup Database - -@menu -* Netgroup Data:: Data in the Netgroup database and where - it comes from. -* Lookup Netgroup:: How to look for a particular netgroup. -* Netgroup Membership:: How to test for netgroup membership. -@end menu - -@node Netgroup Data -@subsection Netgroup Data - -@cindex Netgroup -Sometimes it is useful to group users according to other criteria -(@pxref{Group Database}). E.g., it is useful to associate a certain -group of users with a certain machine. On the other hand grouping of -host names is not supported so far. - -In Sun Microsystems' SunOS appeared a new kind of database, the netgroup -database. It allows grouping hosts, users, and domains freely, giving -them individual names. To be more concrete, a netgroup is a list of triples -consisting of a host name, a user name, and a domain name where any of -the entries can be a wildcard entry matching all inputs. A last -possibility is that names of other netgroups can also be given in the -list specifying a netgroup. So one can construct arbitrary hierarchies -without loops. - -Sun's implementation allows netgroups only for the @code{nis} or -@code{nisplus} service, @pxref{Services in the NSS configuration}. The -implementation in @theglibc{} has no such restriction. An entry -in either of the input services must have the following form: - -@smallexample -@var{groupname} ( @var{groupname} | @code{(}@var{hostname}@code{,}@var{username}@code{,}@code{domainname}@code{)} )+ -@end smallexample - -Any of the fields in the triple can be empty which means anything -matches. While describing the functions we will see that the opposite -case is useful as well. I.e., there may be entries which will not -match any input. For entries like this, a name consisting of the single -character @code{-} shall be used. - -@node Lookup Netgroup -@subsection Looking up one Netgroup - -The lookup functions for netgroups are a bit different than all other -system database handling functions. Since a single netgroup can contain -many entries a two-step process is needed. First a single netgroup is -selected and then one can iterate over all entries in this netgroup. -These functions are declared in @file{netdb.h}. - -@comment netdb.h -@comment BSD -@deftypefun int setnetgrent (const char *@var{netgroup}) -@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c setnetgrent @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock dup @asulock @aculock -@c nscd_setnetgrent @ascuheap @acsfd @acsmem -@c __nscd_setnetgrent @ascuheap @acsfd @acsmem -@c strlen dup ok -@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem -@c nscd_cache_search dup ok -@c nscd_open_socket dup @acsfd -@c malloc dup @ascuheap @acsmem -@c readall dup ok -@c free dup @ascuheap @acsmem -@c close_not_cancel_no_status dup @acsfd -@c nscd_drop_map_ref dup @ascuheap @acsmem -@c nscd_unmap dup @ascuheap @acsmem -@c internal_setnetgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c free_memory dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c internal_setnetgrent_reuse @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *endfct @ascuplugin -@c (netgroup::)setup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_netgroup_lookup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_netgroup_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct.f @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *endfct @ascuplugin -@c strlen dup ok -@c malloc dup @ascuheap @acsmem -@c memcpy dup ok -@c libc_lock_unlock dup @aculock -A call to this function initializes the internal state of the library to -allow following calls of @code{getnetgrent} to iterate over all entries -in the netgroup with name @var{netgroup}. - -When the call is successful (i.e., when a netgroup with this name exists) -the return value is @code{1}. When the return value is @code{0} no -netgroup of this name is known or some other error occurred. -@end deftypefun - -It is important to remember that there is only one single state for -iterating the netgroups. Even if the programmer uses the -@code{getnetgrent_r} function the result is not really reentrant since -always only one single netgroup at a time can be processed. If the -program needs to process more than one netgroup simultaneously she -must protect this by using external locking. This problem was -introduced in the original netgroups implementation in SunOS and since -we must stay compatible it is not possible to change this. - -Some other functions also use the netgroups state. Currently these are -the @code{innetgr} function and parts of the implementation of the -@code{compat} service part of the NSS implementation. - -@comment netdb.h -@comment BSD -@deftypefun int getnetgrent (char **@var{hostp}, char **@var{userp}, char **@var{domainp}) -@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtasurace{:netgrentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getnetgrent @mtasurace:netgrent @mtasurace:netgrentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c uses unsafely a static buffer allocated within a libc_once call -@c allocate (libc_once) @ascuheap @acsmem -@c malloc dup @ascuheap @acsmem -@c getnetgrent_r dup @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -This function returns the next unprocessed entry of the currently -selected netgroup. The string pointers, in which addresses are passed in -the arguments @var{hostp}, @var{userp}, and @var{domainp}, will contain -after a successful call pointers to appropriate strings. If the string -in the next entry is empty the pointer has the value @code{NULL}. -The returned string pointers are only valid if none of the netgroup -related functions are called. - -The return value is @code{1} if the next entry was successfully read. A -value of @code{0} means no further entries exist or internal errors occurred. -@end deftypefun - -@comment netdb.h -@comment GNU -@deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, size_t @var{buflen}) -@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c getnetgrent_r @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock dup @asulock @aculock -@c internal_getnetgrent_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *fct @ascuplugin -@c nscd_getnetgrent ok -@c rawmemchr dup ok -@c internal_setnetgrent_reuse dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c strcmp dup ok -@c malloc dup @ascuheap @acsmem -@c memcpy dup ok -@c libc_lock_unlock dup @aculock -This function is similar to @code{getnetgrent} with only one exception: -the strings the three string pointers @var{hostp}, @var{userp}, and -@var{domainp} point to, are placed in the buffer of @var{buflen} bytes -starting at @var{buffer}. This means the returned values are valid -even after other netgroup related functions are called. - -The return value is @code{1} if the next entry was successfully read and -the buffer contains enough room to place the strings in it. @code{0} is -returned in case no more entries are found, the buffer is too small, or -internal errors occurred. - -This function is a GNU extension. The original implementation in the -SunOS libc does not provide this function. -@end deftypefun - -@comment netdb.h -@comment BSD -@deftypefun void endnetgrent (void) -@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c endnetgrent @mtasurace:netgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c libc_lock_lock dup @asulock @aculock -@c internal_endnetgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c free_memory dup @ascuheap @acsmem -@c libc_lock_unlock dup @aculock -This function frees all buffers which were allocated to process the last -selected netgroup. As a result all string pointers returned by calls -to @code{getnetgrent} are invalid afterwards. -@end deftypefun - -@node Netgroup Membership -@subsection Testing for Netgroup Membership - -It is often not necessary to scan the whole netgroup since often the -only interesting question is whether a given entry is part of the -selected netgroup. - -@comment netdb.h -@comment BSD -@deftypefun int innetgr (const char *@var{netgroup}, const char *@var{host}, const char *@var{user}, const char *@var{domain}) -@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} -@c This function does not use the static data structure that the -@c *netgrent* ones do, but since each nss must maintains internal state -@c to support iteration and concurrent iteration will interfere -@c destructively, we regard this internal state as a static buffer. -@c getnetgrent_r iteration in each nss backend. -@c innetgr @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c nscd_innetgr @ascuheap @acsfd @acsmem -@c strlen dup ok -@c malloc dup @ascuheap @acsmem -@c stpcpy dup ok -@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem -@c nscd_cache_search dup ok -@c nscd_open_socket dup @acsfd -@c close_not_cancel_no_status dup @acsfd -@c nscd_drop_map_ref dup @ascuheap @acsmem -@c nscd_unmap dup @ascuheap @acsmem -@c free dup @ascuheap @acsmem -@c memset dup ok -@c (netgroup::)setup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *setfct.f @ascuplugin -@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c *getfct @ascuplugin -@c strcmp dup ok -@c strlen dup ok -@c malloc dup @ascuheap @acsmem -@c memcpy dup ok -@c strcasecmp dup -@c *endfct @ascuplugin -@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem -@c free_memory dup @ascuheap @acsmem -This function tests whether the triple specified by the parameters -@var{host}, @var{user}, and @var{domain} is part of the netgroup -@var{netgroup}. Using this function has the advantage that - -@enumerate -@item -no other netgroup function can use the global netgroup state since -internal locking is used and -@item -the function is implemented more efficiently than successive calls -to the other @code{set}/@code{get}/@code{endnetgrent} functions. -@end enumerate - -Any of the pointers @var{host}, @var{user}, or @var{domain} can be -@code{NULL} which means any value is accepted in this position. This is -also true for the name @code{-} which should not match any other string -otherwise. - -The return value is @code{1} if an entry matching the given triple is -found in the netgroup. The return value is @code{0} if the netgroup -itself is not found, the netgroup does not contain the triple or -internal errors occurred. -@end deftypefun - -@c FIXME these are undocumented: -@c setresgid -@c setresuid |