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