Decoded: id (coreutils)

[Back to Project Main Page]

Note: This page explores the design of command-line utilities. It is not a user guide.
[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]

Logical flow of id command (coreutils)

Summary

id - print user identity

[Source] [Code Walkthrough]

Lines of code: 441
Principal syscall: None
Support syscalls: None
Options: 17 (8 short, 9 long)

Descended from id in System V (1985)
Added to Shellutils in November 1992 [First version]
Number of revisions: 157 [Code Evolution]

Helpers:
  • gidtostr_ptr() - Converts a gid_t to a string
  • print_full_info() - Prints user, group, effective ids, and context
  • print_user() - Prints a user name based on a uid_t match in passwd
  • uidtostr_ptr() - Converts a uid_t to a string
External non-standard helpers:
  • die() - Exit with mandatory non-zero error and message to stderr
  • error() - Outputs error message to standard error with possible process termination
  • print_group() - Prints a group id (from group_list.c

Setup

Some flags and variables for id are declared as globals, including:

  • egid - The effective group id
  • euid - The effective user id
  • ok - The execution status of the utility
  • rgid - The real group id
  • ruid - The real user id

The majority of variables are locals in main():

  • just_group - Flag to print only EGID
  • just_group_list - Flag to print all EGIDs
  • just_user - Flag to print only EUID
  • opt_zero - Flag to use the NUL delimiter rather than whitespace
  • optc - The first character of the next option to process
  • pw_name - The name returned from the passwd file
  • selinux_enabled - Flag if SELinux is enabled
  • smack_enabled - Flag is Smack is enabled
  • use_real - Flag if real IDs should be displayed rahter than effective IDs

Parsing

Parsing user input for id tells us how the user wants information displayed:

  • Should we display IDs or names? Real or effective IDs? All, some, or one?
  • Should we delimit with NUL or whitespace?
  • Should we display the security context?
  • Should we look up the current user or a specified user?

That final question drives where we find the information and which syscalls to use during execution.

Parsing has many sanity checks due to the number of ways users can display data.

Parsing failures

Thess failure cases are explicitly checked:

  • Using context options on a system without security features enabled
  • More than one argument provided
  • Trying to display a user and a context at the same time
  • Try to print many 'single only' types at once
  • Trying to print
  • Using a zero delimiter in default format
  • Using an unknown option

This failure result in a short error message followed by the usage instructions.


Execution

The most important factor in the id execution path is if a user lookup is specified. The general idea is:

  • Get security context, if requested
  • If a user is specified, verify from passwd with getpwuid()
  • If a no user is specified, verify the current user information
  • Work through each display flag and print data requesting for user

Failure cases:

  • User doesn't exist
  • Cannot pull any requested data (EUID, RUID, EGID, RGID, etc)
  • Cannot find user groups
  • Cannot access passwd
  • Cannot find process context

[Back to Project Main Page]