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