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
5 Every user who can log in on the system is identified by a unique number
6 called the @dfn{user ID}. Each process has an effective user ID which
7 says which user's access permissions it has.
9 Users are classified into @dfn{groups} for access control purposes. Each
10 process has one or more @dfn{group ID values} which say which groups the
11 process can use for access to files.
13 The effective user and group IDs of a process collectively form its
14 @dfn{persona}. This determines which files the process can access.
15 Normally, a process inherits its persona from the parent process, but
16 under special circumstances a process can change its persona and thus
17 change its access permissions.
19 Each file in the system also has a user ID and a group ID. Access
20 control works by comparing the user and group IDs of the file with those
21 of the running process.
23 The system keeps a database of all the registered users, and another
24 database of all the defined groups. There are library functions you
25 can use to examine these databases.
28 * User and Group IDs:: Each user has a unique numeric ID;
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.
36 * Setting User ID:: Functions for setting the user ID.
37 * Setting Groups:: Functions for setting the group IDs.
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.
43 * Who Logged In:: Getting the name of the user who logged in,
44 or of the real user ID of the current process.
46 * User Accounting Database:: Keeping information about users and various
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
55 * Netgroup Database:: Functions for accessing the netgroup database.
58 @node User and Group IDs
59 @section User and Group IDs
64 Each user account on a computer system is identified by a @dfn{user
65 name} (or @dfn{login name}) and @dfn{user ID}. Normally, each user name
66 has a unique user ID, but it is possible for several login names to have
67 the same user ID. The user names and corresponding user IDs are stored
68 in a data base which you can access as described in @ref{User Database}.
72 Users 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
75 share resources (such as files) that are not accessible to users who are
76 not 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
78 about a group ID or group name.
81 @section The Persona of a Process
83 @cindex effective user ID
84 @cindex effective group ID
85 @cindex supplementary group IDs
87 @c When Hurd is more widely used, explain multiple effective user IDs
89 At any time, each process has an @dfn{effective user ID}, a @dfn{effective
90 group ID}, and a set of @dfn{supplementary group IDs}. These IDs
91 determine the privileges of the process. They are collectively
92 called the @dfn{persona} of the process, because they determine ``who it
93 is'' for purposes of access control.
95 Your login shell starts out with a persona which consists of your user
96 ID, your default group ID, and your supplementary group IDs (if you are
97 in more than one group). In normal circumstances, all your other processes
101 @cindex real group ID
102 A process also has a @dfn{real user ID} which identifies the user who
103 created the process, and a @dfn{real group ID} which identifies that
104 user's default group. These values do not play a role in access
105 control, so we do not consider them part of the persona. But they are
108 Both the real and effective user ID can be changed during the lifetime
109 of a process. @xref{Why Change Persona}.
111 For details on how a process's effective user ID and group IDs affect
112 its permission to access files, see @ref{Access Permission}.
114 The effective user ID of a process also controls permissions for sending
115 signals using the @code{kill} function. @xref{Signaling Another
118 Finally, there are many operations which can only be performed by a
119 process whose effective user ID is zero. A process with this user ID is
120 a @dfn{privileged process}. Commonly the user name @code{root} is
121 associated with user ID 0, but there may be other user names with this
123 @c !!! should mention POSIX capabilities here.
125 @node Why Change Persona
126 @section Why Change the Persona of a Process?
128 The most obvious situation where it is necessary for a process to change
129 its 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
131 start a shell whose user and group IDs are those of the user who is
132 logging in. (To accomplish this fully, @code{login} must set the real
133 user and group IDs as well as its persona. But this is a special case.)
135 The more common case of changing persona is when an ordinary user
136 program needs access to a resource that wouldn't ordinarily be
137 accessible to the user actually running it.
139 For example, you may have a file that is controlled by your program but
140 that shouldn't be read or modified directly by other users, either
141 because it implements some kind of locking protocol, or because you want
142 to preserve the integrity or privacy of the information it contains.
143 This kind of restricted access can be implemented by having the program
144 change its effective user or group ID to match that of the resource.
146 Thus, imagine a game program that saves scores in a file. The game
147 program itself needs to be able to update this file no matter who is
148 running it, but if users can write the file without going through the
149 game, they can give themselves any scores they like. Some people
150 consider this undesirable, or even reprehensible. It can be prevented
151 by creating a new user ID and login name (say, @code{games}) to own the
152 scores file, and make the file writable only by this user. Then, when
153 the game program wants to update this file, it can change its effective
154 user ID to be that for @code{games}. In effect, the program must
155 adopt the persona of @code{games} so it can write to the scores file.
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}
164 The ability to change the persona of a process can be a source of
165 unintentional privacy violations, or even intentional abuse. Because of
166 the potential for problems, changing persona is restricted to special
169 You can't arbitrarily set your user ID or group ID to anything you want;
170 only privileged processes can do that. Instead, the normal way for a
171 program to change its persona is that it has been set up in advance to
172 change to a particular user or group. This is the function of the setuid
173 and setgid bits of a file's access mode. @xref{Permission Bits}.
175 When the setuid bit of an executable file is on, executing that file
176 gives the process a third user ID: the @dfn{file user ID}. This ID is
177 set to the owner ID of the file. The system then changes the effective
178 user ID to the file user ID. The real user ID remains as it was.
179 Likewise, if the setgid bit is on, the process is given a @dfn{file
180 group ID} equal to the group ID of the file, and its effective group ID
181 is changed to the file group ID.
183 If a process has a file ID (user or group), then it can at any time
184 change its effective ID to its real ID and back to its file ID.
185 Programs use this feature to relinquish their special privileges except
186 when they actually need them. This makes it less likely that they can
187 be tricked into doing something inappropriate with their privileges.
189 @strong{Portability Note:} Older systems do not have file IDs.
190 To determine if a system has this feature, you can test the compiler
191 define @code{_POSIX_SAVED_IDS}. (In the POSIX standard, file IDs are
194 @xref{File Attributes}, for a more general discussion of file modes and
197 @node Reading Persona
198 @section Reading the Persona of a Process
200 Here are detailed descriptions of the functions for reading the user and
201 group IDs of a process, both real and effective. To use these
202 facilities, you must include the header files @file{sys/types.h} and
207 @deftp {Data Type} uid_t
208 @standards{POSIX.1, sys/types.h}
209 This is an integer data type used to represent user IDs. In
210 @theglibc{}, this is an alias for @code{unsigned int}.
213 @deftp {Data Type} gid_t
214 @standards{POSIX.1, sys/types.h}
215 This is an integer data type used to represent group IDs. In
216 @theglibc{}, this is an alias for @code{unsigned int}.
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
224 The @code{getuid} function returns the real user ID of the process.
227 @deftypefun gid_t getgid (void)
228 @standards{POSIX.1, unistd.h}
229 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
230 The @code{getgid} function returns the real group ID of the process.
233 @deftypefun uid_t geteuid (void)
234 @standards{POSIX.1, unistd.h}
235 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
236 The @code{geteuid} function returns the effective user ID of the process.
239 @deftypefun gid_t getegid (void)
240 @standards{POSIX.1, unistd.h}
241 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
242 The @code{getegid} function returns the effective group ID of the process.
245 @deftypefun int getgroups (int @var{count}, gid_t *@var{groups})
246 @standards{POSIX.1, unistd.h}
247 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
248 The @code{getgroups} function is used to inquire about the supplementary
249 group IDs of the process. Up to @var{count} of these group IDs are
250 stored in the array @var{groups}; the return value from the function is
251 the number of group IDs actually stored. If @var{count} is smaller than
252 the total number of supplementary group IDs, then @code{getgroups}
253 returns a value of @code{-1} and @code{errno} is set to @code{EINVAL}.
255 If @var{count} is zero, then @code{getgroups} just returns the total
256 number of supplementary group IDs. On systems that do not support
257 supplementary groups, this will always be zero.
259 Here's how to use @code{getgroups} to read all the supplementary group
265 read_all_groups (void)
267 int ngroups = getgroups (0, NULL);
269 = (gid_t *) xmalloc (ngroups * sizeof (gid_t));
270 int val = getgroups (ngroups, groups);
282 @node Setting User ID
283 @section Setting the User ID
285 This section describes the functions for altering the user ID (real
286 and/or effective) of a process. To use these facilities, you must
287 include the header files @file{sys/types.h} and @file{unistd.h}.
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
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
316 @c lll_unlock @aculock
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.
321 This function sets the effective user ID of a process to @var{neweuid},
322 provided that the process is allowed to change its effective user ID. A
323 privileged process (effective user ID zero) can change its effective
324 user ID to any legal value. An unprivileged process with a file user ID
325 can change its effective user ID to its real user ID or to its file user
326 ID. Otherwise, a process may not change its effective user ID at all.
328 The @code{seteuid} function returns a value of @code{0} to indicate
329 successful completion, and a value of @code{-1} to indicate an error.
330 The following @code{errno} error conditions are defined for this
335 The value of the @var{neweuid} argument is invalid.
338 The process may not change to the specified ID.
341 Older systems (those without the @code{_POSIX_SAVED_IDS} feature) do not
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
350 If the calling process is privileged, this function sets both the real
351 and effective user IDs of the process to @var{newuid}. It also deletes
352 the file user ID of the process, if any. @var{newuid} may be any
353 legal value. (Once this has been done, there is no way to recover the
354 old effective user ID.)
356 If the process is not privileged, and the system supports the
357 @code{_POSIX_SAVED_IDS} feature, then this function behaves like
360 The return values and error conditions are the same as for @code{seteuid}.
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
368 This function sets the real user ID of the process to @var{ruid} and the
369 effective user ID to @var{euid}. If @var{ruid} is @code{-1}, it means
370 not to change the real user ID; likewise if @var{euid} is @code{-1}, it
371 means not to change the effective user ID.
373 The @code{setreuid} function exists for compatibility with 4.3 BSD Unix,
374 which does not support file IDs. You can use this function to swap the
375 effective and real user IDs of the process. (Privileged processes are
376 not limited to this particular usage.) If file IDs are supported, you
377 should use that feature instead of this function. @xref{Enable/Disable
380 The return value is @code{0} on success and @code{-1} on failure.
381 The following @code{errno} error conditions are defined for this
386 The process does not have the appropriate privileges; you do not
387 have permission to change to the specified ID.
392 @section Setting the Group IDs
394 This section describes the functions for altering the group IDs (real
395 and effective) of a process. To use these facilities, you must include
396 the header files @file{sys/types.h} and @file{unistd.h}.
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
405 This function sets the effective group ID of the process to
406 @var{newgid}, provided that the process is allowed to change its group
407 ID. Just as with @code{seteuid}, if the process is privileged it may
408 change its effective group ID to any value; if it isn't, but it has a
409 file group ID, then it may change to its real group ID or file group ID;
410 otherwise it may not change its effective group ID.
412 Note that a process is only privileged if its effective @emph{user} ID
413 is zero. The effective group ID only affects access permissions.
415 The return values and error conditions for @code{setegid} are the same
416 as those for @code{seteuid}.
418 This function is only present if @code{_POSIX_SAVED_IDS} is defined.
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
426 This function sets both the real and effective group ID of the process
427 to @var{newgid}, provided that the process is privileged. It also
428 deletes the file group ID, if any.
430 If the process is not privileged, then @code{setgid} behaves like
433 The return values and error conditions for @code{setgid} are the same
434 as those for @code{seteuid}.
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
442 This function sets the real group ID of the process to @var{rgid} and
443 the effective group ID to @var{egid}. If @var{rgid} is @code{-1}, it
444 means not to change the real group ID; likewise if @var{egid} is
445 @code{-1}, it means not to change the effective group ID.
447 The @code{setregid} function is provided for compatibility with 4.3 BSD
448 Unix, which does not support file IDs. You can use this function to
449 swap the effective and real group IDs of the process. (Privileged
450 processes are not limited to this usage.) If file IDs are supported,
451 you should use that feature instead of using this function.
452 @xref{Enable/Disable Setuid}.
454 The return values and error conditions for @code{setregid} are the same
455 as those for @code{setreuid}.
458 @code{setuid} and @code{setgid} behave differently depending on whether
459 the effective user ID at the time is zero. If it is not zero, they
460 behave like @code{seteuid} and @code{setegid}. If it is, they change
461 both effective and real IDs and delete the file ID. To avoid confusion,
462 we recommend you always use @code{seteuid} and @code{setegid} except
463 when you know the effective user ID is zero and your intent is to change
464 the persona permanently. This case is rare---most of the programs that
465 need it, such as @code{login} and @code{su}, have already been written.
467 Note that if your program is setuid to some user other than @code{root},
468 there is no way to drop privileges permanently.
470 The system also lets privileged processes change their supplementary
471 group IDs. To use @code{setgroups} or @code{initgroups}, your programs
472 should include the header file @file{grp.h}.
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
480 This function sets the process's supplementary group IDs. It can only
481 be called from privileged processes. The @var{count} argument specifies
482 the number of group IDs in the array @var{groups}.
484 This function returns @code{0} if successful and @code{-1} on error.
485 The following @code{errno} error conditions are defined for this
490 The calling process is not privileged.
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
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
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
526 The @code{initgroups} function sets the process's supplementary group
527 IDs to be the normal default for the user name @var{user}. The group
528 @var{group} is automatically included.
530 This 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
534 The return values and error conditions are the same as for
538 If you are interested in the groups a particular user belongs to, but do
539 not want to change the process's supplementary group IDs, you can use
540 @code{getgrouplist}. To use @code{getgrouplist}, your programs should
541 include the header file @file{grp.h}.
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
549 @c malloc dup @ascuheap @acsmem
550 @c internal_getgrouplist dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
552 @c free dup @ascuheap @acsmem
553 The @code{getgrouplist} function scans the group database for all the
554 groups @var{user} belongs to. Up to *@var{ngroups} group IDs
555 corresponding to these groups are stored in the array @var{groups}; the
556 return value from the function is the number of group IDs actually
557 stored. If *@var{ngroups} is smaller than the total number of groups
558 found, then @code{getgrouplist} returns a value of @code{-1} and stores
559 the actual number of groups in *@var{ngroups}. The group @var{group} is
560 automatically included in the list of groups returned by
563 Here's how to use @code{getgrouplist} to read all supplementary groups
569 supplementary_groups (char *user)
573 = (gid_t *) xmalloc (ngroups * sizeof (gid_t));
574 struct passwd *pw = getpwnam (user);
579 if (getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups) < 0)
581 groups = xrealloc (ngroups * sizeof (gid_t));
582 getgrouplist (pw->pw_name, pw->pw_gid, groups, &ngroups);
590 @node Enable/Disable Setuid
591 @section Enabling and Disabling Setuid Access
593 A typical setuid program does not need its special access all of the
594 time. It's a good idea to turn off this access when it isn't needed,
595 so it can't possibly give unintended access.
597 If the system supports the @code{_POSIX_SAVED_IDS} feature, you can
598 accomplish this with @code{seteuid}. When the game program starts, its
599 real user ID is @code{jdoe}, its effective user ID is @code{games}, and
600 its saved user ID is also @code{games}. The program should record both
601 user ID values once at the beginning, like this:
604 user_user_id = getuid ();
605 game_user_id = geteuid ();
608 Then it can turn off game file access with
611 seteuid (user_user_id);
618 seteuid (game_user_id);
622 Throughout this process, the real user ID remains @code{jdoe} and the
623 file user ID remains @code{games}, so the program can always set its
624 effective user ID to either one.
626 On other systems that don't support file user IDs, you can
627 turn setuid access on and off by using @code{setreuid} to swap the real
628 and effective user IDs of the process, as follows:
631 setreuid (geteuid (), getuid ());
635 This special case is always allowed---it cannot fail.
637 Why does this have the effect of toggling the setuid access? Suppose a
638 game program has just started, and its real user ID is @code{jdoe} while
639 its effective user ID is @code{games}. In this state, the game can
640 write 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
642 only @code{jdoe} access. Another swap brings @code{games} back to
643 the effective user ID and restores access to the scores file.
645 In order to handle both kinds of systems, test for the saved user ID
646 feature with a preprocessor conditional, like this:
649 #ifdef _POSIX_SAVED_IDS
650 seteuid (user_user_id);
652 setreuid (geteuid (), getuid ());
656 @node Setuid Program Example
657 @section Setuid Program Example
659 Here's an example showing how to set up a program that changes its
662 This is part of a game program called @code{caber-toss} that manipulates
663 a file @file{scores} that should be writable only by the game program
664 itself. The program assumes that its executable file will be installed
665 with the setuid bit set and owned by the same user as the @file{scores}
666 file. Typically, a system administrator will set up an account like
667 @code{games} for this purpose.
669 The executable file is given mode @code{4755}, so that doing an
670 @samp{ls -l} on it produces output like:
673 -rwsr-xr-x 1 games 184422 Jul 30 15:17 caber-toss
677 The setuid bit shows up in the file modes as the @samp{s}.
679 The scores file is given mode @code{644}, and doing an @samp{ls -l} on
683 -rw-r--r-- 1 games 0 Jul 31 15:33 scores
686 Here are the parts of the program that show how to set up the changed
687 user ID. This program is conditionalized so that it makes use of the
688 file IDs feature if it is supported, and otherwise uses @code{setreuid}
689 to swap the effective and real user IDs.
693 #include <sys/types.h>
698 /* @r{Remember the effective and real UIDs.} */
700 static uid_t euid, ruid;
703 /* @r{Restore the effective UID to its original value.} */
710 #ifdef _POSIX_SAVED_IDS
711 status = seteuid (euid);
713 status = setreuid (ruid, euid);
716 fprintf (stderr, "Couldn't set uid.\n");
723 /* @r{Set the effective UID to the real UID.} */
730 #ifdef _POSIX_SAVED_IDS
731 status = seteuid (ruid);
733 status = setreuid (euid, ruid);
736 fprintf (stderr, "Couldn't set uid.\n");
742 /* @r{Main program.} */
747 /* @r{Remember the real and effective user IDs.} */
752 /* @r{Do the game and record the score.} */
757 Notice how the first thing the @code{main} function does is to set the
758 effective user ID back to the real user ID. This is so that any other
759 file accesses that are performed while the user is playing the game use
760 the real user ID for determining permissions. Only when the program
761 needs to open the scores file does it switch back to the file user ID,
765 /* @r{Record the score.} */
768 record_score (int score)
773 /* @r{Open the scores file.} */
775 stream = fopen (SCORES_FILE, "a");
779 /* @r{Write the score to the file.} */
782 myname = cuserid (NULL);
784 fprintf (stream, "%10s: Couldn't lift the caber.\n", myname);
786 fprintf (stream, "%10s: %d feet.\n", myname, score);
796 @node Tips for Setuid
797 @section Tips for Writing Setuid Programs
799 It is easy for setuid programs to give the user access that isn't
800 intended---in fact, if you want to avoid this, you need to be careful.
801 Here are some guidelines for preventing unintended access and
802 minimizing its consequences when it does occur:
806 Don't have @code{setuid} programs with privileged user IDs such as
807 @code{root} unless it is absolutely necessary. If the resource is
808 specific to your particular program, it's better to define a new,
809 nonprivileged user ID or group ID just to manage that resource.
810 It's better if you can write your program to use a special group than a
814 Be cautious about using the @code{exec} functions in combination with
815 changing the effective user ID. Don't let users of your program execute
816 arbitrary programs under a changed user ID. Executing a shell is
817 especially bad news. Less obviously, the @code{execlp} and @code{execvp}
818 functions are a potential risk (since the program they execute depends
819 on the user's @code{PATH} environment variable).
821 If you must @code{exec} another program under a changed ID, specify an
822 absolute file name (@pxref{File Name Resolution}) for the executable,
823 and make sure that the protections on that executable and @emph{all}
824 containing directories are such that ordinary users cannot replace it
825 with some other program.
827 You should also check the arguments passed to the program to make sure
828 they do not have unexpected effects. Likewise, you should examine the
829 environment variables. Decide which arguments and variables are safe,
830 and reject all others.
832 You should never use @code{system} in a privileged program, because it
836 Only use the user ID controlling the resource in the part of the program
837 that actually uses that resource. When you're finished with it, restore
838 the effective user ID back to the actual user's user ID.
839 @xref{Enable/Disable Setuid}.
842 If the @code{setuid} part of your program needs to access other files
843 besides the controlled resource, it should verify that the real user
844 would ordinarily have permission to access those files. You can use the
845 @code{access} function (@pxref{Access Permission}) to check this; it
846 uses the real user and group IDs, rather than the effective IDs.
850 @section Identifying Who Logged In
851 @cindex login name, determining
852 @cindex user ID, determining
854 You can use the functions listed in this section to determine the login
855 name of the user who is running a process, and the name of the user who
856 logged in the current session. See also the function @code{getuid} and
857 friends (@pxref{Reading Persona}). How this information is collected by
858 the system and how to control/add/remove information from the background
859 storage is described in @ref{User Accounting Database}.
861 The @code{getlogin} function is declared in @file{unistd.h}, while
862 @code{cuserid} and @code{L_cuserid} are declared in @file{stdio.h}.
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
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
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
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
896 @c libc_lock_lock dup @asulock @aculock
897 @c *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd
898 @c *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer
899 @c *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock
900 @c libc_lock_unlock dup ok
903 The @code{getlogin} function returns a pointer to a string containing the
904 name of the user logged in on the controlling terminal of the process,
905 or a null pointer if this information cannot be determined. The string
906 is statically allocated and might be overwritten on subsequent calls to
907 this function or to @code{cuserid}.
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
916 @c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
918 The @code{cuserid} function returns a pointer to a string containing a
919 user 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
921 at least @code{L_cuserid} characters; the string is returned in this
922 array. Otherwise, a pointer to a string in a static area is returned.
923 This string is statically allocated and might be overwritten on
924 subsequent calls to this function or to @code{getlogin}.
926 The use of this function is deprecated since it is marked to be
927 withdrawn in XPG4.2 and has already been removed from newer revisions of
931 @deftypevr Macro int L_cuserid
932 @standards{POSIX.1, stdio.h}
933 An integer constant that indicates how long an array you might need to
937 These functions let your program identify positively the user who is
938 running or the user who logged in this session. (These can differ when
939 setuid programs are involved; see @ref{Process Persona}.) The user cannot
940 do anything to fool these functions.
942 For 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
944 precisely because the user can set @code{LOGNAME} arbitrarily.
945 @xref{Standard Environment}.
948 @node User Accounting Database
949 @section The User Accounting Database
950 @cindex user accounting database
952 Most Unix-like operating systems keep track of logged in users by
953 maintaining a user accounting database. This user accounting database
954 stores for each terminal, who has logged on, at what time, the process
955 ID of the user's login shell, etc., etc., but also stores information
956 about the run level of the system, the time of the last system reboot,
959 The user accounting database typically lives in @file{/etc/utmp},
960 @file{/var/adm/utmp} or @file{/var/run/utmp}. However, these files
961 should @strong{never} be accessed directly. For reading information
962 from and writing information to the user accounting database, the
963 functions described in this section should be used.
967 * Manipulating the Database:: Scanning and modifying the user
969 * XPG Functions:: A standardized way for doing the same thing.
970 * Logging In and Out:: Functions from BSD that modify the user
974 @node Manipulating the Database
975 @subsection Manipulating the User Accounting Database
977 These functions and the corresponding data structures are declared in
978 the header file @file{utmp.h}.
981 @deftp {Data Type} {struct exit_status}
982 @standards{SVID, utmp.h}
983 The @code{exit_status} data structure is used to hold information about
984 the exit status of processes marked as @code{DEAD_PROCESS} in the user
988 @item short int e_termination
989 The exit status of the process.
991 @item short int e_exit
992 The exit status of the process.
996 @deftp {Data Type} {struct utmp}
997 The @code{utmp} data structure is used to hold information about entries
998 in the user accounting database. On @gnusystems{} it has the following
1002 @item short int ut_type
1003 Specifies 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
1009 The process ID number of the login process.
1011 @item char ut_line[]
1012 The device name of the tty (without @file{/dev/}).
1015 The inittab ID of the process.
1017 @item char ut_user[]
1018 The user's login name.
1020 @item char ut_host[]
1021 The name of the host from which the user logged in.
1023 @item struct exit_status ut_exit
1024 The exit status of a process marked as @code{DEAD_PROCESS}.
1026 @item long ut_session
1027 The Session ID, used for windowing.
1029 @item struct timeval ut_tv
1030 Time the entry was made. For entries of type @code{OLD_TIME} this is
1031 the 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.
1034 @item int32_t ut_addr_v6[4]
1035 The Internet address of a remote host.
1039 The @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
1041 applications therefore should be prepared for these situations. To help
1042 do 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
1045 available. The programmer can handle the situations by using
1046 @code{#ifdef} in the program code.
1048 The following macros are defined for use as values for the
1049 @code{ut_type} member of the @code{utmp} structure. The values are
1054 @standards{SVID, utmp.h}
1055 This macro is used to indicate that the entry contains no valid user
1056 accounting information.
1059 @standards{SVID, utmp.h}
1060 This macro is used to identify the system's runlevel.
1063 @standards{SVID, utmp.h}
1064 This macro is used to identify the time of system boot.
1067 @standards{SVID, utmp.h}
1068 This macro is used to identify the time when the system clock changed.
1071 @standards{SVID, utmp.h}
1072 This macro is used to identify the time after the system clock changed.
1075 @standards{SVID, utmp.h}
1076 This macro is used to identify a process spawned by the init process.
1079 @standards{SVID, utmp.h}
1080 This macro is used to identify the session leader of a logged in user.
1083 @standards{SVID, utmp.h}
1084 This macro is used to identify a user process.
1087 @standards{SVID, utmp.h}
1088 This macro is used to identify a terminated process.
1091 @standards{SVID, utmp.h}
1095 The 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.
1098 Many older systems have, instead of an @code{ut_tv} member, an
1099 @code{ut_time} member, usually of type @code{time_t}, for representing
1100 the time associated with the entry. Therefore, for backwards
1101 compatibility only, @file{utmp.h} defines @code{ut_time} as an alias for
1102 @code{ut_tv.tv_sec}.
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.
1112 @c setutent @mtasurace:utent @asulock @aculock @acsfd
1113 @c libc_lock_lock dup @asulock @aculock
1114 @c *libc_utmp_jump_table->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
1121 @c libc_lock_unlock dup ok
1122 This function opens the user accounting database to begin scanning it.
1123 You can then call @code{getutent}, @code{getutid} or @code{getutline} to
1124 read entries and @code{pututline} to write entries.
1126 If the database is already open, it resets the input to the beginning of
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.
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
1140 The @code{getutent} function reads the next entry from the user
1141 accounting database. It returns a pointer to the entry, which is
1142 statically allocated and may be overwritten by subsequent calls to
1143 @code{getutent}. You must copy the contents of the structure if you
1144 wish to save the information or you can use the @code{getutent_r}
1145 function which stores the data in a user-provided buffer.
1147 A null pointer is returned in case no further entry is available.
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_utmp_jump_table->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
1160 This function closes the user accounting database.
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.
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
1172 This function searches forward from the current point in the database
1173 for 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
1177 the @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
1180 these 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
1182 from the database is empty it checks if the @code{ut_line} members match
1183 instead. If a matching entry is found, @code{getutid} returns a pointer
1184 to the entry, which is statically allocated, and may be overwritten by a
1185 subsequent call to @code{getutent}, @code{getutid} or @code{getutline}.
1186 You must copy the contents of the structure if you wish to save the
1189 A null pointer is returned in case the end of the database is reached
1192 The @code{getutid} function may cache the last read entry. Therefore,
1193 if you are using @code{getutid} to search for multiple occurrences, it
1194 is 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
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.
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
1209 This function searches forward from the current point in the database
1210 until it finds an entry whose @code{ut_type} value is
1211 @code{LOGIN_PROCESS} or @code{USER_PROCESS}, and whose @code{ut_line}
1212 member matches the @code{ut_line} member of the @var{line} structure.
1213 If it finds such an entry, it returns a pointer to the entry which is
1214 statically allocated, and may be overwritten by a subsequent call to
1215 @code{getutent}, @code{getutid} or @code{getutline}. You must copy the
1216 contents of the structure if you wish to save the information.
1218 A null pointer is returned in case the end of the database is reached
1221 The @code{getutline} function may cache the last read entry. Therefore
1222 if you are using @code{getutline} to search for multiple occurrences, it
1223 is 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
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_utmp_jump_table->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
1240 @c open_not_cancel_2 dup @acsfd
1241 @c fcntl_not_cancel dup ok
1242 @c close_not_cancel_no_status dup @acsfd
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
1253 The @code{pututline} function inserts the entry @code{*@var{utmp}} at
1254 the appropriate place in the user accounting database. If it finds that
1255 it 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
1257 this will not modify the static structure returned by @code{getutent},
1258 @code{getutid} and @code{getutline}. If this search fails, the entry
1259 is appended to the database.
1261 The @code{pututline} function returns a pointer to a copy of the entry
1262 inserted in the user accounting database, or a null pointer if the entry
1263 could not be added. The following @code{errno} error conditions are
1264 defined for this function:
1268 The process does not have the appropriate privileges; you cannot modify
1269 the user accounting database.
1273 All the @code{get*} functions mentioned before store the information
1274 they return in a static buffer. This can be a problem in multi-threaded
1275 programs since the data returned for the request is overwritten by the
1276 return value data in another thread. Therefore @theglibc{}
1277 provides as extensions three more functions which return the data in a
1278 user-provided buffer.
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_utmp_jump_table->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
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
1302 @c libc_lock_unlock dup ok
1303 The @code{getutent_r} is equivalent to the @code{getutent} function. It
1304 returns the next entry from the database. But instead of storing the
1305 information in a static buffer it stores it in the buffer pointed to by
1306 the parameter @var{buffer}.
1308 If the call was successful, the function returns @code{0} and the
1309 pointer variable pointed to by the parameter @var{result} contains a
1310 pointer to the buffer which contains the result (this is most probably
1311 the same value as @var{buffer}). If something went wrong during the
1312 execution of @code{getutent_r} the function returns @code{-1}.
1314 This function is a GNU extension.
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_utmp_jump_table->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
1332 @c UNLOCK_FILE dup @mtascutimer
1334 @c libc_lock_unlock dup @aculock
1335 This function retrieves just like @code{getutid} the next entry matching
1336 the information stored in @var{id}. But the result is stored in the
1337 buffer pointed to by the parameter @var{buffer}.
1339 If successful the function returns @code{0} and the pointer variable
1340 pointed to by the parameter @var{result} contains a pointer to the
1341 buffer with the result (probably the same as @var{result}. If not
1342 successful the function return @code{-1}.
1344 This function is a GNU extension.
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_utmp_jump_table->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
1361 @c fcntl_not_cancel dup ok
1362 @c LOCKING_FAILED ok
1363 @c read_not_cancel dup ok
1365 @c UNLOCK_FILE @mtascutimer
1366 @c fcntl_not_cancel dup ok
1367 @c alarm dup @mtascutimer
1370 @c libc_lock_unlock dup ok
1371 This function retrieves just like @code{getutline} the next entry
1372 matching the information stored in @var{line}. But the result is stored
1373 in the buffer pointed to by the parameter @var{buffer}.
1375 If successful the function returns @code{0} and the pointer variable
1376 pointed to by the parameter @var{result} contains a pointer to the
1377 buffer with the result (probably the same as @var{result}. If not
1378 successful the function return @code{-1}.
1380 This function is a GNU extension.
1384 In addition to the user accounting database, most systems keep a number
1385 of similar databases. For example most systems keep a log file with all
1386 previous logins (usually in @file{/etc/wtmp} or @file{/var/log/wtmp}).
1388 For specifying which database to examine, the following function should
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_utmp_jump_table->endutent dup @mtasurace:utent
1398 @c free dup @ascuheap @acsmem
1399 @c strdup dup @ascuheap @acsmem
1400 @c libc_lock_unlock dup @aculock
1401 The @code{utmpname} function changes the name of the database to be
1402 examined to @var{file}, and closes any previously opened database. By
1403 default @code{getutent}, @code{getutid}, @code{getutline} and
1404 @code{pututline} read from and write to the user accounting database.
1406 The following macros are defined for use as the @var{file} argument:
1408 @deftypevr Macro {char *} _PATH_UTMP
1409 This macro is used to specify the user accounting database.
1412 @deftypevr Macro {char *} _PATH_WTMP
1413 This macro is used to specify the user accounting log file.
1416 The @code{utmpname} function returns a value of @code{0} if the new name
1417 was successfully stored, and a value of @code{-1} to indicate an error.
1418 Note that @code{utmpname} does not try to open the database, and that
1419 therefore the return value does not say anything about whether the
1420 database can be successfully opened.
1423 Specially for maintaining log-like databases @theglibc{} provides
1424 the following function:
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
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
1440 The @code{updwtmp} function appends the entry *@var{utmp} to the
1441 database specified by @var{wtmp_file}. For possible values for the
1442 @var{wtmp_file} argument see the @code{utmpname} function.
1445 @strong{Portability Note:} Although many operating systems provide a
1446 subset of these functions, they are not standardized. There are often
1447 subtle differences in the return types, and there are considerable
1448 differences between the various definitions of @code{struct utmp}. When
1449 programming for @theglibc{}, it is probably best to stick
1450 with the functions described in this section. If however, you want your
1451 program 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}.
1457 @subsection XPG User Accounting Database Functions
1459 These functions, described in the X/Open Portability Guide, are declared
1460 in the header file @file{utmpx.h}.
1463 @deftp {Data Type} {struct utmpx}
1464 The @code{utmpx} data structure contains at least the following members:
1467 @item short int ut_type
1468 Specifies 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}.
1473 The process ID number of the login process.
1475 @item char ut_line[]
1476 The device name of the tty (without @file{/dev/}).
1479 The inittab ID of the process.
1481 @item char ut_user[]
1482 The user's login name.
1484 @item struct timeval ut_tv
1485 Time the entry was made. For entries of type @code{OLD_TIME} this is
1486 the 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.
1489 In @theglibc{}, @code{struct utmpx} is identical to @code{struct
1490 utmp} except for the fact that including @file{utmpx.h} does not make
1491 visible the declaration of @code{struct exit_status}.
1494 The following macros are defined for use as values for the
1495 @code{ut_type} member of the @code{utmpx} structure. The values are
1496 integer constants and are, in @theglibc{}, identical to the
1497 definitions in @file{utmp.h}.
1501 @standards{XPG4.2, utmpx.h}
1502 This macro is used to indicate that the entry contains no valid user
1503 accounting information.
1506 @standards{XPG4.2, utmpx.h}
1507 This macro is used to identify the system's runlevel.
1510 @standards{XPG4.2, utmpx.h}
1511 This macro is used to identify the time of system boot.
1514 @standards{XPG4.2, utmpx.h}
1515 This macro is used to identify the time when the system clock changed.
1518 @standards{XPG4.2, utmpx.h}
1519 This macro is used to identify the time after the system clock changed.
1522 @standards{XPG4.2, utmpx.h}
1523 This macro is used to identify a process spawned by the init process.
1526 @standards{XPG4.2, utmpx.h}
1527 This macro is used to identify the session leader of a logged in user.
1530 @standards{XPG4.2, utmpx.h}
1531 This macro is used to identify a user process.
1534 @standards{XPG4.2, utmpx.h}
1535 This macro is used to identify a terminated process.
1538 The size of the @code{ut_line}, @code{ut_id} and @code{ut_user} arrays
1539 can be found using the @code{sizeof} operator.
1541 @deftypefun void setutxent (void)
1542 @standards{XPG4.2, utmpx.h}
1543 @safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}}
1544 This function is similar to @code{setutent}. In @theglibc{} it is
1545 simply an alias for @code{setutent}.
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{}}}
1551 The @code{getutxent} function is similar to @code{getutent}, but returns
1552 a pointer to a @code{struct utmpx} instead of @code{struct utmp}. In
1553 @theglibc{} it simply is an alias for @code{getutent}.
1556 @deftypefun void endutxent (void)
1557 @standards{XPG4.2, utmpx.h}
1558 @safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
1559 This function is similar to @code{endutent}. In @theglibc{} it is
1560 simply an alias for @code{endutent}.
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{}}}
1566 This function is similar to @code{getutid}, but uses @code{struct utmpx}
1567 instead of @code{struct utmp}. In @theglibc{} it is simply an alias
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{}}}
1574 This function is similar to @code{getutid}, but uses @code{struct utmpx}
1575 instead of @code{struct utmp}. In @theglibc{} it is simply an alias
1576 for @code{getutline}.
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{}}}
1582 The @code{pututxline} function is functionally identical to
1583 @code{pututline}, but uses @code{struct utmpx} instead of @code{struct
1584 utmp}. In @theglibc{}, @code{pututxline} is simply an alias for
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{}}}
1591 The @code{utmpxname} function is functionally identical to
1592 @code{utmpname}. In @theglibc{}, @code{utmpxname} is simply an
1593 alias for @code{utmpname}.
1596 You can translate between a traditional @code{struct utmp} and an XPG
1597 @code{struct utmpx} with the following functions. In @theglibc{},
1598 these functions are merely copies, since the two structures are
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
1606 compatible, from @var{utmpx} to @var{utmp}.
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
1614 compatible, from @var{utmp} to @var{utmpx}.
1618 @node Logging In and Out
1619 @subsection Logging In and Out
1621 These functions, derived from BSD, are available in the separate
1622 @file{libutil} library, and declared in @file{utmp.h}.
1625 Note 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
1627 for @code{ut_user} in @file{utmp.h}.
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
1638 @c ttyname dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd
1642 This function makes @var{filedes} the controlling terminal of the
1643 current process, redirects standard input, standard output and
1644 standard error output to this terminal, and closes @var{filedes}.
1646 This function returns @code{0} on successful completion, and @code{-1}
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
1655 @c tty_name @ascuheap @acucorrupt @acsmem @acsfd
1656 @c ttyname_r dup @ascuheap @acsmem @acsfd
1658 @c realloc dup @ascuheap @acsmem
1659 @c malloc dup @ascuheap @acsmem
1660 @c free dup @ascuheap @acsmem
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
1670 The @code{login} functions inserts an entry into the user accounting
1671 database. The @code{ut_line} member is set to the name of the terminal
1672 on standard input. If standard input is not a terminal @code{login}
1673 uses standard output or standard error output to determine the name of
1674 the 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
1677 process. The remaining entries are copied from @var{entry}.
1679 A copy of the entry is written to the user accounting log file.
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
1689 @c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1691 @c gettimeofday dup ok
1693 @c pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd
1694 @c endutent dup @mtasurace:utent @asulock @aculock
1695 This function modifies the user accounting database to indicate that the
1696 user on @var{ut_line} has logged out.
1698 The @code{logout} function returns @code{1} if the entry was successfully
1699 written to the database, or @code{0} on error.
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
1709 @c gettimeofday dup ok
1711 @c updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd
1712 The @code{logwtmp} function appends an entry to the user accounting log
1713 file, for the current time and the information provided in the
1714 @var{ut_line}, @var{ut_name} and @var{ut_host} arguments.
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}
1719 members. Older systems do not even have the @code{ut_host} member.
1723 @section User Database
1724 @cindex user database
1725 @cindex password database
1728 This section describes how to search and scan the database of registered
1729 users. The database itself is kept in the file @file{/etc/passwd} on
1730 most systems, but on some systems a special network server gives access
1734 * User Data Structure:: What each user record contains.
1735 * Lookup User:: How to look for a particular user.
1736 * Scanning All Users:: Scanning the list of all users, one by one.
1737 * Writing a User Entry:: How a program can rewrite a user's record.
1740 @node User Data Structure
1741 @subsection The Data Structure that Describes a User
1743 The functions and data structures for accessing the system user database
1744 are declared in the header file @file{pwd.h}.
1747 @deftp {Data Type} {struct passwd}
1748 @standards{POSIX.1, pwd.h}
1749 The @code{passwd} data structure is used to hold information about
1750 entries in the system user data base. It has at least the following members:
1754 The user's login name.
1756 @item char *pw_passwd.
1757 The encrypted password string.
1763 The user's default group ID number.
1765 @item char *pw_gecos
1766 A string typically containing the user's real name, and possibly other
1767 information such as a phone number.
1770 The user's home directory, or initial working directory. This might be
1771 a null pointer, in which case the interpretation is system-dependent.
1773 @item char *pw_shell
1774 The user's default shell, or the initial program run when the user logs in.
1775 This might be a null pointer, indicating that the system default should
1781 @subsection Looking Up One User
1782 @cindex converting user ID to user name
1783 @cindex converting user name to user ID
1785 You can search the system user database for information about a
1786 specific user using @code{getpwuid} or @code{getpwnam}. These
1787 functions are declared in @file{pwd.h}.
1789 @deftypefun {struct passwd *} getpwuid (uid_t @var{uid})
1790 @standards{POSIX.1, pwd.h}
1791 @safety{@prelim{}@mtunsafe{@mtasurace{:pwuid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
1792 @c getpwuid @mtasurace:pwuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1793 @c libc_lock_lock dup @asulock @aculock
1794 @c malloc dup @ascuheap @acsmem
1795 @c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1796 @c realloc dup @ascuheap @acsmem
1797 @c free dup @ascuheap @acsmem
1798 @c libc_lock_unlock dup @aculock
1799 This function returns a pointer to a statically-allocated structure
1800 containing information about the user whose user ID is @var{uid}. This
1801 structure may be overwritten on subsequent calls to @code{getpwuid}.
1803 A null pointer value indicates there is no user in the data base with
1807 @deftypefun int getpwuid_r (uid_t @var{uid}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
1808 @standards{POSIX.1c, pwd.h}
1809 @safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
1810 @c getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1811 @c nscd_getpwuid_r @ascuheap @acsfd @acsmem
1813 @c nscd_getpw_r @ascuheap @acsfd @acsmem
1814 @c nscd_get_map_ref @ascuheap @acsfd @acsmem
1815 @c nscd_acquire_maplock ok
1816 @c nscd_get_mapping @ascuheap @acsfd @acsmem
1817 @c open_socket dup @acsfd
1819 @c wait_on_socket dup ok
1824 @c munmap dup @acsmem
1825 @c malloc dup @ascuheap @acsmem
1827 @c nscd_unmap dup @ascuheap @acsmem
1828 @c nscd_cache_search ok
1831 @c nscd_open_socket @acsfd
1832 @c open_socket @acsfd
1833 @c socket dup @acsfd
1838 @c gettimeofday dup ok
1840 @c close_not_cancel_no_status dup @acsfd
1841 @c wait_on_socket dup ok
1843 @c close_not_cancel_no_status dup @acsfd
1846 @c wait_on_socket ok
1848 @c gettimeofday dup ok
1850 @c close_not_cancel_no_status dup @acsfd
1851 @c nscd_drop_map_ref @ascuheap @acsmem
1852 @c nscd_unmap dup @ascuheap @acsmem
1853 @c nscd_unmap @ascuheap @acsmem
1855 @c free dup @ascuheap @acsmem
1856 @c nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1857 @c nss_database_lookup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
1858 @c libc_lock_lock @asulock @aculock
1859 @c libc_lock_unlock @aculock
1860 @c nss_parse_file @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
1861 @c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
1862 @c fsetlocking dup ok [no concurrent uses]
1863 @c malloc dup @asulock @aculock @acsfd @acsmem
1864 @c fclose dup @ascuheap @asulock @acsmem @acsfd @aculock
1865 @c getline dup @ascuheap @aculock @acucorrupt @acsmem
1867 @c nss_getline @mtslocale @ascuheap @acsmem
1868 @c isspace @mtslocale^^
1870 @c malloc dup @asulock @aculock @acsfd @acsmem
1872 @c nss_parse_service_list dup @mtslocale^, @ascuheap @acsmem
1873 @c feof_unlocked dup ok
1874 @c free dup @asulock @aculock @acsfd @acsmem
1876 @c nss_parse_service_list @mtslocale^, @ascuheap @acsmem
1877 @c isspace @mtslocale^^
1878 @c malloc dup @asulock @aculock @acsfd @acsmem
1880 @c strncasecmp dup ok
1881 @c free dup @asulock @aculock @acsfd @acsmem
1882 @c malloc dup @asulock @aculock @acsfd @acsmem
1883 @c nss_lookup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1884 @c nss_lookup_function @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1885 @c libc_lock_lock @asulock @aculock
1886 @c tsearch @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
1889 @c malloc dup @ascuheap @acsmem
1890 @c tdelete @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking]
1891 @c free dup @ascuheap @acsmem
1892 @c nss_load_library @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem
1893 @c nss_new_service @ascuheap @acsmem
1895 @c malloc dup @ascuheap @acsmem
1898 @c libc_dlopen @ascudlopen @ascuheap @asulock @aculock @acsfd @acsmem
1899 @c libc_dlsym dup @asulock @aculock @acsfd @acsmem
1900 @c *ifct(*nscd_init_cb) @ascuplugin
1902 @c libc_dlsym dup @asulock @aculock @acsfd @acsmem
1903 @c libc_lock_unlock dup ok
1904 @c nss_next_action ok
1905 @c *fct.l -> _nss_*_getpwuid_r @ascuplugin
1906 @c nss_next2 @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1907 @c nss_next_action dup ok
1908 @c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
1910 @c _nss_files_getpwuid_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
1911 @c libc_lock_lock dup @asulock @aculock
1912 @c internal_setent @ascuheap @asulock @aculock @acsmem @acsfd
1913 @c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
1916 @c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
1917 @c rewind dup @aculock [stream guarded by non-recursive pwent lock]
1918 @c internal_getent @mtslocale^
1919 @c fgets_unlocked dup ok [stream guarded by non-recursive pwent lock]
1920 @c isspace dup @mtslocale^^
1921 @c _nss_files_parse_pwent = parse_line ok
1923 @c internal_endent @ascuheap @asulock @aculock @acsmem @acsfd
1924 @c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
1925 @c libc_lock_unlock dup @aculock
1927 @c _nss_nis_getpwuid_r ... not fully reviewed (assumed) @asuinit @asulock @acucorrupt @aculock
1928 @c yp_get_default_domain @asulock @aculock
1929 @c libc_lock_lock dup @asulock @aculock
1930 @c getdomainname dup ok
1932 @c libc_lock_unlock dup @aculock
1933 @c snprintf dup @ascuheap @acsmem
1935 @c do_ypcall_tr(xdr_ypreq_key,xdr_ypresp_val)
1936 @c do_ypcall(xdr_ypreq_key,xdr_ypresp_val)
1937 @c libc_lock_lock @asulock @aculock
1943 @c libc_lock_unlock @aculock
1947 @c calloc dup @asulock @aculock @acsfd @acsmem
1950 @c snprintf dup @ascuheap @acsmem
1951 @c open dup @acsfd [cancelpt]
1952 @c pread dup [cancelpt]
1953 @c yp_bind_client_create
1954 @c close dup @acsfd [cancelpt]
1955 @c yp_bind_ypbindprog
1958 @c clnt_call(xdr_domainname,xdr_ypbind_resp)
1960 @c yp_bind_client_create
1961 @c free dup @asulock @aculock @acsfd @acsmem
1962 @c calloc dup @asulock @aculock @acsfd @acsmem
1963 @c free dup @asulock @aculock @acsfd @acsmem
1966 @c xdr_free(xdr_ypresp_val)
1985 @c mem_alloc @ascuheap @acsmem
1986 @c malloc dup @ascuheap @acsmem
1992 @c mem_free @ascuheap @acsmem
1993 @c free dup @ascuheap @acsmem
1996 @c _nls_default_nss @asuinit @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
1997 @c init @asuinit^, @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock
1998 @c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock
1999 @c fsetlocking ok [no concurrent uses]
2000 @c feof_unlocked dup ok
2001 @c getline dup @ascuheap @aculock @acucorrupt @acsmem
2002 @c isspace dup @mtslocale^^
2004 @c free dup @asulock @acsmem @acsfd @aculock
2005 @c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
2006 @c free dup @asulock @acsmem @acsfd @aculock
2009 @c isspace dup @mtslocale^^
2010 @c _nss_files_parse_pwent ok
2011 This function is similar to @code{getpwuid} in that it returns
2012 information about the user whose user ID is @var{uid}. However, it
2013 fills the user supplied structure pointed to by @var{result_buf} with
2014 the information instead of using a static buffer. The first
2015 @var{buflen} bytes of the additional buffer pointed to by @var{buffer}
2016 are used to contain additional information, normally strings which are
2017 pointed to by the elements of the result structure.
2019 If a user with ID @var{uid} is found, the pointer returned in
2020 @var{result} points to the record which contains the wanted data (i.e.,
2021 @var{result} contains the value @var{result_buf}). If no user is found
2022 or if an error occurred, the pointer returned in @var{result} is a null
2023 pointer. The function returns zero or an error code. If the buffer
2024 @var{buffer} is too small to contain all the needed information, the
2025 error code @code{ERANGE} is returned and @var{errno} is set to
2030 @deftypefun {struct passwd *} getpwnam (const char *@var{name})
2031 @standards{POSIX.1, pwd.h}
2032 @safety{@prelim{}@mtunsafe{@mtasurace{:pwnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2033 @c getpwnam @mtasurace:pwnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2034 @c libc_lock_lock dup @asulock @aculock
2035 @c malloc dup @ascuheap @acsmem
2036 @c getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2037 @c realloc dup @ascuheap @acsmem
2038 @c free dup @ascuheap @acsmem
2039 @c libc_lock_unlock dup @aculock
2040 This function returns a pointer to a statically-allocated structure
2041 containing information about the user whose user name is @var{name}.
2042 This structure may be overwritten on subsequent calls to
2045 A null pointer return indicates there is no user named @var{name}.
2048 @deftypefun int getpwnam_r (const char *@var{name}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
2049 @standards{POSIX.1c, pwd.h}
2050 @safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2051 @c getpwnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2052 @c nscd_getpwnam_r @ascuheap @asulock @aculock @acsfd @acsmem
2054 @c nscd_getpw_r dup @ascuheap @asulock @aculock @acsfd @acsmem
2055 @c nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2056 @c *fct.l @ascuplugin
2057 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2059 @c _nss_files_getpwnam_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd
2060 @c libc_lock_lock dup @asulock @aculock
2061 @c internal_setent dup @ascuheap @asulock @aculock @acsmem @acsfd
2062 @c internal_getent dup @mtslocale^
2064 @c internal_endent dup @ascuheap @asulock @aculock @acsmem @acsfd
2065 @c libc_lock_unlock dup @aculock
2067 @c _nss_*_getpwnam_r (assumed) @asuinit @asulock @acucorrupt @aculock
2069 This function is similar to @code{getpwnam} in that it returns
2070 information about the user whose user name is @var{name}. However, like
2071 @code{getpwuid_r}, it fills the user supplied buffers in
2072 @var{result_buf} and @var{buffer} with the information instead of using
2075 The return values are the same as for @code{getpwuid_r}.
2079 @node Scanning All Users
2080 @subsection Scanning the List of All Users
2081 @cindex scanning the user list
2083 This section explains how a program can read the list of all users in
2084 the system, one user at a time. The functions described here are
2085 declared in @file{pwd.h}.
2087 You can use the @code{fgetpwent} function to read user entries from a
2090 @deftypefun {struct passwd *} fgetpwent (FILE *@var{stream})
2091 @standards{SVID, pwd.h}
2092 @safety{@prelim{}@mtunsafe{@mtasurace{:fpwent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
2093 @c fgetpwent @mtasurace:fpwent @asucorrupt @asulock @acucorrupt @aculock
2094 @c fgetpos dup @asucorrupt @aculock @acucorrupt
2095 @c libc_lock_lock dup @asulock @aculock
2096 @c malloc dup @ascuheap @acsmem
2097 @c fgetpwent_r dup @asucorrupt @acucorrupt @aculock
2098 @c realloc dup @ascuheap @acsmem
2099 @c free dup @ascuheap @acsmem
2100 @c fsetpos dup @asucorrupt @aculock @acucorrupt
2101 @c libc_lock_unlock dup @aculock
2102 This function reads the next user entry from @var{stream} and returns a
2103 pointer to the entry. The structure is statically allocated and is
2104 rewritten on subsequent calls to @code{fgetpwent}. You must copy the
2105 contents of the structure if you wish to save the information.
2107 The stream must correspond to a file in the same format as the standard
2108 password database file.
2111 @deftypefun int fgetpwent_r (FILE *@var{stream}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
2112 @standards{GNU, pwd.h}
2113 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
2114 @c fgetpwent_r @asucorrupt @acucorrupt @aculock
2115 @c flockfile dup @aculock
2116 @c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
2117 @c feof_unlocked dup ok
2118 @c funlockfile dup @aculock
2119 @c isspace dup @mtslocale^^
2120 @c parse_line dup ok
2121 This function is similar to @code{fgetpwent} in that it reads the next
2122 user entry from @var{stream}. But the result is returned in the
2123 structure pointed to by @var{result_buf}. The
2124 first @var{buflen} bytes of the additional buffer pointed to by
2125 @var{buffer} are used to contain additional information, normally
2126 strings which are pointed to by the elements of the result structure.
2128 The stream must correspond to a file in the same format as the standard
2129 password database file.
2131 If the function returns zero @var{result} points to the structure with
2132 the wanted data (normally this is in @var{result_buf}). If errors
2133 occurred the return value is nonzero and @var{result} contains a null
2137 The way to scan all the entries in the user database is with
2138 @code{setpwent}, @code{getpwent}, and @code{endpwent}.
2140 @deftypefun void setpwent (void)
2141 @standards{SVID, pwd.h}
2142 @standards{BSD, pwd.h}
2143 @safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2144 @c setpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2145 @c libc_lock_lock @asulock @aculock
2146 @c nss_setent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2147 @c ** resolv's res_maybe_init not called here
2148 @c setup(nss_passwd_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2149 @c *lookup_fct = nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2150 @c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2151 @c *fct.f @mtasurace:pwent @ascuplugin
2152 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2153 @c libc_lock_unlock @aculock
2154 This function initializes a stream which @code{getpwent} and
2155 @code{getpwent_r} use to read the user database.
2158 @deftypefun {struct passwd *} getpwent (void)
2159 @standards{POSIX.1, pwd.h}
2160 @safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtasurace{:pwentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2161 @c getpwent @mtasurace:pwent @mtasurace:pwentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2162 @c libc_lock_lock dup @asulock @aculock
2163 @c nss_getent(getpwent_r) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2164 @c malloc dup @ascuheap @acsmem
2165 @c *func = getpwent_r dup @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2166 @c realloc dup @ascuheap @acsmem
2167 @c free dup @ascuheap @acsmem
2168 @c libc_lock_unlock dup @aculock
2169 The @code{getpwent} function reads the next entry from the stream
2170 initialized by @code{setpwent}. It returns a pointer to the entry. The
2171 structure is statically allocated and is rewritten on subsequent calls
2172 to @code{getpwent}. You must copy the contents of the structure if you
2173 wish to save the information.
2175 A null pointer is returned when no more entries are available.
2178 @deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result})
2179 @standards{GNU, pwd.h}
2180 @safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2181 @c The static buffer here is not the result_buf, but rather the
2182 @c variables that keep track of what nss backend we've last used, and
2183 @c whatever internal state the nss backend uses to keep track of the
2185 @c getpwent_r @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2186 @c libc_lock_lock dup @asulock @aculock
2187 @c nss_getent_r(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2188 @c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2189 @c *fct.f @mtasurace:pwent @ascuplugin
2190 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2191 @c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2192 @c *sfct.f @mtasurace:pwent @ascuplugin
2193 @c libc_lock_unlock dup @aculock
2194 This function is similar to @code{getpwent} in that it returns the next
2195 entry from the stream initialized by @code{setpwent}. Like
2196 @code{fgetpwent_r}, it uses the user-supplied buffers in
2197 @var{result_buf} and @var{buffer} to return the information requested.
2199 The return values are the same as for @code{fgetpwent_r}.
2203 @deftypefun void endpwent (void)
2204 @standards{SVID, pwd.h}
2205 @standards{BSD, pwd.h}
2206 @safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2207 @c endpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2208 @c libc_lock_lock @asulock @aculock
2209 @c nss_endent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2210 @c ** resolv's res_maybe_init not called here
2211 @c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2212 @c *fct.f @mtasurace:pwent @ascuplugin
2213 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2214 @c libc_lock_unlock @aculock
2215 This function closes the internal stream used by @code{getpwent} or
2219 @node Writing a User Entry
2220 @subsection Writing a User Entry
2222 @deftypefun int putpwent (const struct passwd *@var{p}, FILE *@var{stream})
2223 @standards{SVID, pwd.h}
2224 @safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}}
2225 @c putpwent @mtslocale @asucorrupt @aculock @acucorrupt
2226 @c fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem]
2227 This function writes the user entry @code{*@var{p}} to the stream
2228 @var{stream}, in the format used for the standard user database
2229 file. The return value is zero on success and nonzero on failure.
2231 This function exists for compatibility with SVID. We recommend that you
2232 avoid using it, because it makes sense only on the assumption that the
2233 @code{struct passwd} structure has no members except the standard ones;
2234 on a system which merges the traditional Unix data base with other
2235 extended information about users, adding an entry using this function
2236 would inevitably leave out much of the important information.
2237 @c Then how are programmers to modify the password file? -zw
2239 The group and user ID fields are left empty if the group or user name
2240 starts with a - or +.
2242 The function @code{putpwent} is declared in @file{pwd.h}.
2245 @node Group Database
2246 @section Group Database
2247 @cindex group database
2250 This section describes how to search and scan the database of
2251 registered groups. The database itself is kept in the file
2252 @file{/etc/group} on most systems, but on some systems a special network
2253 service provides access to it.
2256 * Group Data Structure:: What each group record contains.
2257 * Lookup Group:: How to look for a particular group.
2258 * Scanning All Groups:: Scanning the list of all groups.
2261 @node Group Data Structure
2262 @subsection The Data Structure for a Group
2264 The functions and data structures for accessing the system group
2265 database are declared in the header file @file{grp.h}.
2268 @deftp {Data Type} {struct group}
2269 @standards{POSIX.1, grp.h}
2270 The @code{group} structure is used to hold information about an entry in
2271 the system group database. It has at least the following members:
2275 The name of the group.
2278 The group ID of the group.
2281 A vector of pointers to the names of users in the group. Each user name
2282 is a null-terminated string, and the vector itself is terminated by a
2288 @subsection Looking Up One Group
2289 @cindex converting group name to group ID
2290 @cindex converting group ID to group name
2292 You can search the group database for information about a specific
2293 group using @code{getgrgid} or @code{getgrnam}. These functions are
2294 declared in @file{grp.h}.
2296 @deftypefun {struct group *} getgrgid (gid_t @var{gid})
2297 @standards{POSIX.1, grp.h}
2298 @safety{@prelim{}@mtunsafe{@mtasurace{:grgid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2299 @c getgrgid =~ getpwuid dup @mtasurace:grgid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2300 @c getgrgid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2301 This function returns a pointer to a statically-allocated structure
2302 containing information about the group whose group ID is @var{gid}.
2303 This structure may be overwritten by subsequent calls to
2306 A null pointer indicates there is no group with ID @var{gid}.
2309 @deftypefun int getgrgid_r (gid_t @var{gid}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2310 @standards{POSIX.1c, grp.h}
2311 @safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2312 @c getgrgid_r =~ getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2313 @c nscd_getgrgid_r @ascuheap @acsfd @acsmem
2315 @c nscd_getgr_r @ascuheap @acsfd @acsmem
2316 @c nscd_get_map_ref dup @ascuheap @acsfd @acsmem
2317 @c nscd_cache_search dup ok
2318 @c nscd_open_socket dup @acsfd
2322 @c wait_on_socket dup ok
2325 @c close_not_cancel_no_status dup @acsfd
2326 @c nscd_drop_map_ref dup @ascuheap @acsmem
2327 @c nscd_unmap dup @ascuheap @acsmem
2328 @c nss_group_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2329 @c *fct.l -> _nss_*_getgrgid_r @ascuplugin
2330 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2331 This function is similar to @code{getgrgid} in that it returns
2332 information about the group whose group ID is @var{gid}. However, it
2333 fills the user supplied structure pointed to by @var{result_buf} with
2334 the information instead of using a static buffer. The first
2335 @var{buflen} bytes of the additional buffer pointed to by @var{buffer}
2336 are used to contain additional information, normally strings which are
2337 pointed to by the elements of the result structure.
2339 If a group with ID @var{gid} is found, the pointer returned in
2340 @var{result} points to the record which contains the wanted data (i.e.,
2341 @var{result} contains the value @var{result_buf}). If no group is found
2342 or if an error occurred, the pointer returned in @var{result} is a null
2343 pointer. The function returns zero or an error code. If the buffer
2344 @var{buffer} is too small to contain all the needed information, the
2345 error code @code{ERANGE} is returned and @var{errno} is set to
2349 @deftypefun {struct group *} getgrnam (const char *@var{name})
2350 @standards{SVID, grp.h}
2351 @standards{BSD, grp.h}
2352 @safety{@prelim{}@mtunsafe{@mtasurace{:grnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2353 @c getgrnam =~ getpwnam dup @mtasurace:grnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2354 @c getgrnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2355 This function returns a pointer to a statically-allocated structure
2356 containing information about the group whose group name is @var{name}.
2357 This structure may be overwritten by subsequent calls to
2360 A null pointer indicates there is no group named @var{name}.
2363 @deftypefun int getgrnam_r (const char *@var{name}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2364 @standards{POSIX.1c, grp.h}
2365 @safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2366 @c getgrnam_r =~ getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2367 @c nscd_getgrnam_r @ascuheap @asulock @aculock @acsfd @acsmem
2369 @c nscd_getgr_r dup @ascuheap @asulock @aculock @acsfd @acsmem
2370 @c nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2371 @c *fct.l @ascuplugin
2372 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2373 This function is similar to @code{getgrnam} in that it returns
2374 information about the group whose group name is @var{name}. Like
2375 @code{getgrgid_r}, it uses the user supplied buffers in
2376 @var{result_buf} and @var{buffer}, not a static buffer.
2378 The return values are the same as for @code{getgrgid_r}.
2381 @node Scanning All Groups
2382 @subsection Scanning the List of All Groups
2383 @cindex scanning the group list
2385 This section explains how a program can read the list of all groups in
2386 the system, one group at a time. The functions described here are
2387 declared in @file{grp.h}.
2389 You can use the @code{fgetgrent} function to read group entries from a
2392 @deftypefun {struct group *} fgetgrent (FILE *@var{stream})
2393 @standards{SVID, grp.h}
2394 @safety{@prelim{}@mtunsafe{@mtasurace{:fgrent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}}
2395 @c fgetgrent @mtasurace:fgrent @asucorrupt @asulock @acucorrupt @aculock
2396 @c fgetpos dup @asucorrupt @aculock @acucorrupt
2397 @c libc_lock_lock dup @asulock @aculock
2398 @c malloc dup @ascuheap @acsmem
2399 @c fgetgrent_r dup @asucorrupt @acucorrupt @aculock
2400 @c realloc dup @ascuheap @acsmem
2401 @c free dup @ascuheap @acsmem
2402 @c fsetpos dup @asucorrupt @aculock @acucorrupt
2403 @c libc_lock_unlock dup @aculock
2404 The @code{fgetgrent} function reads the next entry from @var{stream}.
2405 It returns a pointer to the entry. The structure is statically
2406 allocated and is overwritten on subsequent calls to @code{fgetgrent}. You
2407 must copy the contents of the structure if you wish to save the
2410 The stream must correspond to a file in the same format as the standard
2411 group database file.
2414 @deftypefun int fgetgrent_r (FILE *@var{stream}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2415 @standards{GNU, grp.h}
2416 @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}}
2417 @c fgetgrent_r @asucorrupt @acucorrupt @aculock
2418 @c flockfile dup @aculock
2419 @c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking]
2420 @c feof_unlocked dup ok
2421 @c funlockfile dup @aculock
2422 @c isspace dup @mtslocale^^
2423 @c parse_line dup ok
2424 This function is similar to @code{fgetgrent} in that it reads the next
2425 user entry from @var{stream}. But the result is returned in the
2426 structure pointed to by @var{result_buf}. The first @var{buflen} bytes
2427 of the additional buffer pointed to by @var{buffer} are used to contain
2428 additional information, normally strings which are pointed to by the
2429 elements of the result structure.
2431 This stream must correspond to a file in the same format as the standard
2432 group database file.
2434 If the function returns zero @var{result} points to the structure with
2435 the wanted data (normally this is in @var{result_buf}). If errors
2436 occurred the return value is non-zero and @var{result} contains a null
2440 The way to scan all the entries in the group database is with
2441 @code{setgrent}, @code{getgrent}, and @code{endgrent}.
2443 @deftypefun void setgrent (void)
2444 @standards{SVID, grp.h}
2445 @standards{BSD, grp.h}
2446 @safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2447 @c setgrent =~ setpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2448 @c ...*lookup_fct = nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2449 This function initializes a stream for reading from the group data base.
2450 You use this stream by calling @code{getgrent} or @code{getgrent_r}.
2453 @deftypefun {struct group *} getgrent (void)
2454 @standards{SVID, grp.h}
2455 @standards{BSD, grp.h}
2456 @safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtasurace{:grentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2457 @c getgrent =~ getpwent dup @mtasurace:grent @mtasurace:grentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2458 @c *func = getgrent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2459 The @code{getgrent} function reads the next entry from the stream
2460 initialized by @code{setgrent}. It returns a pointer to the entry. The
2461 structure is statically allocated and is overwritten on subsequent calls
2462 to @code{getgrent}. You must copy the contents of the structure if you
2463 wish to save the information.
2466 @deftypefun int getgrent_r (struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result})
2467 @standards{GNU, grp.h}
2468 @safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2469 @c getgrent_r =~ getpwent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2470 This function is similar to @code{getgrent} in that it returns the next
2471 entry from the stream initialized by @code{setgrent}. Like
2472 @code{fgetgrent_r}, it places the result in user-supplied buffers
2473 pointed to by @var{result_buf} and @var{buffer}.
2475 If the function returns zero @var{result} contains a pointer to the data
2476 (normally equal to @var{result_buf}). If errors occurred the return
2477 value is non-zero and @var{result} contains a null pointer.
2480 @deftypefun void endgrent (void)
2481 @standards{SVID, grp.h}
2482 @standards{BSD, grp.h}
2483 @safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2484 @c endgrent =~ endpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2485 This function closes the internal stream used by @code{getgrent} or
2489 @node Database Example
2490 @section User and Group Database Example
2492 Here is an example program showing the use of the system database inquiry
2493 functions. The program prints some information about the user running
2500 Here is some output from this program:
2503 I am Throckmorton Snurd.
2504 My login name is snurd.
2506 My home directory is /home/fsg/snurd.
2507 My default shell is /bin/sh.
2508 My default group is guest (12).
2509 The members of this group are:
2514 @node Netgroup Database
2515 @section Netgroup Database
2518 * Netgroup Data:: Data in the Netgroup database and where
2520 * Lookup Netgroup:: How to look for a particular netgroup.
2521 * Netgroup Membership:: How to test for netgroup membership.
2525 @subsection Netgroup Data
2528 Sometimes it is useful to group users according to other criteria
2529 (@pxref{Group Database}). E.g., it is useful to associate a certain
2530 group of users with a certain machine. On the other hand grouping of
2531 host names is not supported so far.
2533 In Sun Microsystems' SunOS appeared a new kind of database, the netgroup
2534 database. It allows grouping hosts, users, and domains freely, giving
2535 them individual names. To be more concrete, a netgroup is a list of triples
2536 consisting of a host name, a user name, and a domain name where any of
2537 the entries can be a wildcard entry matching all inputs. A last
2538 possibility is that names of other netgroups can also be given in the
2539 list specifying a netgroup. So one can construct arbitrary hierarchies
2542 Sun's implementation allows netgroups only for the @code{nis} or
2543 @code{nisplus} service, @pxref{Services in the NSS configuration}. The
2544 implementation in @theglibc{} has no such restriction. An entry
2545 in either of the input services must have the following form:
2548 @var{groupname} ( @var{groupname} | @code{(}@var{hostname}@code{,}@var{username}@code{,}@code{domainname}@code{)} )+
2551 Any of the fields in the triple can be empty which means anything
2552 matches. While describing the functions we will see that the opposite
2553 case is useful as well. I.e., there may be entries which will not
2554 match any input. For entries like this, a name consisting of the single
2555 character @code{-} shall be used.
2557 @node Lookup Netgroup
2558 @subsection Looking up one Netgroup
2560 The lookup functions for netgroups are a bit different than all other
2561 system database handling functions. Since a single netgroup can contain
2562 many entries a two-step process is needed. First a single netgroup is
2563 selected and then one can iterate over all entries in this netgroup.
2564 These functions are declared in @file{netdb.h}.
2566 @deftypefun int setnetgrent (const char *@var{netgroup})
2567 @standards{BSD, netdb.h}
2568 @safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2569 @c setnetgrent @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2570 @c libc_lock_lock dup @asulock @aculock
2571 @c nscd_setnetgrent @ascuheap @acsfd @acsmem
2572 @c __nscd_setnetgrent @ascuheap @acsfd @acsmem
2574 @c nscd_get_map_ref dup @ascuheap @acsfd @acsmem
2575 @c nscd_cache_search dup ok
2576 @c nscd_open_socket dup @acsfd
2577 @c malloc dup @ascuheap @acsmem
2579 @c free dup @ascuheap @acsmem
2580 @c close_not_cancel_no_status dup @acsfd
2581 @c nscd_drop_map_ref dup @ascuheap @acsmem
2582 @c nscd_unmap dup @ascuheap @acsmem
2583 @c internal_setnetgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2584 @c free_memory dup @ascuheap @acsmem
2585 @c free dup @ascuheap @acsmem
2586 @c internal_setnetgrent_reuse @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2587 @c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2588 @c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2589 @c *endfct @ascuplugin
2590 @c (netgroup::)setup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2591 @c nss_netgroup_lookup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2592 @c nss_netgroup_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2593 @c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2594 @c *fct.f @ascuplugin
2595 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2596 @c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2597 @c *endfct @ascuplugin
2599 @c malloc dup @ascuheap @acsmem
2601 @c libc_lock_unlock dup @aculock
2602 A call to this function initializes the internal state of the library to
2603 allow following calls of @code{getnetgrent} to iterate over all entries
2604 in the netgroup with name @var{netgroup}.
2606 When the call is successful (i.e., when a netgroup with this name exists)
2607 the return value is @code{1}. When the return value is @code{0} no
2608 netgroup of this name is known or some other error occurred.
2611 It is important to remember that there is only one single state for
2612 iterating the netgroups. Even if the programmer uses the
2613 @code{getnetgrent_r} function the result is not really reentrant since
2614 always only one single netgroup at a time can be processed. If the
2615 program needs to process more than one netgroup simultaneously she
2616 must protect this by using external locking. This problem was
2617 introduced in the original netgroups implementation in SunOS and since
2618 we must stay compatible it is not possible to change this.
2620 Some other functions also use the netgroups state. Currently these are
2621 the @code{innetgr} function and parts of the implementation of the
2622 @code{compat} service part of the NSS implementation.
2624 @deftypefun int getnetgrent (char **@var{hostp}, char **@var{userp}, char **@var{domainp})
2625 @standards{BSD, netdb.h}
2626 @safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtasurace{:netgrentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2627 @c getnetgrent @mtasurace:netgrent @mtasurace:netgrentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2628 @c uses unsafely a static buffer allocated within a libc_once call
2629 @c allocate (libc_once) @ascuheap @acsmem
2630 @c malloc dup @ascuheap @acsmem
2631 @c getnetgrent_r dup @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2632 This function returns the next unprocessed entry of the currently
2633 selected netgroup. The string pointers, in which addresses are passed in
2634 the arguments @var{hostp}, @var{userp}, and @var{domainp}, will contain
2635 after a successful call pointers to appropriate strings. If the string
2636 in the next entry is empty the pointer has the value @code{NULL}.
2637 The returned string pointers are only valid if none of the netgroup
2638 related functions are called.
2640 The return value is @code{1} if the next entry was successfully read. A
2641 value of @code{0} means no further entries exist or internal errors occurred.
2644 @deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, size_t @var{buflen})
2645 @standards{GNU, netdb.h}
2646 @safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2647 @c getnetgrent_r @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2648 @c libc_lock_lock dup @asulock @aculock
2649 @c internal_getnetgrent_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2650 @c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2652 @c nscd_getnetgrent ok
2654 @c internal_setnetgrent_reuse dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2656 @c malloc dup @ascuheap @acsmem
2658 @c libc_lock_unlock dup @aculock
2659 This function is similar to @code{getnetgrent} with only one exception:
2660 the strings the three string pointers @var{hostp}, @var{userp}, and
2661 @var{domainp} point to, are placed in the buffer of @var{buflen} bytes
2662 starting at @var{buffer}. This means the returned values are valid
2663 even after other netgroup related functions are called.
2665 The return value is @code{1} if the next entry was successfully read and
2666 the buffer contains enough room to place the strings in it. @code{0} is
2667 returned in case no more entries are found, the buffer is too small, or
2668 internal errors occurred.
2670 This function is a GNU extension. The original implementation in the
2671 SunOS libc does not provide this function.
2674 @deftypefun void endnetgrent (void)
2675 @standards{BSD, netdb.h}
2676 @safety{@prelim{}@mtunsafe{@mtasurace{:netgrent}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2677 @c endnetgrent @mtasurace:netgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2678 @c libc_lock_lock dup @asulock @aculock
2679 @c internal_endnetgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2680 @c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2681 @c free_memory dup @ascuheap @acsmem
2682 @c libc_lock_unlock dup @aculock
2683 This function frees all buffers which were allocated to process the last
2684 selected netgroup. As a result all string pointers returned by calls
2685 to @code{getnetgrent} are invalid afterwards.
2688 @node Netgroup Membership
2689 @subsection Testing for Netgroup Membership
2691 It is often not necessary to scan the whole netgroup since often the
2692 only interesting question is whether a given entry is part of the
2695 @deftypefun int innetgr (const char *@var{netgroup}, const char *@var{host}, const char *@var{user}, const char *@var{domain})
2696 @standards{BSD, netdb.h}
2697 @safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
2698 @c This function does not use the static data structure that the
2699 @c *netgrent* ones do, but since each nss must maintains internal state
2700 @c to support iteration and concurrent iteration will interfere
2701 @c destructively, we regard this internal state as a static buffer.
2702 @c getnetgrent_r iteration in each nss backend.
2703 @c innetgr @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2704 @c nscd_innetgr @ascuheap @acsfd @acsmem
2706 @c malloc dup @ascuheap @acsmem
2708 @c nscd_get_map_ref dup @ascuheap @acsfd @acsmem
2709 @c nscd_cache_search dup ok
2710 @c nscd_open_socket dup @acsfd
2711 @c close_not_cancel_no_status dup @acsfd
2712 @c nscd_drop_map_ref dup @ascuheap @acsmem
2713 @c nscd_unmap dup @ascuheap @acsmem
2714 @c free dup @ascuheap @acsmem
2716 @c (netgroup::)setup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2717 @c *setfct.f @ascuplugin
2718 @c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2719 @c *getfct @ascuplugin
2722 @c malloc dup @ascuheap @acsmem
2725 @c *endfct @ascuplugin
2726 @c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem
2727 @c free_memory dup @ascuheap @acsmem
2728 This function tests whether the triple specified by the parameters
2729 @var{host}, @var{user}, and @var{domain} is part of the netgroup
2730 @var{netgroup}. Using this function has the advantage that
2734 no other netgroup function can use the global netgroup state since
2735 internal locking is used and
2737 the function is implemented more efficiently than successive calls
2738 to the other @code{set}/@code{get}/@code{endnetgrent} functions.
2741 Any of the pointers @var{host}, @var{user}, or @var{domain} can be
2742 @code{NULL} which means any value is accepted in this position. This is
2743 also true for the name @code{-} which should not match any other string
2746 The return value is @code{1} if an entry matching the given triple is
2747 found in the netgroup. The return value is @code{0} if the netgroup
2748 itself is not found, the netgroup does not contain the triple or
2749 internal errors occurred.
2752 @c FIXME these are undocumented: