blob: e8f0f3bdf3aa37467b001a888c3bb3d36a5a70da [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001@node Users and Groups, System Management, Name Service Switch, Top
2@c %MENU% How users are identified and classified
3@chapter Users and Groups
4
5Every user who can log in on the system is identified by a unique number
6called the @dfn{user ID}. Each process has an effective user ID which
7says which user's access permissions it has.
8
9Users are classified into @dfn{groups} for access control purposes. Each
10process has one or more @dfn{group ID values} which say which groups the
11process can use for access to files.
12
13The effective user and group IDs of a process collectively form its
14@dfn{persona}. This determines which files the process can access.
15Normally, a process inherits its persona from the parent process, but
16under special circumstances a process can change its persona and thus
17change its access permissions.
18
19Each file in the system also has a user ID and a group ID. Access
20control works by comparing the user and group IDs of the file with those
21of the running process.
22
23The system keeps a database of all the registered users, and another
24database of all the defined groups. There are library functions you
25can use to examine these databases.
26
27@menu
28* User and Group IDs:: Each user has a unique numeric ID;
29 likewise for groups.
30* Process Persona:: The user IDs and group IDs of a process.
31* Why Change Persona:: Why a program might need to change
32 its user and/or group IDs.
33* How Change Persona:: Changing the user and group IDs.
34* Reading Persona:: How to examine the user and group IDs.
35
36* Setting User ID:: Functions for setting the user ID.
37* Setting Groups:: Functions for setting the group IDs.
38
39* Enable/Disable Setuid:: Turning setuid access on and off.
40* Setuid Program Example:: The pertinent parts of one sample program.
41* Tips for Setuid:: How to avoid granting unlimited access.
42
43* Who Logged In:: Getting the name of the user who logged in,
44 or of the real user ID of the current process.
45
46* User Accounting Database:: Keeping information about users and various
47 actions in databases.
48
49* User Database:: Functions and data structures for
50 accessing the user database.
51* Group Database:: Functions and data structures for
52 accessing the group database.
53* Database Example:: Example program showing the use of database
54 inquiry functions.
55* Netgroup Database:: Functions for accessing the netgroup database.
56@end menu
57
58@node User and Group IDs
59@section User and Group IDs
60
61@cindex login name
62@cindex user name
63@cindex user ID
64Each user account on a computer system is identified by a @dfn{user
65name} (or @dfn{login name}) and @dfn{user ID}. Normally, each user name
66has a unique user ID, but it is possible for several login names to have
67the same user ID. The user names and corresponding user IDs are stored
68in a data base which you can access as described in @ref{User Database}.
69
70@cindex group name
71@cindex group ID
72Users are classified in @dfn{groups}. Each user name belongs to one
73@dfn{default group} and may also belong to any number of
74@dfn{supplementary groups}. Users who are members of the same group can
75share resources (such as files) that are not accessible to users who are
76not a member of that group. Each group has a @dfn{group name} and
77@dfn{group ID}. @xref{Group Database}, for how to find information
78about a group ID or group name.
79
80@node Process Persona
81@section The Persona of a Process
82@cindex persona
83@cindex effective user ID
84@cindex effective group ID
85@cindex supplementary group IDs
86
87@c When Hurd is more widely used, explain multiple effective user IDs
88@c here. -zw
89At any time, each process has an @dfn{effective user ID}, a @dfn{effective
90group ID}, and a set of @dfn{supplementary group IDs}. These IDs
91determine the privileges of the process. They are collectively
92called the @dfn{persona} of the process, because they determine ``who it
93is'' for purposes of access control.
94
95Your login shell starts out with a persona which consists of your user
96ID, your default group ID, and your supplementary group IDs (if you are
97in more than one group). In normal circumstances, all your other processes
98inherit these values.
99
100@cindex real user ID
101@cindex real group ID
102A process also has a @dfn{real user ID} which identifies the user who
103created the process, and a @dfn{real group ID} which identifies that
104user's default group. These values do not play a role in access
105control, so we do not consider them part of the persona. But they are
106also important.
107
108Both the real and effective user ID can be changed during the lifetime
109of a process. @xref{Why Change Persona}.
110
111For details on how a process's effective user ID and group IDs affect
112its permission to access files, see @ref{Access Permission}.
113
114The effective user ID of a process also controls permissions for sending
115signals using the @code{kill} function. @xref{Signaling Another
116Process}.
117
118Finally, there are many operations which can only be performed by a
119process whose effective user ID is zero. A process with this user ID is
120a @dfn{privileged process}. Commonly the user name @code{root} is
121associated with user ID 0, but there may be other user names with this
122ID.
123@c !!! should mention POSIX capabilities here.
124
125@node Why Change Persona
126@section Why Change the Persona of a Process?
127
128The most obvious situation where it is necessary for a process to change
129its user and/or group IDs is the @code{login} program. When
130@code{login} starts running, its user ID is @code{root}. Its job is to
131start a shell whose user and group IDs are those of the user who is
132logging in. (To accomplish this fully, @code{login} must set the real
133user and group IDs as well as its persona. But this is a special case.)
134
135The more common case of changing persona is when an ordinary user
136program needs access to a resource that wouldn't ordinarily be
137accessible to the user actually running it.
138
139For example, you may have a file that is controlled by your program but
140that shouldn't be read or modified directly by other users, either
141because it implements some kind of locking protocol, or because you want
142to preserve the integrity or privacy of the information it contains.
143This kind of restricted access can be implemented by having the program
144change its effective user or group ID to match that of the resource.
145
146Thus, imagine a game program that saves scores in a file. The game
147program itself needs to be able to update this file no matter who is
148running it, but if users can write the file without going through the
149game, they can give themselves any scores they like. Some people
150consider this undesirable, or even reprehensible. It can be prevented
151by creating a new user ID and login name (say, @code{games}) to own the
152scores file, and make the file writable only by this user. Then, when
153the game program wants to update this file, it can change its effective
154user ID to be that for @code{games}. In effect, the program must
155adopt the persona of @code{games} so it can write the scores file.
156
157@node How Change Persona
158@section How an Application Can Change Persona
159@cindex @code{setuid} programs
160@cindex saved set-user-ID
161@cindex saved set-group-ID
162@cindex @code{_POSIX_SAVED_IDS}
163
164The ability to change the persona of a process can be a source of
165unintentional privacy violations, or even intentional abuse. Because of
166the potential for problems, changing persona is restricted to special
167circumstances.
168
169You can't arbitrarily set your user ID or group ID to anything you want;
170only privileged processes can do that. Instead, the normal way for a
171program to change its persona is that it has been set up in advance to
172change to a particular user or group. This is the function of the setuid
173and setgid bits of a file's access mode. @xref{Permission Bits}.
174
175When the setuid bit of an executable file is on, executing that file
176gives the process a third user ID: the @dfn{file user ID}. This ID is
177set to the owner ID of the file. The system then changes the effective
178user ID to the file user ID. The real user ID remains as it was.
179Likewise, if the setgid bit is on, the process is given a @dfn{file
180group ID} equal to the group ID of the file, and its effective group ID
181is changed to the file group ID.
182
183If a process has a file ID (user or group), then it can at any time
184change its effective ID to its real ID and back to its file ID.
185Programs use this feature to relinquish their special privileges except
186when they actually need them. This makes it less likely that they can
187be tricked into doing something inappropriate with their privileges.
188
189@strong{Portability Note:} Older systems do not have file IDs.
190To determine if a system has this feature, you can test the compiler
191define @code{_POSIX_SAVED_IDS}. (In the POSIX standard, file IDs are
192known as saved IDs.)
193
194@xref{File Attributes}, for a more general discussion of file modes and
195accessibility.
196
197@node Reading Persona
198@section Reading the Persona of a Process
199
200Here are detailed descriptions of the functions for reading the user and
201group IDs of a process, both real and effective. To use these
202facilities, you must include the header files @file{sys/types.h} and
203@file{unistd.h}.
204@pindex unistd.h
205@pindex sys/types.h
206
207@comment sys/types.h
208@comment POSIX.1
209@deftp {Data Type} uid_t
210This is an integer data type used to represent user IDs. In
211@theglibc{}, this is an alias for @code{unsigned int}.
212@end deftp
213
214@comment sys/types.h
215@comment POSIX.1
216@deftp {Data Type} gid_t
217This is an integer data type used to represent group IDs. In
218@theglibc{}, this is an alias for @code{unsigned int}.
219@end deftp
220
221@comment unistd.h
222@comment POSIX.1
223@deftypefun uid_t getuid (void)
224@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
225@c Atomic syscall, except on hurd, where it takes a lock within a hurd
226@c critical section.
227The @code{getuid} function returns the real user ID of the process.
228@end deftypefun
229
230@comment unistd.h
231@comment POSIX.1
232@deftypefun gid_t getgid (void)
233@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
234The @code{getgid} function returns the real group ID of the process.
235@end deftypefun
236
237@comment unistd.h
238@comment POSIX.1
239@deftypefun uid_t geteuid (void)
240@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
241The @code{geteuid} function returns the effective user ID of the process.
242@end deftypefun
243
244@comment unistd.h
245@comment POSIX.1
246@deftypefun gid_t getegid (void)
247@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
248The @code{getegid} function returns the effective group ID of the process.
249@end deftypefun
250
251@comment unistd.h
252@comment POSIX.1
253@deftypefun int getgroups (int @var{count}, gid_t *@var{groups})
254@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
255The @code{getgroups} function is used to inquire about the supplementary
256group IDs of the process. Up to @var{count} of these group IDs are
257stored in the array @var{groups}; the return value from the function is
258the number of group IDs actually stored. If @var{count} is smaller than
259the total number of supplementary group IDs, then @code{getgroups}
260returns a value of @code{-1} and @code{errno} is set to @code{EINVAL}.
261
262If @var{count} is zero, then @code{getgroups} just returns the total
263number of supplementary group IDs. On systems that do not support
264supplementary groups, this will always be zero.
265
266Here's how to use @code{getgroups} to read all the supplementary group
267IDs:
268
269@smallexample
270@group
271gid_t *
272read_all_groups (void)
273@{
274 int ngroups = getgroups (0, NULL);
275 gid_t *groups
276 = (gid_t *) xmalloc (ngroups * sizeof (gid_t));
277 int val = getgroups (ngroups, groups);
278 if (val < 0)
279 @{
280 free (groups);
281 return NULL;
282 @}
283 return groups;
284@}
285@end group
286@end smallexample
287@end deftypefun
288
289@node Setting User ID
290@section Setting the User ID
291
292This section describes the functions for altering the user ID (real
293and/or effective) of a process. To use these facilities, you must
294include the header files @file{sys/types.h} and @file{unistd.h}.
295@pindex unistd.h
296@pindex sys/types.h
297
298@comment unistd.h
299@comment POSIX.1
300@deftypefun int seteuid (uid_t @var{neweuid})
301@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
302@c seteuid @asulock @aculock
303@c INLINE_SETXID_SYSCALL @asulock @aculock
304@c This may be just a unix syscall, or the ugliness below used by
305@c nptl to propagate the syscall to all cloned processes used to
306@c implement threads.
307@c nptl_setxid @asulock @aculock
308@c while holding the stack_alloc_lock, mark with SETXID_BITMASK all
309@c threads that are not exiting, signal them until no thread remains
310@c marked, clear the marks and run the syscall, then release the lock.
311@c lll_lock @asulock @aculock
312@c list_for_each ok
313@c list_entry ok
314@c setxid_mark_thread ok
315@c if a thread is initializing, wait for it to be cloned.
316@c mark it with SETXID_BITMASK if it's not exiting
317@c setxid_signal_thread ok
318@c if a thread is marked with SETXID_BITMASK,
319@c send it the SIGSETXID signal
320@c setxid_unmark_thread ok
321@c clear SETXID_BITMASK and release the futex if SETXID_BITMASK is
322@c set.
323@c <syscall> ok
324@c lll_unlock @aculock
325@c
326@c sighandler_setxid ok
327@c issue the syscall, clear SETXID_BITMASK, release the futex, and
328@c wake up the signaller loop if the counter reached zero.
329This function sets the effective user ID of a process to @var{neweuid},
330provided that the process is allowed to change its effective user ID. A
331privileged process (effective user ID zero) can change its effective
332user ID to any legal value. An unprivileged process with a file user ID
333can change its effective user ID to its real user ID or to its file user
334ID. Otherwise, a process may not change its effective user ID at all.
335
336The @code{seteuid} function returns a value of @code{0} to indicate
337successful completion, and a value of @code{-1} to indicate an error.
338The following @code{errno} error conditions are defined for this
339function:
340
341@table @code
342@item EINVAL
343The value of the @var{neweuid} argument is invalid.
344
345@item EPERM
346The process may not change to the specified ID.
347@end table
348
349Older systems (those without the @code{_POSIX_SAVED_IDS} feature) do not
350have this function.
351@end deftypefun
352
353@comment unistd.h
354@comment POSIX.1
355@deftypefun int setuid (uid_t @var{newuid})
356@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
357@c setuid @asulock @aculock
358@c INLINE_SETXID_SYSCALL dup @asulock @aculock
359If the calling process is privileged, this function sets both the real
360and effective user ID of the process to @var{newuid}. It also deletes
361the file user ID of the process, if any. @var{newuid} may be any
362legal value. (Once this has been done, there is no way to recover the
363old effective user ID.)
364
365If the process is not privileged, and the system supports the
366@code{_POSIX_SAVED_IDS} feature, then this function behaves like
367@code{seteuid}.
368
369The return values and error conditions are the same as for @code{seteuid}.
370@end deftypefun
371
372@comment unistd.h
373@comment BSD
374@deftypefun int setreuid (uid_t @var{ruid}, uid_t @var{euid})
375@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
376@c setreuid @asulock @aculock
377@c INLINE_SETXID_SYSCALL dup @asulock @aculock
378This function sets the real user ID of the process to @var{ruid} and the
379effective user ID to @var{euid}. If @var{ruid} is @code{-1}, it means
380not to change the real user ID; likewise if @var{euid} is @code{-1}, it
381means not to change the effective user ID.
382
383The @code{setreuid} function exists for compatibility with 4.3 BSD Unix,
384which does not support file IDs. You can use this function to swap the
385effective and real user IDs of the process. (Privileged processes are
386not limited to this particular usage.) If file IDs are supported, you
387should use that feature instead of this function. @xref{Enable/Disable
388Setuid}.
389
390The return value is @code{0} on success and @code{-1} on failure.
391The following @code{errno} error conditions are defined for this
392function:
393
394@table @code
395@item EPERM
396The process does not have the appropriate privileges; you do not
397have permission to change to the specified ID.
398@end table
399@end deftypefun
400
401@node Setting Groups
402@section Setting the Group IDs
403
404This section describes the functions for altering the group IDs (real
405and effective) of a process. To use these facilities, you must include
406the header files @file{sys/types.h} and @file{unistd.h}.
407@pindex unistd.h
408@pindex sys/types.h
409
410@comment unistd.h
411@comment POSIX.1
412@deftypefun int setegid (gid_t @var{newgid})
413@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
414@c setegid @asulock @aculock
415@c INLINE_SETXID_SYSCALL dup @asulock @aculock
416This function sets the effective group ID of the process to
417@var{newgid}, provided that the process is allowed to change its group
418ID. Just as with @code{seteuid}, if the process is privileged it may
419change its effective group ID to any value; if it isn't, but it has a
420file group ID, then it may change to its real group ID or file group ID;
421otherwise it may not change its effective group ID.
422
423Note that a process is only privileged if its effective @emph{user} ID
424is zero. The effective group ID only affects access permissions.
425
426The return values and error conditions for @code{setegid} are the same
427as those for @code{seteuid}.
428
429This function is only present if @code{_POSIX_SAVED_IDS} is defined.
430@end deftypefun
431
432@comment unistd.h
433@comment POSIX.1
434@deftypefun int setgid (gid_t @var{newgid})
435@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
436@c setgid @asulock @aculock
437@c INLINE_SETXID_SYSCALL dup @asulock @aculock
438This function sets both the real and effective group ID of the process
439to @var{newgid}, provided that the process is privileged. It also
440deletes the file group ID, if any.
441
442If the process is not privileged, then @code{setgid} behaves like
443@code{setegid}.
444
445The return values and error conditions for @code{setgid} are the same
446as those for @code{seteuid}.
447@end deftypefun
448
449@comment unistd.h
450@comment BSD
451@deftypefun int setregid (gid_t @var{rgid}, gid_t @var{egid})
452@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
453@c setregid @asulock @aculock
454@c INLINE_SETXID_SYSCALL dup @asulock @aculock
455This function sets the real group ID of the process to @var{rgid} and
456the effective group ID to @var{egid}. If @var{rgid} is @code{-1}, it
457means not to change the real group ID; likewise if @var{egid} is
458@code{-1}, it means not to change the effective group ID.
459
460The @code{setregid} function is provided for compatibility with 4.3 BSD
461Unix, which does not support file IDs. You can use this function to
462swap the effective and real group IDs of the process. (Privileged
463processes are not limited to this usage.) If file IDs are supported,
464you should use that feature instead of using this function.
465@xref{Enable/Disable Setuid}.
466
467The return values and error conditions for @code{setregid} are the same
468as those for @code{setreuid}.
469@end deftypefun
470
471@code{setuid} and @code{setgid} behave differently depending on whether
472the effective user ID at the time is zero. If it is not zero, they
473behave like @code{seteuid} and @code{setegid}. If it is, they change
474both effective and real IDs and delete the file ID. To avoid confusion,
475we recommend you always use @code{seteuid} and @code{setegid} except
476when you know the effective user ID is zero and your intent is to change
477the persona permanently. This case is rare---most of the programs that
478need it, such as @code{login} and @code{su}, have already been written.
479
480Note that if your program is setuid to some user other than @code{root},
481there is no way to drop privileges permanently.
482
483The system also lets privileged processes change their supplementary
484group IDs. To use @code{setgroups} or @code{initgroups}, your programs
485should include the header file @file{grp.h}.
486@pindex grp.h
487
488@comment grp.h
489@comment BSD
490@deftypefun int setgroups (size_t @var{count}, const gid_t *@var{groups})
491@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
492@c setgroups @asulock @aculock
493@c INLINE_SETXID_SYSCALL dup @asulock @aculock
494This function sets the process's supplementary group IDs. It can only
495be called from privileged processes. The @var{count} argument specifies
496the number of group IDs in the array @var{groups}.
497
498This function returns @code{0} if successful and @code{-1} on error.
499The following @code{errno} error conditions are defined for this
500function:
501
502@table @code
503@item EPERM
504The calling process is not privileged.
505@end table
506@end deftypefun
507
508@comment grp.h
509@comment BSD
510@deftypefun int initgroups (const char *@var{user}, gid_t @var{group})
511@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}}
512@c initgroups @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
513@c sysconf(_SC_NGROUPS_MAX) dup @acsfd
514@c MIN dup ok
515@c malloc @ascuheap @acsmem
516@c internal_getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
517@c nscd_getgrouplist @ascuheap @acsfd @acsmem
518@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem
519@c nscd_cache_search dup ok
520@c nscd_open_socket dup @acsfd
521@c realloc dup @ascuheap @acsmem
522@c readall dup ok
523@c memcpy dup ok
524@c close_not_cancel_no_status dup @acsfd
525@c nscd_drop_map_ref dup @ascuheap @acsmem
526@c nscd_unmap dup @ascuheap @acsmem
527@c nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
528@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
529@c compat_call @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
530@c sysconf(_SC_GETGR_R_SIZE_MAX) ok
531@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
532@c *getgrent_fct @ascuplugin
533@c *setgrent_fct @ascuplugin
534@c *endgrent_fct @ascuplugin
535@c realloc dup @ascuheap @acsmem
536@c free dup @ascuheap @acsmem
537@c *initgroups_dyn_fct @ascuplugin
538@c nss_next_action dup ok
539@c setgroups dup @asulock @aculock
540@c free dup @ascuheap @acsmem
541The @code{initgroups} function sets the process's supplementary group
542IDs to be the normal default for the user name @var{user}. The group
543@var{group} is automatically included.
544
545This function works by scanning the group database for all the groups
546@var{user} belongs to. It then calls @code{setgroups} with the list it
547has constructed.
548
549The return values and error conditions are the same as for
550@code{setgroups}.
551@end deftypefun
552
553If you are interested in the groups a particular user belongs to, but do
554not want to change the process's supplementary group IDs, you can use
555@code{getgrouplist}. To use @code{getgrouplist}, your programs should
556include the header file @file{grp.h}.
557@pindex grp.h
558
559@comment grp.h
560@comment BSD
561@deftypefun int getgrouplist (const char *@var{user}, gid_t @var{group}, gid_t *@var{groups}, int *@var{ngroups})
562@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}}
563@c getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
564@c MAX dup ok
565@c malloc dup @ascuheap @acsmem
566@c internal_getgrouplist dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
567@c memcpy dup ok
568@c free dup @ascuheap @acsmem
569The @code{getgrouplist} function scans the group database for all the
570groups @var{user} belongs to. Up to *@var{ngroups} group IDs
571corresponding to these groups are stored in the array @var{groups}; the
572return value from the function is the number of group IDs actually
573stored. If *@var{ngroups} is smaller than the total number of groups
574found, then @code{getgrouplist} returns a value of @code{-1} and stores
575the actual number of groups in *@var{ngroups}. The group @var{group} is
576automatically included in the list of groups returned by
577@code{getgrouplist}.
578
579Here's how to use @code{getgrouplist} to read all supplementary groups
580for @var{user}:
581
582@smallexample
583@group
584gid_t *
585supplementary_groups (char *user)
586@{
587 int ngroups = 16;
588 gid_t *groups
589 = (gid_t *) xmalloc (ngroups * sizeof (gid_t));
590 struct passwd *pw = getpwnam (user);
591
592 if (pw == NULL)
593 return NULL;
594
595 if (getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups) < 0)
596 @{
597 groups = xrealloc (ngroups * sizeof (gid_t));
598 getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups);
599 @}
600 return groups;
601@}
602@end group
603@end smallexample
604@end deftypefun
605
606@node Enable/Disable Setuid
607@section Enabling and Disabling Setuid Access
608
609A typical setuid program does not need its special access all of the
610time. It's a good idea to turn off this access when it isn't needed,
611so it can't possibly give unintended access.
612
613If the system supports the @code{_POSIX_SAVED_IDS} feature, you can
614accomplish this with @code{seteuid}. When the game program starts, its
615real user ID is @code{jdoe}, its effective user ID is @code{games}, and
616its saved user ID is also @code{games}. The program should record both
617user ID values once at the beginning, like this:
618
619@smallexample
620user_user_id = getuid ();
621game_user_id = geteuid ();
622@end smallexample
623
624Then it can turn off game file access with
625
626@smallexample
627seteuid (user_user_id);
628@end smallexample
629
630@noindent
631and turn it on with
632
633@smallexample
634seteuid (game_user_id);
635@end smallexample
636
637@noindent
638Throughout this process, the real user ID remains @code{jdoe} and the
639file user ID remains @code{games}, so the program can always set its
640effective user ID to either one.
641
642On other systems that don't support file user IDs, you can
643turn setuid access on and off by using @code{setreuid} to swap the real
644and effective user IDs of the process, as follows:
645
646@smallexample
647setreuid (geteuid (), getuid ());
648@end smallexample
649
650@noindent
651This special case is always allowed---it cannot fail.
652
653Why does this have the effect of toggling the setuid access? Suppose a
654game program has just started, and its real user ID is @code{jdoe} while
655its effective user ID is @code{games}. In this state, the game can
656write the scores file. If it swaps the two uids, the real becomes
657@code{games} and the effective becomes @code{jdoe}; now the program has
658only @code{jdoe} access. Another swap brings @code{games} back to
659the effective user ID and restores access to the scores file.
660
661In order to handle both kinds of systems, test for the saved user ID
662feature with a preprocessor conditional, like this:
663
664@smallexample
665#ifdef _POSIX_SAVED_IDS
666 seteuid (user_user_id);
667#else
668 setreuid (geteuid (), getuid ());
669#endif
670@end smallexample
671
672@node Setuid Program Example
673@section Setuid Program Example
674
675Here's an example showing how to set up a program that changes its
676effective user ID.
677
678This is part of a game program called @code{caber-toss} that manipulates
679a file @file{scores} that should be writable only by the game program
680itself. The program assumes that its executable file will be installed
681with the setuid bit set and owned by the same user as the @file{scores}
682file. Typically, a system administrator will set up an account like
683@code{games} for this purpose.
684
685The executable file is given mode @code{4755}, so that doing an
686@samp{ls -l} on it produces output like:
687
688@smallexample
689-rwsr-xr-x 1 games 184422 Jul 30 15:17 caber-toss
690@end smallexample
691
692@noindent
693The setuid bit shows up in the file modes as the @samp{s}.
694
695The scores file is given mode @code{644}, and doing an @samp{ls -l} on
696it shows:
697
698@smallexample
699-rw-r--r-- 1 games 0 Jul 31 15:33 scores
700@end smallexample
701
702Here are the parts of the program that show how to set up the changed
703user ID. This program is conditionalized so that it makes use of the
704file IDs feature if it is supported, and otherwise uses @code{setreuid}
705to swap the effective and real user IDs.
706
707@smallexample
708#include <stdio.h>
709#include <sys/types.h>
710#include <unistd.h>
711#include <stdlib.h>
712
713
714/* @r{Remember the effective and real UIDs.} */
715
716static uid_t euid, ruid;
717
718
719/* @r{Restore the effective UID to its original value.} */
720
721void
722do_setuid (void)
723@{
724 int status;
725
726#ifdef _POSIX_SAVED_IDS
727 status = seteuid (euid);
728#else
729 status = setreuid (ruid, euid);
730#endif
731 if (status < 0) @{
732 fprintf (stderr, "Couldn't set uid.\n");
733 exit (status);
734 @}
735@}
736
737
738@group
739/* @r{Set the effective UID to the real UID.} */
740
741void
742undo_setuid (void)
743@{
744 int status;
745
746#ifdef _POSIX_SAVED_IDS
747 status = seteuid (ruid);
748#else
749 status = setreuid (euid, ruid);
750#endif
751 if (status < 0) @{
752 fprintf (stderr, "Couldn't set uid.\n");
753 exit (status);
754 @}
755@}
756@end group
757
758/* @r{Main program.} */
759
760int
761main (void)
762@{
763 /* @r{Remember the real and effective user IDs.} */
764 ruid = getuid ();
765 euid = geteuid ();
766 undo_setuid ();
767
768 /* @r{Do the game and record the score.} */
769 @dots{}
770@}
771@end smallexample
772
773Notice how the first thing the @code{main} function does is to set the
774effective user ID back to the real user ID. This is so that any other
775file accesses that are performed while the user is playing the game use
776the real user ID for determining permissions. Only when the program
777needs to open the scores file does it switch back to the file user ID,
778like this:
779
780@smallexample
781/* @r{Record the score.} */
782
783int
784record_score (int score)
785@{
786 FILE *stream;
787 char *myname;
788
789 /* @r{Open the scores file.} */
790 do_setuid ();
791 stream = fopen (SCORES_FILE, "a");
792 undo_setuid ();
793
794@group
795 /* @r{Write the score to the file.} */
796 if (stream)
797 @{
798 myname = cuserid (NULL);
799 if (score < 0)
800 fprintf (stream, "%10s: Couldn't lift the caber.\n", myname);
801 else
802 fprintf (stream, "%10s: %d feet.\n", myname, score);
803 fclose (stream);
804 return 0;
805 @}
806 else
807 return -1;
808@}
809@end group
810@end smallexample
811
812@node Tips for Setuid
813@section Tips for Writing Setuid Programs
814
815It is easy for setuid programs to give the user access that isn't
816intended---in fact, if you want to avoid this, you need to be careful.
817Here are some guidelines for preventing unintended access and
818minimizing its consequences when it does occur:
819
820@itemize @bullet
821@item
822Don't have @code{setuid} programs with privileged user IDs such as
823@code{root} unless it is absolutely necessary. If the resource is
824specific to your particular program, it's better to define a new,
825nonprivileged user ID or group ID just to manage that resource.
826It's better if you can write your program to use a special group than a
827special user.
828
829@item
830Be cautious about using the @code{exec} functions in combination with
831changing the effective user ID. Don't let users of your program execute
832arbitrary programs under a changed user ID. Executing a shell is
833especially bad news. Less obviously, the @code{execlp} and @code{execvp}
834functions are a potential risk (since the program they execute depends
835on the user's @code{PATH} environment variable).
836
837If you must @code{exec} another program under a changed ID, specify an
838absolute file name (@pxref{File Name Resolution}) for the executable,
839and make sure that the protections on that executable and @emph{all}
840containing directories are such that ordinary users cannot replace it
841with some other program.
842
843You should also check the arguments passed to the program to make sure
844they do not have unexpected effects. Likewise, you should examine the
845environment variables. Decide which arguments and variables are safe,
846and reject all others.
847
848You should never use @code{system} in a privileged program, because it
849invokes a shell.
850
851@item
852Only use the user ID controlling the resource in the part of the program
853that actually uses that resource. When you're finished with it, restore
854the effective user ID back to the actual user's user ID.
855@xref{Enable/Disable Setuid}.
856
857@item
858If the @code{setuid} part of your program needs to access other files
859besides the controlled resource, it should verify that the real user
860would ordinarily have permission to access those files. You can use the
861@code{access} function (@pxref{Access Permission}) to check this; it
862uses the real user and group IDs, rather than the effective IDs.
863@end itemize
864
865@node Who Logged In
866@section Identifying Who Logged In
867@cindex login name, determining
868@cindex user ID, determining
869
870You can use the functions listed in this section to determine the login
871name of the user who is running a process, and the name of the user who
872logged in the current session. See also the function @code{getuid} and
873friends (@pxref{Reading Persona}). How this information is collected by
874the system and how to control/add/remove information from the background
875storage is described in @ref{User Accounting Database}.
876
877The @code{getlogin} function is declared in @file{unistd.h}, while
878@code{cuserid} and @code{L_cuserid} are declared in @file{stdio.h}.
879@pindex stdio.h
880@pindex unistd.h
881
882@comment unistd.h
883@comment POSIX.1
884@deftypefun {char *} getlogin (void)
885@safety{@prelim{}@mtunsafe{@mtasurace{:getlogin} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
886@c getlogin (linux) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
887@c getlogin_r_loginuid dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
888@c getlogin_fd0 (unix) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem
889@c uses static buffer name => @mtasurace:getlogin
890@c ttyname_r dup @ascuheap @acsmem @acsfd
891@c strncpy dup ok
892@c setutent dup @mtasurace:utent @asulock @aculock @acsfd
893@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
894@c endutent dup @mtasurace:utent @asulock @aculock
895@c libc_lock_unlock dup ok
896@c strlen dup ok
897@c memcpy dup ok
898@c
899@c getlogin_r (linux) @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
900@c getlogin_r_loginuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
901@c open_not_cancel_2 dup @acsfd
902@c read_not_cancel dup ok
903@c close_not_cancel_no_status dup @acsfd
904@c strtoul @mtslocale
905@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
906@c realloc dup @asulock @aculock @acsfd @acsmem
907@c strlen dup ok
908@c memcpy dup ok
909@c free dup @asulock @aculock @acsfd @acsmem
910@c getlogin_r_fd0 (unix) @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd
911@c ttyname_r dup @ascuheap @acsmem @acsfd
912@c strncpy dup ok
913@c libc_lock_lock dup @asulock @aculock
914@c *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd
915@c *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer
916@c *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock
917@c libc_lock_unlock dup ok
918@c strlen dup ok
919@c memcpy dup ok
920The @code{getlogin} function returns a pointer to a string containing the
921name of the user logged in on the controlling terminal of the process,
922or a null pointer if this information cannot be determined. The string
923is statically allocated and might be overwritten on subsequent calls to
924this function or to @code{cuserid}.
925@end deftypefun
926
927@comment stdio.h
928@comment POSIX.1
929@deftypefun {char *} cuserid (char *@var{string})
930@safety{@prelim{}@mtunsafe{@mtasurace{:cuserid/!string} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
931@c cuserid @mtasurace:cuserid/!string @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
932@c if string is NULL, cuserid will overwrite and return a static buffer
933@c geteuid dup ok
934@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
935@c strncpy dup ok
936The @code{cuserid} function returns a pointer to a string containing a
937user name associated with the effective ID of the process. If
938@var{string} is not a null pointer, it should be an array that can hold
939at least @code{L_cuserid} characters; the string is returned in this
940array. Otherwise, a pointer to a string in a static area is returned.
941This string is statically allocated and might be overwritten on
942subsequent calls to this function or to @code{getlogin}.
943
944The use of this function is deprecated since it is marked to be
945withdrawn in XPG4.2 and has already been removed from newer revisions of
946POSIX.1.
947@end deftypefun
948
949@comment stdio.h
950@comment POSIX.1
951@deftypevr Macro int L_cuserid
952An integer constant that indicates how long an array you might need to
953store a user name.
954@end deftypevr
955
956These functions let your program identify positively the user who is
957running or the user who logged in this session. (These can differ when
958setuid programs are involved; see @ref{Process Persona}.) The user cannot
959do anything to fool these functions.
960
961For most purposes, it is more useful to use the environment variable
962@code{LOGNAME} to find out who the user is. This is more flexible
963precisely because the user can set @code{LOGNAME} arbitrarily.
964@xref{Standard Environment}.
965
966
967@node User Accounting Database
968@section The User Accounting Database
969@cindex user accounting database
970
971Most Unix-like operating systems keep track of logged in users by
972maintaining a user accounting database. This user accounting database
973stores for each terminal, who has logged on, at what time, the process
974ID of the user's login shell, etc., etc., but also stores information
975about the run level of the system, the time of the last system reboot,
976and possibly more.
977
978The user accounting database typically lives in @file{/etc/utmp},
979@file{/var/adm/utmp} or @file{/var/run/utmp}. However, these files
980should @strong{never} be accessed directly. For reading information
981from and writing information to the user accounting database, the
982functions described in this section should be used.
983
984
985@menu
986* Manipulating the Database:: Scanning and modifying the user
987 accounting database.
988* XPG Functions:: A standardized way for doing the same thing.
989* Logging In and Out:: Functions from BSD that modify the user
990 accounting database.
991@end menu
992
993@node Manipulating the Database
994@subsection Manipulating the User Accounting Database
995
996These functions and the corresponding data structures are declared in
997the header file @file{utmp.h}.
998@pindex utmp.h
999
1000@comment utmp.h
1001@comment SVID
1002@deftp {Data Type} {struct exit_status}
1003The @code{exit_status} data structure is used to hold information about
1004the exit status of processes marked as @code{DEAD_PROCESS} in the user
1005accounting database.
1006
1007@table @code
1008@item short int e_termination
1009The exit status of the process.
1010
1011@item short int e_exit
1012The exit status of the process.
1013@end table
1014@end deftp
1015
1016@deftp {Data Type} {struct utmp}
1017The @code{utmp} data structure is used to hold information about entries
1018in the user accounting database. On @gnusystems{} it has the following
1019members:
1020
1021@table @code
1022@item short int ut_type
1023Specifies the type of login; one of @code{EMPTY}, @code{RUN_LVL},
1024@code{BOOT_TIME}, @code{OLD_TIME}, @code{NEW_TIME}, @code{INIT_PROCESS},
1025@code{LOGIN_PROCESS}, @code{USER_PROCESS}, @code{DEAD_PROCESS} or
1026@code{ACCOUNTING}.
1027
1028@item pid_t ut_pid
1029The process ID number of the login process.
1030
1031@item char ut_line[]
1032The device name of the tty (without @file{/dev/}).
1033
1034@item char ut_id[]
1035The inittab ID of the process.
1036
1037@item char ut_user[]
1038The user's login name.
1039
1040@item char ut_host[]
1041The name of the host from which the user logged in.
1042
1043@item struct exit_status ut_exit
1044The exit status of a process marked as @code{DEAD_PROCESS}.
1045
1046@item long ut_session
1047The Session ID, used for windowing.
1048
1049@item struct timeval ut_tv
1050Time the entry was made. For entries of type @code{OLD_TIME} this is
1051the time when the system clock changed, and for entries of type
1052@code{NEW_TIME} this is the time the system clock was set to.
1053
1054@item int32_t ut_addr_v6[4]
1055The Internet address of a remote host.
1056@end table
1057@end deftp
1058
1059The @code{ut_type}, @code{ut_pid}, @code{ut_id}, @code{ut_tv}, and
1060@code{ut_host} fields are not available on all systems. Portable
1061applications therefore should be prepared for these situations. To help
1062doing this the @file{utmp.h} header provides macros
1063@code{_HAVE_UT_TYPE}, @code{_HAVE_UT_PID}, @code{_HAVE_UT_ID},
1064@code{_HAVE_UT_TV}, and @code{_HAVE_UT_HOST} if the respective field is
1065available. The programmer can handle the situations by using
1066@code{#ifdef} in the program code.
1067
1068The following macros are defined for use as values for the
1069@code{ut_type} member of the @code{utmp} structure. The values are
1070integer constants.
1071
1072@table @code
1073@comment utmp.h
1074@comment SVID
1075@vindex EMPTY
1076@item EMPTY
1077This macro is used to indicate that the entry contains no valid user
1078accounting information.
1079
1080@comment utmp.h
1081@comment SVID
1082@vindex RUN_LVL
1083@item RUN_LVL
1084This macro is used to identify the systems runlevel.
1085
1086@comment utmp.h
1087@comment SVID
1088@vindex BOOT_TIME
1089@item BOOT_TIME
1090This macro is used to identify the time of system boot.
1091
1092@comment utmp.h
1093@comment SVID
1094@vindex OLD_TIME
1095@item OLD_TIME
1096This macro is used to identify the time when the system clock changed.
1097
1098@comment utmp.h
1099@comment SVID
1100@vindex NEW_TIME
1101@item NEW_TIME
1102This macro is used to identify the time after the system changed.
1103
1104@comment utmp.h
1105@comment SVID
1106@vindex INIT_PROCESS
1107@item INIT_PROCESS
1108This macro is used to identify a process spawned by the init process.
1109
1110@comment utmp.h
1111@comment SVID
1112@vindex LOGIN_PROCESS
1113@item LOGIN_PROCESS
1114This macro is used to identify the session leader of a logged in user.
1115
1116@comment utmp.h
1117@comment SVID
1118@vindex USER_PROCESS
1119@item USER_PROCESS
1120This macro is used to identify a user process.
1121
1122@comment utmp.h
1123@comment SVID
1124@vindex DEAD_PROCESS
1125@item DEAD_PROCESS
1126This macro is used to identify a terminated process.
1127
1128@comment utmp.h
1129@comment SVID
1130@vindex ACCOUNTING
1131@item ACCOUNTING
1132???
1133@end table
1134
1135The size of the @code{ut_line}, @code{ut_id}, @code{ut_user} and
1136@code{ut_host} arrays can be found using the @code{sizeof} operator.
1137
1138Many older systems have, instead of an @code{ut_tv} member, an
1139@code{ut_time} member, usually of type @code{time_t}, for representing
1140the time associated with the entry. Therefore, for backwards
1141compatibility only, @file{utmp.h} defines @code{ut_time} as an alias for
1142@code{ut_tv.tv_sec}.
1143
1144@comment utmp.h
1145@comment SVID
1146@deftypefun void setutent (void)
1147@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1148@c Besides the static variables in utmp_file.c, there's the jump_table.
1149@c They're both modified while holding a lock, but other threads may
1150@c cause the variables to be modified between calling this function and
1151@c others that rely on the internal state it sets up.
1152
1153@c setutent @mtasurace:utent @asulock @aculock @acsfd
1154@c libc_lock_lock dup @asulock @aculock
1155@c *libc_utmp_jump_table->setutent @mtasurace:utent @acsfd
1156@c setutent_unknown @mtasurace:utent @acsfd
1157@c *libc_utmp_file_functions.setutent = setutent_file @mtasurace:utent @acsfd
1158@c open_not_cancel_2 dup @acsfd
1159@c fcntl_not_cancel dup ok
1160@c close_not_cancel_no_status dup @acsfd
1161@c lseek64 dup ok
1162@c libc_lock_unlock dup ok
1163This function opens the user accounting database to begin scanning it.
1164You can then call @code{getutent}, @code{getutid} or @code{getutline} to
1165read entries and @code{pututline} to write entries.
1166
1167If the database is already open, it resets the input to the beginning of
1168the database.
1169@end deftypefun
1170
1171@comment utmp.h
1172@comment SVID
1173@deftypefun {struct utmp *} getutent (void)
1174@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasurace{:utentbuf} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
1175@c The static buffer that holds results is allocated with malloc at
1176@c the first call; the test is not thread-safe, so multiple concurrent
1177@c calls could malloc multiple buffers.
1178
1179@c getutent @mtuinit @mtasurace:utent @mtasurace:utentbuf @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem
1180@c malloc @asulock @aculock @acsfd @acsmem
1181@c getutent_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1182The @code{getutent} function reads the next entry from the user
1183accounting database. It returns a pointer to the entry, which is
1184statically allocated and may be overwritten by subsequent calls to
1185@code{getutent}. You must copy the contents of the structure if you
1186wish to save the information or you can use the @code{getutent_r}
1187function which stores the data in a user-provided buffer.
1188
1189A null pointer is returned in case no further entry is available.
1190@end deftypefun
1191
1192@comment utmp.h
1193@comment SVID
1194@deftypefun void endutent (void)
1195@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1196@c endutent @mtasurace:utent @asulock @aculock @acsfd
1197@c libc_lock_lock dup @asulock @aculock
1198@c *libc_utmp_jump_table->endutent @mtasurace:utent @acsfd
1199@c endutent_unknown ok
1200@c endutent_file @mtasurace:utent @acsfd
1201@c close_not_cancel_no_status dup @acsfd
1202@c libc_lock_unlock dup ok
1203This function closes the user accounting database.
1204@end deftypefun
1205
1206@comment utmp.h
1207@comment SVID
1208@deftypefun {struct utmp *} getutid (const struct utmp *@var{id})
1209@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
1210@c Same caveats as getutline.
1211@c
1212@c getutid @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd
1213@c uses a static buffer malloced on the first call
1214@c malloc dup @ascuheap @acsmem
1215@c getutid_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1216This function searches forward from the current point in the database
1217for an entry that matches @var{id}. If the @code{ut_type} member of the
1218@var{id} structure is one of @code{RUN_LVL}, @code{BOOT_TIME},
1219@code{OLD_TIME} or @code{NEW_TIME} the entries match if the
1220@code{ut_type} members are identical. If the @code{ut_type} member of
1221the @var{id} structure is @code{INIT_PROCESS}, @code{LOGIN_PROCESS},
1222@code{USER_PROCESS} or @code{DEAD_PROCESS}, the entries match if the
1223@code{ut_type} member of the entry read from the database is one of
1224these four, and the @code{ut_id} members match. However if the
1225@code{ut_id} member of either the @var{id} structure or the entry read
1226from the database is empty it checks if the @code{ut_line} members match
1227instead. If a matching entry is found, @code{getutid} returns a pointer
1228to the entry, which is statically allocated, and may be overwritten by a
1229subsequent call to @code{getutent}, @code{getutid} or @code{getutline}.
1230You must copy the contents of the structure if you wish to save the
1231information.
1232
1233A null pointer is returned in case the end of the database is reached
1234without a match.
1235
1236The @code{getutid} function may cache the last read entry. Therefore,
1237if you are using @code{getutid} to search for multiple occurrences, it
1238is necessary to zero out the static data after each call. Otherwise
1239@code{getutid} could just return a pointer to the same entry over and
1240over again.
1241@end deftypefun
1242
1243@comment utmp.h
1244@comment SVID
1245@deftypefun {struct utmp *} getutline (const struct utmp *@var{line})
1246@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
1247@c The static buffer that holds results is allocated with malloc at
1248@c the first call; the test is not thread-safe, so multiple concurrent
1249@c calls could malloc multiple buffers.
1250
1251@c getutline @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem
1252@c malloc @asulock @aculock @acsfd @acsmem
1253@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1254This function searches forward from the current point in the database
1255until it finds an entry whose @code{ut_type} value is
1256@code{LOGIN_PROCESS} or @code{USER_PROCESS}, and whose @code{ut_line}
1257member matches the @code{ut_line} member of the @var{line} structure.
1258If it finds such an entry, it returns a pointer to the entry which is
1259statically allocated, and may be overwritten by a subsequent call to
1260@code{getutent}, @code{getutid} or @code{getutline}. You must copy the
1261contents of the structure if you wish to save the information.
1262
1263A null pointer is returned in case the end of the database is reached
1264without a match.
1265
1266The @code{getutline} function may cache the last read entry. Therefore
1267if you are using @code{getutline} to search for multiple occurrences, it
1268is necessary to zero out the static data after each call. Otherwise
1269@code{getutline} could just return a pointer to the same entry over and
1270over again.
1271@end deftypefun
1272
1273@comment utmp.h
1274@comment SVID
1275@deftypefun {struct utmp *} pututline (const struct utmp *@var{utmp})
1276@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1277@c pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1278@c libc_lock_lock dup @asulock @aculock
1279@c *libc_utmp_jump_table->pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
1280@c pututline_unknown @mtasurace:utent @acsfd
1281@c setutent_unknown dup @mtasurace:utent @acsfd
1282@c pututline_file @mtascusig:ALRM @mtascutimer @acsfd
1283@c TRANSFORM_UTMP_FILE_NAME ok
1284@c strcmp dup ok
1285@c acesss dup ok
1286@c open_not_cancel_2 dup @acsfd
1287@c fcntl_not_cancel dup ok
1288@c close_not_cancel_no_status dup @acsfd
1289@c llseek dup ok
1290@c dup2 dup ok
1291@c utmp_equal dup ok
1292@c internal_getut_r dup @mtascusig:ALRM @mtascutimer
1293@c LOCK_FILE dup @mtascusig:ALRM @mtasctimer
1294@c LOCKING_FAILED dup ok
1295@c ftruncate64 dup ok
1296@c write_not_cancel dup ok
1297@c UNLOCK_FILE dup @mtasctimer
1298@c libc_lock_unlock dup @aculock
1299The @code{pututline} function inserts the entry @code{*@var{utmp}} at
1300the appropriate place in the user accounting database. If it finds that
1301it is not already at the correct place in the database, it uses
1302@code{getutid} to search for the position to insert the entry, however
1303this will not modify the static structure returned by @code{getutent},
1304@code{getutid} and @code{getutline}. If this search fails, the entry
1305is appended to the database.
1306
1307The @code{pututline} function returns a pointer to a copy of the entry
1308inserted in the user accounting database, or a null pointer if the entry
1309could not be added. The following @code{errno} error conditions are
1310defined for this function:
1311
1312@table @code
1313@item EPERM
1314The process does not have the appropriate privileges; you cannot modify
1315the user accounting database.
1316@end table
1317@end deftypefun
1318
1319All the @code{get*} functions mentioned before store the information
1320they return in a static buffer. This can be a problem in multi-threaded
1321programs since the data returned for the request is overwritten by the
1322return value data in another thread. Therefore @theglibc{}
1323provides as extensions three more functions which return the data in a
1324user-provided buffer.
1325
1326@comment utmp.h
1327@comment GNU
1328@deftypefun int getutent_r (struct utmp *@var{buffer}, struct utmp **@var{result})
1329@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1330@c getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1331@c libc_lock_lock dup @asulock @aculock
1332@c *libc_utmp_jump_table->getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
1333@c getutent_r_unknown @mtasurace:utent @acsfd
1334@c setutent_unknown dup @mtasurace:utent @acsfd
1335@c getutent_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer
1336@c LOCK_FILE @mtascusig:ALRM @mtascutimer
1337@c alarm dup @mtascutimer
1338@c sigemptyset dup ok
1339@c sigaction dup ok
1340@c memset dup ok
1341@c fcntl_not_cancel dup ok
1342@c LOCKING_FAILED ok
1343@c read_not_cancel dup ok
1344@c UNLOCK_FILE @mtascutimer
1345@c fcntl_not_cancel dup ok
1346@c alarm dup @mtascutimer
1347@c sigaction dup ok
1348@c memcpy dup ok
1349@c libc_lock_unlock dup ok
1350The @code{getutent_r} is equivalent to the @code{getutent} function. It
1351returns the next entry from the database. But instead of storing the
1352information in a static buffer it stores it in the buffer pointed to by
1353the parameter @var{buffer}.
1354
1355If the call was successful, the function returns @code{0} and the
1356pointer variable pointed to by the parameter @var{result} contains a
1357pointer to the buffer which contains the result (this is most probably
1358the same value as @var{buffer}). If something went wrong during the
1359execution of @code{getutent_r} the function returns @code{-1}.
1360
1361This function is a GNU extension.
1362@end deftypefun
1363
1364@comment utmp.h
1365@comment GNU
1366@deftypefun int getutid_r (const struct utmp *@var{id}, struct utmp *@var{buffer}, struct utmp **@var{result})
1367@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1368@c getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1369@c libc_lock_lock dup @asulock @aculock
1370@c *libc_utmp_jump_table->getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
1371@c getutid_r_unknown @mtasurace:utent @acsfd
1372@c setutent_unknown dup @mtasurace:utent @acsfd
1373@c getutid_r_file @mtascusig:ALRM @mtascutimer
1374@c internal_getut_r @mtascusig:ALRM @mtascutimer
1375@c LOCK_FILE dup @mtascusig:ALRM @mtascutimer
1376@c LOCKING_FAILED dup ok
1377@c read_not_cancel dup ok
1378@c utmp_equal ok
1379@c strncmp dup ok
1380@c UNLOCK_FILE dup @mtascutimer
1381@c memcpy dup ok
1382@c libc_lock_unlock dup @aculock
1383This function retrieves just like @code{getutid} the next entry matching
1384the information stored in @var{id}. But the result is stored in the
1385buffer pointed to by the parameter @var{buffer}.
1386
1387If successful the function returns @code{0} and the pointer variable
1388pointed to by the parameter @var{result} contains a pointer to the
1389buffer with the result (probably the same as @var{result}. If not
1390successful the function return @code{-1}.
1391
1392This function is a GNU extension.
1393@end deftypefun
1394
1395@comment utmp.h
1396@comment GNU
1397@deftypefun int getutline_r (const struct utmp *@var{line}, struct utmp *@var{buffer}, struct utmp **@var{result})
1398@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1399@c getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1400@c libc_lock_lock dup @asulock @aculock
1401@c *libc_utmp_jump_table->getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd
1402@c getutline_r_unknown @mtasurace:utent @acsfd
1403@c setutent_unknown dup @mtasurace:utent @acsfd
1404@c getutline_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer
1405@c LOCK_FILE @mtascusig:ALRM @mtascutimer
1406@c alarm dup @mtascutimer
1407@c sigemptyset dup ok
1408@c sigaction dup ok
1409@c memset dup ok
1410@c fcntl_not_cancel dup ok
1411@c LOCKING_FAILED ok
1412@c read_not_cancel dup ok
1413@c strncmp dup ok
1414@c UNLOCK_FILE @mtascutimer
1415@c fcntl_not_cancel dup ok
1416@c alarm dup @mtascutimer
1417@c sigaction dup ok
1418@c memcpy dup ok
1419@c libc_lock_unlock dup ok
1420This function retrieves just like @code{getutline} the next entry
1421matching the information stored in @var{line}. But the result is stored
1422in the buffer pointed to by the parameter @var{buffer}.
1423
1424If successful the function returns @code{0} and the pointer variable
1425pointed to by the parameter @var{result} contains a pointer to the
1426buffer with the result (probably the same as @var{result}. If not
1427successful the function return @code{-1}.
1428
1429This function is a GNU extension.
1430@end deftypefun
1431
1432
1433In addition to the user accounting database, most systems keep a number
1434of similar databases. For example most systems keep a log file with all
1435previous logins (usually in @file{/etc/wtmp} or @file{/var/log/wtmp}).
1436
1437For specifying which database to examine, the following function should
1438be used.
1439
1440@comment utmp.h
1441@comment SVID
1442@deftypefun int utmpname (const char *@var{file})
1443@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
1444@c utmpname @mtasurace:utent @asulock @ascuheap @aculock @acsmem
1445@c libc_lock_lock dup @asulock @aculock
1446@c *libc_utmp_jump_table->endutent dup @mtasurace:utent
1447@c strcmp dup ok
1448@c free dup @ascuheap @acsmem
1449@c strdup dup @ascuheap @acsmem
1450@c libc_lock_unlock dup @aculock
1451The @code{utmpname} function changes the name of the database to be
1452examined to @var{file}, and closes any previously opened database. By
1453default @code{getutent}, @code{getutid}, @code{getutline} and
1454@code{pututline} read from and write to the user accounting database.
1455
1456The following macros are defined for use as the @var{file} argument:
1457
1458@deftypevr Macro {char *} _PATH_UTMP
1459This macro is used to specify the user accounting database.
1460@end deftypevr
1461
1462@deftypevr Macro {char *} _PATH_WTMP
1463This macro is used to specify the user accounting log file.
1464@end deftypevr
1465
1466The @code{utmpname} function returns a value of @code{0} if the new name
1467was successfully stored, and a value of @code{-1} to indicate an error.
1468Note that @code{utmpname} does not try to open the database, and that
1469therefore the return value does not say anything about whether the
1470database can be successfully opened.
1471@end deftypefun
1472
1473Specially for maintaining log-like databases @theglibc{} provides
1474the following function:
1475
1476@comment utmp.h
1477@comment SVID
1478@deftypefun void updwtmp (const char *@var{wtmp_file}, const struct utmp *@var{utmp})
1479@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}}
1480@c updwtmp @mtascusig:ALRM @mtascutimer @acsfd
1481@c TRANSFORM_UTMP_FILE_NAME dup ok
1482@c *libc_utmp_file_functions->updwtmp = updwtmp_file @mtascusig:ALRM @mtascutimer @acsfd
1483@c open_not_cancel_2 dup @acsfd
1484@c LOCK_FILE dup @mtascusig:ALRM @mtascutimer
1485@c LOCKING_FAILED dup ok
1486@c lseek64 dup ok
1487@c ftruncate64 dup ok
1488@c write_not_cancel dup ok
1489@c UNLOCK_FILE dup @mtascutimer
1490@c close_not_cancel_no_status dup @acsfd
1491The @code{updwtmp} function appends the entry *@var{utmp} to the
1492database specified by @var{wtmp_file}. For possible values for the
1493@var{wtmp_file} argument see the @code{utmpname} function.
1494@end deftypefun
1495
1496@strong{Portability Note:} Although many operating systems provide a
1497subset of these functions, they are not standardized. There are often
1498subtle differences in the return types, and there are considerable
1499differences between the various definitions of @code{struct utmp}. When
1500programming for @theglibc{}, it is probably best to stick
1501with the functions described in this section. If however, you want your
1502program to be portable, consider using the XPG functions described in
1503@ref{XPG Functions}, or take a look at the BSD compatible functions in
1504@ref{Logging In and Out}.
1505
1506
1507@node XPG Functions
1508@subsection XPG User Accounting Database Functions
1509
1510These functions, described in the X/Open Portability Guide, are declared
1511in the header file @file{utmpx.h}.
1512@pindex utmpx.h
1513
1514@deftp {Data Type} {struct utmpx}
1515The @code{utmpx} data structure contains at least the following members:
1516
1517@table @code
1518@item short int ut_type
1519Specifies the type of login; one of @code{EMPTY}, @code{RUN_LVL},
1520@code{BOOT_TIME}, @code{OLD_TIME}, @code{NEW_TIME}, @code{INIT_PROCESS},
1521@code{LOGIN_PROCESS}, @code{USER_PROCESS} or @code{DEAD_PROCESS}.
1522
1523@item pid_t ut_pid
1524The process ID number of the login process.
1525
1526@item char ut_line[]
1527The device name of the tty (without @file{/dev/}).
1528
1529@item char ut_id[]
1530The inittab ID of the process.
1531
1532@item char ut_user[]
1533The user's login name.
1534
1535@item struct timeval ut_tv
1536Time the entry was made. For entries of type @code{OLD_TIME} this is
1537the time when the system clock changed, and for entries of type
1538@code{NEW_TIME} this is the time the system clock was set to.
1539@end table
1540In @theglibc{}, @code{struct utmpx} is identical to @code{struct
1541utmp} except for the fact that including @file{utmpx.h} does not make
1542visible the declaration of @code{struct exit_status}.
1543@end deftp
1544
1545The following macros are defined for use as values for the
1546@code{ut_type} member of the @code{utmpx} structure. The values are
1547integer constants and are, in @theglibc{}, identical to the
1548definitions in @file{utmp.h}.
1549
1550@table @code
1551@comment utmpx.h
1552@comment XPG4.2
1553@vindex EMPTY
1554@item EMPTY
1555This macro is used to indicate that the entry contains no valid user
1556accounting information.
1557
1558@comment utmpx.h
1559@comment XPG4.2
1560@vindex RUN_LVL
1561@item RUN_LVL
1562This macro is used to identify the systems runlevel.
1563
1564@comment utmpx.h
1565@comment XPG4.2
1566@vindex BOOT_TIME
1567@item BOOT_TIME
1568This macro is used to identify the time of system boot.
1569
1570@comment utmpx.h
1571@comment XPG4.2
1572@vindex OLD_TIME
1573@item OLD_TIME
1574This macro is used to identify the time when the system clock changed.
1575
1576@comment utmpx.h
1577@comment XPG4.2
1578@vindex NEW_TIME
1579@item NEW_TIME
1580This macro is used to identify the time after the system changed.
1581
1582@comment utmpx.h
1583@comment XPG4.2
1584@vindex INIT_PROCESS
1585@item INIT_PROCESS
1586This macro is used to identify a process spawned by the init process.
1587
1588@comment utmpx.h
1589@comment XPG4.2
1590@vindex LOGIN_PROCESS
1591@item LOGIN_PROCESS
1592This macro is used to identify the session leader of a logged in user.
1593
1594@comment utmpx.h
1595@comment XPG4.2
1596@vindex USER_PROCESS
1597@item USER_PROCESS
1598This macro is used to identify a user process.
1599
1600@comment utmpx.h
1601@comment XPG4.2
1602@vindex DEAD_PROCESS
1603@item DEAD_PROCESS
1604This macro is used to identify a terminated process.
1605@end table
1606
1607The size of the @code{ut_line}, @code{ut_id} and @code{ut_user} arrays
1608can be found using the @code{sizeof} operator.
1609
1610@comment utmpx.h
1611@comment XPG4.2
1612@deftypefun void setutxent (void)
1613@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1614This function is similar to @code{setutent}. In @theglibc{} it is
1615simply an alias for @code{setutent}.
1616@end deftypefun
1617
1618@comment utmpx.h
1619@comment XPG4.2
1620@deftypefun {struct utmpx *} getutxent (void)
1621@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
1622The @code{getutxent} function is similar to @code{getutent}, but returns
1623a pointer to a @code{struct utmpx} instead of @code{struct utmp}. In
1624@theglibc{} it simply is an alias for @code{getutent}.
1625@end deftypefun
1626
1627@comment utmpx.h
1628@comment XPG4.2
1629@deftypefun void endutxent (void)
1630@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
1631This function is similar to @code{endutent}. In @theglibc{} it is
1632simply an alias for @code{endutent}.
1633@end deftypefun
1634
1635@comment utmpx.h
1636@comment XPG4.2
1637@deftypefun {struct utmpx *} getutxid (const struct utmpx *@var{id})
1638@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}}
1639This function is similar to @code{getutid}, but uses @code{struct utmpx}
1640instead of @code{struct utmp}. In @theglibc{} it is simply an alias
1641for @code{getutid}.
1642@end deftypefun
1643
1644@comment utmpx.h
1645@comment XPG4.2
1646@deftypefun {struct utmpx *} getutxline (const struct utmpx *@var{line})
1647@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
1648This function is similar to @code{getutid}, but uses @code{struct utmpx}
1649instead of @code{struct utmp}. In @theglibc{} it is simply an alias
1650for @code{getutline}.
1651@end deftypefun
1652
1653@comment utmpx.h
1654@comment XPG4.2
1655@deftypefun {struct utmpx *} pututxline (const struct utmpx *@var{utmp})
1656@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1657The @code{pututxline} function is functionally identical to
1658@code{pututline}, but uses @code{struct utmpx} instead of @code{struct
1659utmp}. In @theglibc{}, @code{pututxline} is simply an alias for
1660@code{pututline}.
1661@end deftypefun
1662
1663@comment utmpx.h
1664@comment XPG4.2
1665@deftypefun int utmpxname (const char *@var{file})
1666@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}}
1667The @code{utmpxname} function is functionally identical to
1668@code{utmpname}. In @theglibc{}, @code{utmpxname} is simply an
1669alias for @code{utmpname}.
1670@end deftypefun
1671
1672You can translate between a traditional @code{struct utmp} and an XPG
1673@code{struct utmpx} with the following functions. In @theglibc{},
1674these functions are merely copies, since the two structures are
1675identical.
1676
1677@comment utmpx.h
1678@comment utmp.h
1679@comment GNU
1680@deftypefun int getutmp (const struct utmpx *@var{utmpx}, struct utmp *@var{utmp})
1681@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
1682@code{getutmp} copies the information, insofar as the structures are
1683compatible, from @var{utmpx} to @var{utmp}.
1684@end deftypefun
1685
1686@comment utmpx.h
1687@comment utmp.h
1688@comment GNU
1689@deftypefun int getutmpx (const struct utmp *@var{utmp}, struct utmpx *@var{utmpx})
1690@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
1691@code{getutmpx} copies the information, insofar as the structures are
1692compatible, from @var{utmp} to @var{utmpx}.
1693@end deftypefun
1694
1695
1696@node Logging In and Out
1697@subsection Logging In and Out
1698
1699These functions, derived from BSD, are available in the separate
1700@file{libutil} library, and declared in @file{utmp.h}.
1701@pindex utmp.h
1702
1703Note that the @code{ut_user} member of @code{struct utmp} is called
1704@code{ut_name} in BSD. Therefore, @code{ut_name} is defined as an alias
1705for @code{ut_user} in @file{utmp.h}.
1706
1707@comment utmp.h
1708@comment BSD
1709@deftypefun int login_tty (int @var{filedes})
1710@safety{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
1711@c If this function is canceled, it may have succeeded in redirecting
1712@c only some of the standard streams to the newly opened terminal.
1713@c Should there be a safety annotation for this?
1714@c login_tty @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
1715@c setsid dup ok
1716@c ioctl dup ok
1717@c ttyname dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
1718@c close dup @acsfd
1719@c open dup @acsfd
1720@c dup2 dup ok
1721This function makes @var{filedes} the controlling terminal of the
1722current process, redirects standard input, standard output and
1723standard error output to this terminal, and closes @var{filedes}.
1724
1725This function returns @code{0} on successful completion, and @code{-1}
1726on error.
1727@end deftypefun
1728
1729@comment utmp.h
1730@comment BSD
1731@deftypefun void login (const struct utmp *@var{entry})
1732@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsfd{} @acsmem{}}}
1733@c login @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acucorrupt @acsfd @acsmem
1734@c getpid dup ok
1735@c tty_name @ascuheap @acucorrupt @acsmem @acsfd
1736@c ttyname_r dup @ascuheap @acsmem @acsfd
1737@c memchr dup ok
1738@c realloc dup @ascuheap @acsmem
1739@c malloc dup @ascuheap @acsmem
1740@c free dup @ascuheap @acsmem
1741@c strncmp dup ok
1742@c basename dup ok
1743@c strncpy dup ok
1744@c utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem
1745@c setutent dup @mtasurace:utent @asulock @aculock @acsfd
1746@c pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1747@c endutent dup @mtasurace:utent @asulock @aculock
1748@c free dup @ascuheap @acsmem
1749@c updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd
1750The @code{login} functions inserts an entry into the user accounting
1751database. The @code{ut_line} member is set to the name of the terminal
1752on standard input. If standard input is not a terminal @code{login}
1753uses standard output or standard error output to determine the name of
1754the terminal. If @code{struct utmp} has a @code{ut_type} member,
1755@code{login} sets it to @code{USER_PROCESS}, and if there is an
1756@code{ut_pid} member, it will be set to the process ID of the current
1757process. The remaining entries are copied from @var{entry}.
1758
1759A copy of the entry is written to the user accounting log file.
1760@end deftypefun
1761
1762@comment utmp.h
1763@comment BSD
1764@deftypefun int logout (const char *@var{ut_line})
1765@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
1766@c logout @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acsfd @acsmem
1767@c utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem
1768@c setutent dup @mtasurace:utent @asulock @aculock @acsfd
1769@c strncpy dup ok
1770@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1771@c bzero dup ok
1772@c gettimeofday dup ok
1773@c time dup ok
1774@c pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1775@c endutent dup @mtasurace:utent @asulock @aculock
1776This function modifies the user accounting database to indicate that the
1777user on @var{ut_line} has logged out.
1778
1779The @code{logout} function returns @code{1} if the entry was successfully
1780written to the database, or @code{0} on error.
1781@end deftypefun
1782
1783@comment utmp.h
1784@comment BSD
1785@deftypefun void logwtmp (const char *@var{ut_line}, const char *@var{ut_name}, const char *@var{ut_host})
1786@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}}
1787@c logwtmp @mtascusig:ALRM @mtascutimer @acsfd
1788@c memset dup ok
1789@c getpid dup ok
1790@c strncpy dup ok
1791@c gettimeofday dup ok
1792@c time dup ok
1793@c updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd
1794The @code{logwtmp} function appends an entry to the user accounting log
1795file, for the current time and the information provided in the
1796@var{ut_line}, @var{ut_name} and @var{ut_host} arguments.
1797@end deftypefun
1798
1799@strong{Portability Note:} The BSD @code{struct utmp} only has the
1800@code{ut_line}, @code{ut_name}, @code{ut_host} and @code{ut_time}
1801members. Older systems do not even have the @code{ut_host} member.
1802
1803
1804@node User Database
1805@section User Database
1806@cindex user database
1807@cindex password database
1808@pindex /etc/passwd
1809
1810This section describes how to search and scan the database of registered
1811users. The database itself is kept in the file @file{/etc/passwd} on
1812most systems, but on some systems a special network server gives access
1813to it.
1814
1815@menu
1816* User Data Structure:: What each user record contains.
1817* Lookup User:: How to look for a particular user.
1818* Scanning All Users:: Scanning the list of all users, one by one.
1819* Writing a User Entry:: How a program can rewrite a user's record.
1820@end menu
1821
1822@node User Data Structure
1823@subsection The Data Structure that Describes a User
1824
1825The functions and data structures for accessing the system user database
1826are declared in the header file @file{pwd.h}.
1827@pindex pwd.h
1828
1829@comment pwd.h
1830@comment POSIX.1
1831@deftp {Data Type} {struct passwd}
1832The @code{passwd} data structure is used to hold information about
1833entries in the system user data base. It has at least the following members:
1834
1835@table @code
1836@item char *pw_name
1837The user's login name.
1838
1839@item char *pw_passwd.
1840The encrypted password string.
1841
1842@item uid_t pw_uid
1843The user ID number.
1844
1845@item gid_t pw_gid
1846The user's default group ID number.
1847
1848@item char *pw_gecos
1849A string typically containing the user's real name, and possibly other
1850information such as a phone number.
1851
1852@item char *pw_dir
1853The user's home directory, or initial working directory. This might be
1854a null pointer, in which case the interpretation is system-dependent.
1855
1856@item char *pw_shell
1857The user's default shell, or the initial program run when the user logs in.
1858This might be a null pointer, indicating that the system default should
1859be used.
1860@end table
1861@end deftp
1862
1863@node Lookup User
1864@subsection Looking Up One User
1865@cindex converting user ID to user name
1866@cindex converting user name to user ID
1867
1868You can search the system user database for information about a
1869specific user using @code{getpwuid} or @code{getpwnam}. These
1870functions are declared in @file{pwd.h}.
1871
1872@comment pwd.h
1873@comment POSIX.1
1874@deftypefun {struct passwd *} getpwuid (uid_t @var{uid})
1875@safety{@prelim{}@mtunsafe{@mtasurace{:pwuid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
1876@c getpwuid @mtasurace:pwuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1877@c libc_lock_lock dup @asulock @aculock
1878@c malloc dup @ascuheap @acsmem
1879@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1880@c realloc dup @ascuheap @acsmem
1881@c free dup @ascuheap @acsmem
1882@c libc_lock_unlock dup @aculock
1883This function returns a pointer to a statically-allocated structure
1884containing information about the user whose user ID is @var{uid}. This
1885structure may be overwritten on subsequent calls to @code{getpwuid}.
1886
1887A null pointer value indicates there is no user in the data base with
1888user ID @var{uid}.
1889@end deftypefun
1890
1891@comment pwd.h
1892@comment POSIX.1c
1893@deftypefun int getpwuid_r (uid_t @var{uid}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
1894@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
1895@c getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1896@c nscd_getpwuid_r @ascuheap @acsfd @acsmem
1897@c itoa_word dup ok
1898@c nscd_getpw_r @ascuheap @acsfd @acsmem
1899@c nscd_get_map_ref @ascuheap @acsfd @acsmem
1900@c nscd_acquire_maplock ok
1901@c nscd_get_mapping @ascuheap @acsfd @acsmem
1902@c open_socket dup @acsfd
1903@c memset dup ok
1904@c wait_on_socket dup ok
1905@c recvmsg dup ok
1906@c strcmp dup ok
1907@c fstat64 dup ok
1908@c mmap dup @acsmem
1909@c munmap dup @acsmem
1910@c malloc dup @ascuheap @acsmem
1911@c close dup ok
1912@c nscd_unmap dup @ascuheap @acsmem
1913@c nscd_cache_search ok
1914@c nis_hash ok
1915@c memcmp dup ok
1916@c nscd_open_socket @acsfd
1917@c open_socket @acsfd
1918@c socket dup @acsfd
1919@c fcntl dup ok
1920@c strcpy dup ok
1921@c connect dup ok
1922@c send dup ok
1923@c gettimeofday dup ok
1924@c poll dup ok
1925@c close_not_cancel_no_status dup @acsfd
1926@c wait_on_socket dup ok
1927@c read dup ok
1928@c close_not_cancel_no_status dup @acsfd
1929@c readall ok
1930@c read dup ok
1931@c wait_on_socket ok
1932@c poll dup ok
1933@c gettimeofday dup ok
1934@c memcpy dup ok
1935@c close_not_cancel_no_status dup @acsfd
1936@c nscd_drop_map_ref @ascuheap @acsmem
1937@c nscd_unmap dup @ascuheap @acsmem
1938@c nscd_unmap @ascuheap @acsmem
1939@c munmap dup ok
1940@c free dup @ascuheap @acsmem
1941@c nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1942@c nss_database_lookup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
1943@c libc_lock_lock @asulock @aculock
1944@c libc_lock_unlock @aculock
1945@c nss_parse_file @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
1946@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
1947@c fsetlocking dup ok [no concurrent uses]
1948@c malloc dup @asulock @aculock @acsfd @acsmem
1949@c fclose dup @ascuheap @asulock @acsmem @acsfd @aculock
1950@c getline dup @ascuheap @aculock @acucorrupt @acsmem
1951@c strchrnul dup ok
1952@c nss_getline @mtslocale @ascuheap @acsmem
1953@c isspace @mtslocale^^
1954@c strlen dup ok
1955@c malloc dup @asulock @aculock @acsfd @acsmem
1956@c memcpy dup ok
1957@c nss_parse_service_list dup @mtslocale^, @ascuheap @acsmem
1958@c feof_unlocked dup ok
1959@c free dup @asulock @aculock @acsfd @acsmem
1960@c strcmp dup ok
1961@c nss_parse_service_list @mtslocale^, @ascuheap @acsmem
1962@c isspace @mtslocale^^
1963@c malloc dup @asulock @aculock @acsfd @acsmem
1964@c mempcpy dup ok
1965@c strncasecmp dup ok
1966@c free dup @asulock @aculock @acsfd @acsmem
1967@c malloc dup @asulock @aculock @acsfd @acsmem
1968@c nss_lookup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1969@c nss_lookup_function @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1970@c libc_lock_lock @asulock @aculock
1971@c tsearch @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
1972@c known_compare ok
1973@c strcmp dup ok
1974@c malloc dup @ascuheap @acsmem
1975@c tdelete @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
1976@c free dup @ascuheap @acsmem
1977@c nss_load_library @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
1978@c nss_new_service @ascuheap @acsmem
1979@c strcmp dup ok
1980@c malloc dup @ascuheap @acsmem
1981@c strlen dup ok
1982@c stpcpy dup ok
1983@c libc_dlopen @ascudlopen @ascuheap @asulock @aculock @acsfd @acsmem
1984@c libc_dlsym dup @asulock @aculock @acsfd @acsmem
1985@c *ifct(*nscd_init_cb) @ascuplugin
1986@c stpcpy dup ok
1987@c libc_dlsym dup @asulock @aculock @acsfd @acsmem
1988@c libc_lock_unlock dup ok
1989@c nss_next_action ok
1990@c *fct.l -> _nss_*_getpwuid_r @ascuplugin
1991@c nss_next2 @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1992@c nss_next_action dup ok
1993@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1994
1995@c _nss_files_getpwuid_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
1996@c libc_lock_lock dup @asulock @aculock
1997@c internal_setent @ascuheap @asulock @aculock @acsmem @acsfd
1998@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
1999@c fileno dup ok
2000@c fcntl dup ok
2001@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
2002@c rewind dup @aculock [stream guarded by non-recursive pwent lock]
2003@c internal_getent @mtslocale^
2004@c fgets_unlocked dup ok [stream guarded by non-recursive pwent lock]
2005@c isspace dup @mtslocale^^
2006@c _nss_files_parse_pwent = parse_line ok
2007@c strpbrk dup ok
2008@c internal_endent @ascuheap @asulock @aculock @acsmem @acsfd
2009@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
2010@c libc_lock_unlock dup @aculock
2011
2012@c _nss_nis_getpwuid_r ... not fully reviewed (assumed) @asuinit @asulock @acucorrupt @aculock
2013@c yp_get_default_domain @asulock @aculock
2014@c libc_lock_lock dup @asulock @aculock
2015@c getdomainname dup ok
2016@c strcmp dup ok
2017@c libc_lock_unlock dup @aculock
2018@c snprintf dup @ascuheap @acsmem
2019@c yp_match
2020@c do_ypcall_tr(xdr_ypreq_key,xdr_ypresp_val)
2021@c do_ypcall(xdr_ypreq_key,xdr_ypresp_val)
2022@c libc_lock_lock @asulock @aculock
2023@c strcmp
2024@c yp_bind
2025@c ypclnt_call
2026@c clnt_call
2027@c clnt_perror
2028@c libc_lock_unlock @aculock
2029@c yp_unbind_locked
2030@c yp_unbind
2031@c strcmp dup ok
2032@c calloc dup @asulock @aculock @acsfd @acsmem
2033@c yp_bind_file
2034@c strlen dup ok
2035@c snprintf dup @ascuheap @acsmem
2036@c open dup @acsfd [cancelpt]
2037@c pread dup [cancelpt]
2038@c yp_bind_client_create
2039@c close dup @acsfd [cancelpt]
2040@c yp_bind_ypbindprog
2041@c clnttcp_create
2042@c clnt_destroy
2043@c clnt_call(xdr_domainname,xdr_ypbind_resp)
2044@c memset dup ok
2045@c yp_bind_client_create
2046@c free dup @asulock @aculock @acsfd @acsmem
2047@c calloc dup @asulock @aculock @acsfd @acsmem
2048@c free dup @asulock @aculock @acsfd @acsmem
2049@c ypprot_err
2050@c memcpy dup ok
2051@c xdr_free(xdr_ypresp_val)
2052@c xdr_ypresp_val
2053@c xdr_ypstat
2054@c xdr_enum
2055@c XDR_PUTLONG
2056@c *x_putlong
2057@c XDR_GETLONG
2058@c *x_getlong
2059@c xdr_long
2060@c XDR_PUTLONG dup
2061@c XDR_GETLONG dup
2062@c xdr_short
2063@c XDR_PUTLONG dup
2064@c XDR_GETLONG dup
2065@c xdr_valdat
2066@c xdr_bytes
2067@c xdr_u_int
2068@c XDR_PUTLONG dup
2069@c XDR_GETLONG dup
2070@c mem_alloc @ascuheap @acsmem
2071@c malloc dup @ascuheap @acsmem
2072@c xdr_opaque
2073@c XDR_GETBYTES
2074@c *x_getbytes
2075@c XDR_PUTBYTES
2076@c *x_putbytes
2077@c mem_free @ascuheap @acsmem
2078@c free dup @ascuheap @acsmem
2079@c yperr2nss ok
2080@c strchr dup ok
2081@c _nls_default_nss @asuinit @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
2082@c init @asuinit^, @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
2083@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
2084@c fsetlocking ok [no concurrent uses]
2085@c feof_unlocked dup ok
2086@c getline dup @ascuheap @aculock @acucorrupt @acsmem
2087@c isspace dup @mtslocale^^
2088@c strncmp dup ok
2089@c free dup @asulock @acsmem @acsfd @aculock
2090@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
2091@c free dup @asulock @acsmem @acsfd @aculock
2092@c mempcpy dup ok
2093@c strncpy dup ok
2094@c isspace dup @mtslocale^^
2095@c _nss_files_parse_pwent ok
2096This function is similar to @code{getpwuid} in that it returns
2097information about the user whose user ID is @var{uid}. However, it
2098fills the user supplied structure pointed to by @var{result_buf} with
2099the information instead of using a static buffer. The first
2100@var{buflen} bytes of the additional buffer pointed to by @var{buffer}
2101are used to contain additional information, normally strings which are
2102pointed to by the elements of the result structure.
2103
2104If a user with ID @var{uid} is found, the pointer returned in
2105@var{result} points to the record which contains the wanted data (i.e.,
2106@var{result} contains the value @var{result_buf}). If no user is found
2107or if an error occurred, the pointer returned in @var{result} is a null
2108pointer. The function returns zero or an error code. If the buffer
2109@var{buffer} is too small to contain all the needed information, the
2110error code @code{ERANGE} is returned and @var{errno} is set to
2111@code{ERANGE}.
2112@end deftypefun
2113
2114
2115@comment pwd.h
2116@comment POSIX.1
2117@deftypefun {struct passwd *} getpwnam (const char *@var{name})
2118@safety{@prelim{}@mtunsafe{@mtasurace{:pwnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2119@c getpwnam @mtasurace:pwnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2120@c libc_lock_lock dup @asulock @aculock
2121@c malloc dup @ascuheap @acsmem
2122@c getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2123@c realloc dup @ascuheap @acsmem
2124@c free dup @ascuheap @acsmem
2125@c libc_lock_unlock dup @aculock
2126This function returns a pointer to a statically-allocated structure
2127containing information about the user whose user name is @var{name}.
2128This structure may be overwritten on subsequent calls to
2129@code{getpwnam}.
2130
2131A null pointer return indicates there is no user named @var{name}.
2132@end deftypefun
2133
2134@comment pwd.h
2135@comment POSIX.1c
2136@deftypefun int getpwnam_r (const char *@var{name}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
2137@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2138@c getpwnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2139@c nscd_getpwnam_r @ascuheap @asulock @aculock @acsfd @acsmem
2140@c strlen dup ok
2141@c nscd_getpw_r dup @ascuheap @asulock @aculock @acsfd @acsmem
2142@c nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2143@c *fct.l @ascuplugin
2144@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2145@c
2146@c _nss_files_getpwnam_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
2147@c libc_lock_lock dup @asulock @aculock
2148@c internal_setent dup @ascuheap @asulock @aculock @acsmem @acsfd
2149@c internal_getent dup @mtslocale^
2150@c strcmp dup ok
2151@c internal_endent dup @ascuheap @asulock @aculock @acsmem @acsfd
2152@c libc_lock_unlock dup @aculock
2153@c
2154@c _nss_*_getpwnam_r (assumed) @asuinit @asulock @acucorrupt @aculock
2155
2156This function is similar to @code{getpwnam} in that is returns
2157information about the user whose user name is @var{name}. However, like
2158@code{getpwuid_r}, it fills the user supplied buffers in
2159@var{result_buf} and @var{buffer} with the information instead of using
2160a static buffer.
2161
2162The return values are the same as for @code{getpwuid_r}.
2163@end deftypefun
2164
2165
2166@node Scanning All Users
2167@subsection Scanning the List of All Users
2168@cindex scanning the user list
2169
2170This section explains how a program can read the list of all users in
2171the system, one user at a time. The functions described here are
2172declared in @file{pwd.h}.
2173
2174You can use the @code{fgetpwent} function to read user entries from a
2175particular file.
2176
2177@comment pwd.h
2178@comment SVID
2179@deftypefun {struct passwd *} fgetpwent (FILE *@var{stream})
2180@safety{@prelim{}@mtunsafe{@mtasurace{:fpwent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
2181@c fgetpwent @mtasurace:fpwent @asucorrupt @asulock @acucorrupt @aculock
2182@c fgetpos dup @asucorrupt @aculock @acucorrupt
2183@c libc_lock_lock dup @asulock @aculock
2184@c malloc dup @ascuheap @acsmem
2185@c fgetpwent_r dup @asucorrupt @acucorrupt @aculock
2186@c realloc dup @ascuheap @acsmem
2187@c free dup @ascuheap @acsmem
2188@c fsetpos dup @asucorrupt @aculock @acucorrupt
2189@c libc_lock_unlock dup @aculock
2190This function reads the next user entry from @var{stream} and returns a
2191pointer to the entry. The structure is statically allocated and is
2192rewritten on subsequent calls to @code{fgetpwent}. You must copy the
2193contents of the structure if you wish to save the information.
2194
2195The stream must correspond to a file in the same format as the standard
2196password database file.
2197@end deftypefun
2198
2199@comment pwd.h
2200@comment GNU
2201@deftypefun int fgetpwent_r (FILE *@var{stream}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
2202@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
2203@c fgetpwent_r @asucorrupt @acucorrupt @aculock
2204@c flockfile dup @aculock
2205@c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
2206@c feof_unlocked dup ok
2207@c funlockfile dup @aculock
2208@c isspace dup @mtslocale^^
2209@c parse_line dup ok
2210This function is similar to @code{fgetpwent} in that it reads the next
2211user entry from @var{stream}. But the result is returned in the
2212structure pointed to by @var{result_buf}. The
2213first @var{buflen} bytes of the additional buffer pointed to by
2214@var{buffer} are used to contain additional information, normally
2215strings which are pointed to by the elements of the result structure.
2216
2217The stream must correspond to a file in the same format as the standard
2218password database file.
2219
2220If the function returns zero @var{result} points to the structure with
2221the wanted data (normally this is in @var{result_buf}). If errors
2222occurred the return value is nonzero and @var{result} contains a null
2223pointer.
2224@end deftypefun
2225
2226The way to scan all the entries in the user database is with
2227@code{setpwent}, @code{getpwent}, and @code{endpwent}.
2228
2229@comment pwd.h
2230@comment SVID, BSD
2231@deftypefun void setpwent (void)
2232@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2233@c setpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2234@c libc_lock_lock @asulock @aculock
2235@c nss_setent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2236@c ** resolv's res_maybe_init not called here
2237@c setup(nss_passwd_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2238@c *lookup_fct = nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2239@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2240@c *fct.f @mtasurace:pwent @ascuplugin
2241@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2242@c libc_lock_unlock @aculock
2243This function initializes a stream which @code{getpwent} and
2244@code{getpwent_r} use to read the user database.
2245@end deftypefun
2246
2247@comment pwd.h
2248@comment POSIX.1
2249@deftypefun {struct passwd *} getpwent (void)
2250@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtasurace{:pwentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2251@c getpwent @mtasurace:pwent @mtasurace:pwentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2252@c libc_lock_lock dup @asulock @aculock
2253@c nss_getent(getpwent_r) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2254@c malloc dup @ascuheap @acsmem
2255@c *func = getpwent_r dup @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2256@c realloc dup @ascuheap @acsmem
2257@c free dup @ascuheap @acsmem
2258@c libc_lock_unlock dup @aculock
2259The @code{getpwent} function reads the next entry from the stream
2260initialized by @code{setpwent}. It returns a pointer to the entry. The
2261structure is statically allocated and is rewritten on subsequent calls
2262to @code{getpwent}. You must copy the contents of the structure if you
2263wish to save the information.
2264
2265A null pointer is returned when no more entries are available.
2266@end deftypefun
2267
2268@comment pwd.h
2269@comment GNU
2270@deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
2271@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2272@c The static buffer here is not the result_buf, but rather the
2273@c variables that keep track of what nss backend we've last used, and
2274@c whatever internal state the nss backend uses to keep track of the
2275@c last read entry.
2276@c getpwent_r @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2277@c libc_lock_lock dup @asulock @aculock
2278@c nss_getent_r(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2279@c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2280@c *fct.f @mtasurace:pwent @ascuplugin
2281@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2282@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2283@c *sfct.f @mtasurace:pwent @ascuplugin
2284@c libc_lock_unlock dup @aculock
2285This function is similar to @code{getpwent} in that it returns the next
2286entry from the stream initialized by @code{setpwent}. Like
2287@code{fgetpwent_r}, it uses the user-supplied buffers in
2288@var{result_buf} and @var{buffer} to return the information requested.
2289
2290The return values are the same as for @code{fgetpwent_r}.
2291
2292@end deftypefun
2293
2294@comment pwd.h
2295@comment SVID, BSD
2296@deftypefun void endpwent (void)
2297@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2298@c endpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2299@c libc_lock_lock @asulock @aculock
2300@c nss_endent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2301@c ** resolv's res_maybe_init not called here
2302@c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2303@c *fct.f @mtasurace:pwent @ascuplugin
2304@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2305@c libc_lock_unlock @aculock
2306This function closes the internal stream used by @code{getpwent} or
2307@code{getpwent_r}.
2308@end deftypefun
2309
2310@node Writing a User Entry
2311@subsection Writing a User Entry
2312
2313@comment pwd.h
2314@comment SVID
2315@deftypefun int putpwent (const struct passwd *@var{p}, FILE *@var{stream})
2316@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
2317@c putpwent @mtslocale @asucorrupt @aculock @acucorrupt
2318@c fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem]
2319This function writes the user entry @code{*@var{p}} to the stream
2320@var{stream}, in the format used for the standard user database
2321file. The return value is zero on success and nonzero on failure.
2322
2323This function exists for compatibility with SVID. We recommend that you
2324avoid using it, because it makes sense only on the assumption that the
2325@code{struct passwd} structure has no members except the standard ones;
2326on a system which merges the traditional Unix data base with other
2327extended information about users, adding an entry using this function
2328would inevitably leave out much of the important information.
2329@c Then how are programmers to modify the password file? -zw
2330
2331The group and user ID fields are left empty if the group or user name
2332starts with a - or +.
2333
2334The function @code{putpwent} is declared in @file{pwd.h}.
2335@end deftypefun
2336
2337@node Group Database
2338@section Group Database
2339@cindex group database
2340@pindex /etc/group
2341
2342This section describes how to search and scan the database of
2343registered groups. The database itself is kept in the file
2344@file{/etc/group} on most systems, but on some systems a special network
2345service provides access to it.
2346
2347@menu
2348* Group Data Structure:: What each group record contains.
2349* Lookup Group:: How to look for a particular group.
2350* Scanning All Groups:: Scanning the list of all groups.
2351@end menu
2352
2353@node Group Data Structure
2354@subsection The Data Structure for a Group
2355
2356The functions and data structures for accessing the system group
2357database are declared in the header file @file{grp.h}.
2358@pindex grp.h
2359
2360@comment grp.h
2361@comment POSIX.1
2362@deftp {Data Type} {struct group}
2363The @code{group} structure is used to hold information about an entry in
2364the system group database. It has at least the following members:
2365
2366@table @code
2367@item char *gr_name
2368The name of the group.
2369
2370@item gid_t gr_gid
2371The group ID of the group.
2372
2373@item char **gr_mem
2374A vector of pointers to the names of users in the group. Each user name
2375is a null-terminated string, and the vector itself is terminated by a
2376null pointer.
2377@end table
2378@end deftp
2379
2380@node Lookup Group
2381@subsection Looking Up One Group
2382@cindex converting group name to group ID
2383@cindex converting group ID to group name
2384
2385You can search the group database for information about a specific
2386group using @code{getgrgid} or @code{getgrnam}. These functions are
2387declared in @file{grp.h}.
2388
2389@comment grp.h
2390@comment POSIX.1
2391@deftypefun {struct group *} getgrgid (gid_t @var{gid})
2392@safety{@prelim{}@mtunsafe{@mtasurace{:grgid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2393@c getgrgid =~ getpwuid dup @mtasurace:grgid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2394@c getgrgid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2395This function returns a pointer to a statically-allocated structure
2396containing information about the group whose group ID is @var{gid}.
2397This structure may be overwritten by subsequent calls to
2398@code{getgrgid}.
2399
2400A null pointer indicates there is no group with ID @var{gid}.
2401@end deftypefun
2402
2403@comment grp.h
2404@comment POSIX.1c
2405@deftypefun int getgrgid_r (gid_t @var{gid}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2406@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2407@c getgrgid_r =~ getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2408@c nscd_getgrgid_r @ascuheap @acsfd @acsmem
2409@c itoa_word dup ok
2410@c nscd_getgr_r @ascuheap @acsfd @acsmem
2411@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem
2412@c nscd_cache_search dup ok
2413@c nscd_open_socket dup @acsfd
2414@c readvall ok
2415@c readv dup ok
2416@c memcpy dup ok
2417@c wait_on_socket dup ok
2418@c memcpy dup ok
2419@c readall dup ok
2420@c close_not_cancel_no_status dup @acsfd
2421@c nscd_drop_map_ref dup @ascuheap @acsmem
2422@c nscd_unmap dup @ascuheap @acsmem
2423@c nss_group_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2424@c *fct.l -> _nss_*_getgrgid_r @ascuplugin
2425@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2426This function is similar to @code{getgrgid} in that it returns
2427information about the group whose group ID is @var{gid}. However, it
2428fills the user supplied structure pointed to by @var{result_buf} with
2429the information instead of using a static buffer. The first
2430@var{buflen} bytes of the additional buffer pointed to by @var{buffer}
2431are used to contain additional information, normally strings which are
2432pointed to by the elements of the result structure.
2433
2434If a group with ID @var{gid} is found, the pointer returned in
2435@var{result} points to the record which contains the wanted data (i.e.,
2436@var{result} contains the value @var{result_buf}). If no group is found
2437or if an error occurred, the pointer returned in @var{result} is a null
2438pointer. The function returns zero or an error code. If the buffer
2439@var{buffer} is too small to contain all the needed information, the
2440error code @code{ERANGE} is returned and @var{errno} is set to
2441@code{ERANGE}.
2442@end deftypefun
2443
2444@comment grp.h
2445@comment SVID, BSD
2446@deftypefun {struct group *} getgrnam (const char *@var{name})
2447@safety{@prelim{}@mtunsafe{@mtasurace{:grnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2448@c getgrnam =~ getpwnam dup @mtasurace:grnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2449@c getgrnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2450This function returns a pointer to a statically-allocated structure
2451containing information about the group whose group name is @var{name}.
2452This structure may be overwritten by subsequent calls to
2453@code{getgrnam}.
2454
2455A null pointer indicates there is no group named @var{name}.
2456@end deftypefun
2457
2458@comment grp.h
2459@comment POSIX.1c
2460@deftypefun int getgrnam_r (const char *@var{name}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2461@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2462@c getgrnam_r =~ getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2463@c nscd_getgrnam_r @ascuheap @asulock @aculock @acsfd @acsmem
2464@c strlen dup ok
2465@c nscd_getgr_r dup @ascuheap @asulock @aculock @acsfd @acsmem
2466@c nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2467@c *fct.l @ascuplugin
2468@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2469This function is similar to @code{getgrnam} in that is returns
2470information about the group whose group name is @var{name}. Like
2471@code{getgrgid_r}, it uses the user supplied buffers in
2472@var{result_buf} and @var{buffer}, not a static buffer.
2473
2474The return values are the same as for @code{getgrgid_r}
2475@code{ERANGE}.
2476@end deftypefun
2477
2478@node Scanning All Groups
2479@subsection Scanning the List of All Groups
2480@cindex scanning the group list
2481
2482This section explains how a program can read the list of all groups in
2483the system, one group at a time. The functions described here are
2484declared in @file{grp.h}.
2485
2486You can use the @code{fgetgrent} function to read group entries from a
2487particular file.
2488
2489@comment grp.h
2490@comment SVID
2491@deftypefun {struct group *} fgetgrent (FILE *@var{stream})
2492@safety{@prelim{}@mtunsafe{@mtasurace{:fgrent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
2493@c fgetgrent @mtasurace:fgrent @asucorrupt @asulock @acucorrupt @aculock
2494@c fgetpos dup @asucorrupt @aculock @acucorrupt
2495@c libc_lock_lock dup @asulock @aculock
2496@c malloc dup @ascuheap @acsmem
2497@c fgetgrent_r dup @asucorrupt @acucorrupt @aculock
2498@c realloc dup @ascuheap @acsmem
2499@c free dup @ascuheap @acsmem
2500@c fsetpos dup @asucorrupt @aculock @acucorrupt
2501@c libc_lock_unlock dup @aculock
2502The @code{fgetgrent} function reads the next entry from @var{stream}.
2503It returns a pointer to the entry. The structure is statically
2504allocated and is overwritten on subsequent calls to @code{fgetgrent}. You
2505must copy the contents of the structure if you wish to save the
2506information.
2507
2508The stream must correspond to a file in the same format as the standard
2509group database file.
2510@end deftypefun
2511
2512@comment grp.h
2513@comment GNU
2514@deftypefun int fgetgrent_r (FILE *@var{stream}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2515@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
2516@c fgetgrent_r @asucorrupt @acucorrupt @aculock
2517@c flockfile dup @aculock
2518@c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
2519@c feof_unlocked dup ok
2520@c funlockfile dup @aculock
2521@c isspace dup @mtslocale^^
2522@c parse_line dup ok
2523This function is similar to @code{fgetgrent} in that it reads the next
2524user entry from @var{stream}. But the result is returned in the
2525structure pointed to by @var{result_buf}. The first @var{buflen} bytes
2526of the additional buffer pointed to by @var{buffer} are used to contain
2527additional information, normally strings which are pointed to by the
2528elements of the result structure.
2529
2530This stream must correspond to a file in the same format as the standard
2531group database file.
2532
2533If the function returns zero @var{result} points to the structure with
2534the wanted data (normally this is in @var{result_buf}). If errors
2535occurred the return value is non-zero and @var{result} contains a null
2536pointer.
2537@end deftypefun
2538
2539The way to scan all the entries in the group database is with
2540@code{setgrent}, @code{getgrent}, and @code{endgrent}.
2541
2542@comment grp.h
2543@comment SVID, BSD
2544@deftypefun void setgrent (void)
2545@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2546@c setgrent =~ setpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2547@c ...*lookup_fct = nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2548This function initializes a stream for reading from the group data base.
2549You use this stream by calling @code{getgrent} or @code{getgrent_r}.
2550@end deftypefun
2551
2552@comment grp.h
2553@comment SVID, BSD
2554@deftypefun {struct group *} getgrent (void)
2555@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtasurace{:grentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2556@c getgrent =~ getpwent dup @mtasurace:grent @mtasurace:grentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2557@c *func = getgrent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2558The @code{getgrent} function reads the next entry from the stream
2559initialized by @code{setgrent}. It returns a pointer to the entry. The
2560structure is statically allocated and is overwritten on subsequent calls
2561to @code{getgrent}. You must copy the contents of the structure if you
2562wish to save the information.
2563@end deftypefun
2564
2565@comment grp.h
2566@comment GNU
2567@deftypefun int getgrent_r (struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2568@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2569@c getgrent_r =~ getpwent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2570This function is similar to @code{getgrent} in that it returns the next
2571entry from the stream initialized by @code{setgrent}. Like
2572@code{fgetgrent_r}, it places the result in user-supplied buffers
2573pointed to @var{result_buf} and @var{buffer}.
2574
2575If the function returns zero @var{result} contains a pointer to the data
2576(normally equal to @var{result_buf}). If errors occurred the return
2577value is non-zero and @var{result} contains a null pointer.
2578@end deftypefun
2579
2580@comment grp.h
2581@comment SVID, BSD
2582@deftypefun void endgrent (void)
2583@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2584@c endgrent =~ endpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2585This function closes the internal stream used by @code{getgrent} or
2586@code{getgrent_r}.
2587@end deftypefun
2588
2589@node Database Example
2590@section User and Group Database Example
2591
2592Here is an example program showing the use of the system database inquiry
2593functions. The program prints some information about the user running
2594the program.
2595
2596@smallexample
2597@include db.c.texi
2598@end smallexample
2599
2600Here is some output from this program:
2601
2602@smallexample
2603I am Throckmorton Snurd.
2604My login name is snurd.
2605My uid is 31093.
2606My home directory is /home/fsg/snurd.
2607My default shell is /bin/sh.
2608My default group is guest (12).
2609The members of this group are:
2610 friedman
2611 tami
2612@end smallexample
2613
2614@node Netgroup Database
2615@section Netgroup Database
2616
2617@menu
2618* Netgroup Data:: Data in the Netgroup database and where
2619 it comes from.
2620* Lookup Netgroup:: How to look for a particular netgroup.
2621* Netgroup Membership:: How to test for netgroup membership.
2622@end menu
2623
2624@node Netgroup Data
2625@subsection Netgroup Data
2626
2627@cindex Netgroup
2628Sometimes it is useful to group users according to other criteria
2629(@pxref{Group Database}). E.g., it is useful to associate a certain
2630group of users with a certain machine. On the other hand grouping of
2631host names is not supported so far.
2632
2633In Sun Microsystems SunOS appeared a new kind of database, the netgroup
2634database. It allows grouping hosts, users, and domains freely, giving
2635them individual names. To be more concrete, a netgroup is a list of triples
2636consisting of a host name, a user name, and a domain name where any of
2637the entries can be a wildcard entry matching all inputs. A last
2638possibility is that names of other netgroups can also be given in the
2639list specifying a netgroup. So one can construct arbitrary hierarchies
2640without loops.
2641
2642Sun's implementation allows netgroups only for the @code{nis} or
2643@code{nisplus} service, @pxref{Services in the NSS configuration}. The
2644implementation in @theglibc{} has no such restriction. An entry
2645in either of the input services must have the following form:
2646
2647@smallexample
2648@var{groupname} ( @var{groupname} | @code{(}@var{hostname}@code{,}@var{username}@code{,}@code{domainname}@code{)} )+
2649@end smallexample
2650
2651Any of the fields in the triple can be empty which means anything
2652matches. While describing the functions we will see that the opposite
2653case is useful as well. I.e., there may be entries which will not
2654match any input. For entries like this, a name consisting of the single
2655character @code{-} shall be used.
2656
2657@node Lookup Netgroup
2658@subsection Looking up one Netgroup
2659
2660The lookup functions for netgroups are a bit different to all other
2661system database handling functions. Since a single netgroup can contain
2662many entries a two-step process is needed. First a single netgroup is
2663selected and then one can iterate over all entries in this netgroup.
2664These functions are declared in @file{netdb.h}.
2665
2666@comment netdb.h
2667@comment BSD
2668@deftypefun int setnetgrent (const char *@var{netgroup})
2669@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2670@c setnetgrent @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2671@c libc_lock_lock dup @asulock @aculock
2672@c nscd_setnetgrent @ascuheap @acsfd @acsmem
2673@c __nscd_setnetgrent @ascuheap @acsfd @acsmem
2674@c strlen dup ok
2675@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem
2676@c nscd_cache_search dup ok
2677@c nscd_open_socket dup @acsfd
2678@c malloc dup @ascuheap @acsmem
2679@c readall dup ok
2680@c free dup @ascuheap @acsmem
2681@c close_not_cancel_no_status dup @acsfd
2682@c nscd_drop_map_ref dup @ascuheap @acsmem
2683@c nscd_unmap dup @ascuheap @acsmem
2684@c internal_setnetgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2685@c free_memory dup @ascuheap @acsmem
2686@c free dup @ascuheap @acsmem
2687@c internal_setnetgrent_reuse @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2688@c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2689@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2690@c *endfct @ascuplugin
2691@c (netgroup::)setup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2692@c nss_netgroup_lookup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2693@c nss_netgroup_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2694@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2695@c *fct.f @ascuplugin
2696@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2697@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2698@c *endfct @ascuplugin
2699@c strlen dup ok
2700@c malloc dup @ascuheap @acsmem
2701@c memcpy dup ok
2702@c libc_lock_unlock dup @aculock
2703A call to this function initializes the internal state of the library to
2704allow following calls of the @code{getnetgrent} to iterate over all entries
2705in the netgroup with name @var{netgroup}.
2706
2707When the call is successful (i.e., when a netgroup with this name exists)
2708the return value is @code{1}. When the return value is @code{0} no
2709netgroup of this name is known or some other error occurred.
2710@end deftypefun
2711
2712It is important to remember that there is only one single state for
2713iterating the netgroups. Even if the programmer uses the
2714@code{getnetgrent_r} function the result is not really reentrant since
2715always only one single netgroup at a time can be processed. If the
2716program needs to process more than one netgroup simultaneously she
2717must protect this by using external locking. This problem was
2718introduced in the original netgroups implementation in SunOS and since
2719we must stay compatible it is not possible to change this.
2720
2721Some other functions also use the netgroups state. Currently these are
2722the @code{innetgr} function and parts of the implementation of the
2723@code{compat} service part of the NSS implementation.
2724
2725@comment netdb.h
2726@comment BSD
2727@deftypefun int getnetgrent (char **@var{hostp}, char **@var{userp}, char **@var{domainp})
2728@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtasurace{:netgrentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2729@c getnetgrent @mtasurace:netgrent @mtasurace:netgrentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2730@c uses unsafely a static buffer allocated within a libc_once call
2731@c allocate (libc_once) @ascuheap @acsmem
2732@c malloc dup @ascuheap @acsmem
2733@c getnetgrent_r dup @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2734This function returns the next unprocessed entry of the currently
2735selected netgroup. The string pointers, in which addresses are passed in
2736the arguments @var{hostp}, @var{userp}, and @var{domainp}, will contain
2737after a successful call pointers to appropriate strings. If the string
2738in the next entry is empty the pointer has the value @code{NULL}.
2739The returned string pointers are only valid if none of the netgroup
2740related functions are called.
2741
2742The return value is @code{1} if the next entry was successfully read. A
2743value of @code{0} means no further entries exist or internal errors occurred.
2744@end deftypefun
2745
2746@comment netdb.h
2747@comment GNU
2748@deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, size_t @var{buflen})
2749@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2750@c getnetgrent_r @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2751@c libc_lock_lock dup @asulock @aculock
2752@c internal_getnetgrent_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2753@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2754@c *fct @ascuplugin
2755@c nscd_getnetgrent ok
2756@c rawmemchr dup ok
2757@c internal_setnetgrent_reuse dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2758@c strcmp dup ok
2759@c malloc dup @ascuheap @acsmem
2760@c memcpy dup ok
2761@c libc_lock_unlock dup @aculock
2762This function is similar to @code{getnetgrent} with only one exception:
2763the strings the three string pointers @var{hostp}, @var{userp}, and
2764@var{domainp} point to, are placed in the buffer of @var{buflen} bytes
2765starting at @var{buffer}. This means the returned values are valid
2766even after other netgroup related functions are called.
2767
2768The return value is @code{1} if the next entry was successfully read and
2769the buffer contains enough room to place the strings in it. @code{0} is
2770returned in case no more entries are found, the buffer is too small, or
2771internal errors occurred.
2772
2773This function is a GNU extension. The original implementation in the
2774SunOS libc does not provide this function.
2775@end deftypefun
2776
2777@comment netdb.h
2778@comment BSD
2779@deftypefun void endnetgrent (void)
2780@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2781@c endnetgrent @mtasurace:netgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2782@c libc_lock_lock dup @asulock @aculock
2783@c internal_endnetgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2784@c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2785@c free_memory dup @ascuheap @acsmem
2786@c libc_lock_unlock dup @aculock
2787This function frees all buffers which were allocated to process the last
2788selected netgroup. As a result all string pointers returned by calls
2789to @code{getnetgrent} are invalid afterwards.
2790@end deftypefun
2791
2792@node Netgroup Membership
2793@subsection Testing for Netgroup Membership
2794
2795It is often not necessary to scan the whole netgroup since often the
2796only interesting question is whether a given entry is part of the
2797selected netgroup.
2798
2799@comment netdb.h
2800@comment BSD
2801@deftypefun int innetgr (const char *@var{netgroup}, const char *@var{host}, const char *@var{user}, const char *@var{domain})
2802@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2803@c This function does not use the static data structure that the
2804@c *netgrent* ones do, but since each nss must maintains internal state
2805@c to support iteration and concurrent iteration will interfere
2806@c destructively, we regard this internal state as a static buffer.
2807@c getnetgrent_r iteration in each nss backend.
2808@c innetgr @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2809@c nscd_innetgr @ascuheap @acsfd @acsmem
2810@c strlen dup ok
2811@c malloc dup @ascuheap @acsmem
2812@c stpcpy dup ok
2813@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem
2814@c nscd_cache_search dup ok
2815@c nscd_open_socket dup @acsfd
2816@c close_not_cancel_no_status dup @acsfd
2817@c nscd_drop_map_ref dup @ascuheap @acsmem
2818@c nscd_unmap dup @ascuheap @acsmem
2819@c free dup @ascuheap @acsmem
2820@c memset dup ok
2821@c (netgroup::)setup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2822@c *setfct.f @ascuplugin
2823@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2824@c *getfct @ascuplugin
2825@c strcmp dup ok
2826@c strlen dup ok
2827@c malloc dup @ascuheap @acsmem
2828@c memcpy dup ok
2829@c strcasecmp dup
2830@c *endfct @ascuplugin
2831@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2832@c free_memory dup @ascuheap @acsmem
2833This function tests whether the triple specified by the parameters
2834@var{hostp}, @var{userp}, and @var{domainp} is part of the netgroup
2835@var{netgroup}. Using this function has the advantage that
2836
2837@enumerate
2838@item
2839no other netgroup function can use the global netgroup state since
2840internal locking is used and
2841@item
2842the function is implemented more efficiently than successive calls
2843to the other @code{set}/@code{get}/@code{endnetgrent} functions.
2844@end enumerate
2845
2846Any of the pointers @var{hostp}, @var{userp}, and @var{domainp} can be
2847@code{NULL} which means any value is accepted in this position. This is
2848also true for the name @code{-} which should not match any other string
2849otherwise.
2850
2851The return value is @code{1} if an entry matching the given triple is
2852found in the netgroup. The return value is @code{0} if the netgroup
2853itself is not found, the netgroup does not contain the triple or
2854internal errors occurred.
2855@end deftypefun
2856
2857@c FIXME these are undocumented:
2858@c setresgid
2859@c setresuid