toybox/toys/posix/id.c
<<
>>
Prefs
   1/* id.c - print real and effective user and group IDs
   2 *
   3 * Copyright 2012 Sony Network Entertainment, Inc.
   4 *
   5 * by Tim Bird <tim.bird@am.sony.com>
   6 *
   7 * See http://opengroup.org/onlinepubs/9699919799/utilities/id.html
   8
   9USE_ID(NEWTOY(id, ">1"USE_ID_Z("Z")"nGgru[!"USE_ID_Z("Z")"Ggu]", TOYFLAG_USR|TOYFLAG_BIN))
  10USE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN))
  11USE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_USR|TOYFLAG_BIN))
  12USE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_USR|TOYFLAG_BIN))
  13
  14config ID
  15  bool "id"
  16  default y
  17  help
  18    usage: id [-nGgru]
  19
  20    Print user and group ID.
  21
  22    -n  print names instead of numeric IDs (to be used with -Ggu)
  23    -G  Show only the group IDs
  24    -g  Show only the effective group ID
  25    -r  Show real ID instead of effective ID
  26    -u  Show only the effective user ID
  27
  28config ID_Z
  29  bool
  30  default y
  31  depends on ID && !TOYBOX_LSM_NONE
  32  help
  33    usage: id [-Z]
  34
  35    -Z  Show only security context
  36
  37config GROUPS
  38  bool "groups"
  39  default y
  40  help
  41    usage: groups [user]
  42
  43    Print the groups a user is in.
  44
  45config LOGNAME
  46  bool "logname"
  47  default y
  48  help
  49    usage: logname
  50
  51    Print the current user name.
  52
  53config WHOAMI
  54  bool "whoami"
  55  default y
  56  help
  57    usage: whoami
  58
  59    Print the current user name.
  60*/
  61
  62#define FOR_id
  63#define FORCE_FLAGS
  64#include "toys.h"
  65
  66GLOBALS(
  67  int is_groups;
  68)
  69
  70static void s_or_u(char *s, unsigned u, int done)
  71{
  72  if (toys.optflags&FLAG_n) printf("%s", s);
  73  else printf("%u", u);
  74  if (done) {
  75    xputc('\n');
  76    xexit();
  77  }
  78}
  79
  80static void showid(char *header, unsigned u, char *s)
  81{
  82  printf("%s%u(%s)", header, u, s);
  83}
  84
  85static void do_id(char *username)
  86{
  87  int flags, i, ngroups;
  88  struct passwd *pw;
  89  struct group *grp;
  90  uid_t uid = getuid(), euid = geteuid();
  91  gid_t gid = getgid(), egid = getegid(), *groups;
  92
  93  flags = toys.optflags;
  94
  95  // check if a username is given
  96  if (username) {
  97    pw = xgetpwnam(username);
  98    uid = euid = pw->pw_uid;
  99    gid = egid = pw->pw_gid;
 100    if (TT.is_groups) printf("%s : ", pw->pw_name);
 101  }
 102
 103  i = flags & FLAG_r;
 104  pw = xgetpwuid(i ? uid : euid);
 105  if (toys.optflags&FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1);
 106
 107  grp = xgetgrgid(i ? gid : egid);
 108  if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
 109
 110  if (!(toys.optflags&(FLAG_G|FLAG_g|FLAG_Z))) {
 111    showid("uid=", pw->pw_uid, pw->pw_name);
 112    showid(" gid=", grp->gr_gid, grp->gr_name);
 113
 114    if (!i) {
 115      if (uid != euid) {
 116        pw = xgetpwuid(euid);
 117        showid(" euid=", pw->pw_uid, pw->pw_name);
 118      }
 119      if (gid != egid) {
 120        grp = xgetgrgid(egid);
 121        showid(" egid=", grp->gr_gid, grp->gr_name);
 122      }
 123    }
 124
 125    showid(" groups=", grp->gr_gid, grp->gr_name);
 126  }
 127
 128  if (!(toys.optflags&FLAG_Z)) {
 129    groups = (gid_t *)toybuf;
 130    i = sizeof(toybuf)/sizeof(gid_t);
 131    ngroups = username ? getgrouplist(username, gid, groups, &i)
 132      : getgroups(i, groups);
 133    if (ngroups<0) perror_exit(0);
 134
 135    int show_separator = !(toys.optflags&FLAG_G);
 136    for (i = 0; i<ngroups; i++) {
 137      if (show_separator) xputc((toys.optflags&FLAG_G) ? ' ' : ',');
 138      show_separator = 1;
 139      if (!(grp = getgrgid(groups[i]))) perror_msg(0);
 140      else if (toys.optflags&FLAG_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
 141      else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
 142      else show_separator = 0; // Because we didn't show anything this time.
 143    }
 144    if (toys.optflags&FLAG_G) {
 145      xputc('\n');
 146      xexit();
 147    }
 148  }
 149
 150  if (!CFG_TOYBOX_LSM_NONE) {
 151    if (lsm_enabled()) {
 152      char *context = lsm_context();
 153
 154      printf(" context=%s"+!!(toys.optflags&FLAG_Z), context);
 155      if (CFG_TOYBOX_FREE) free(context);
 156    } else if (toys.optflags&FLAG_Z) error_exit("%s disabled", lsm_name());
 157  }
 158
 159  xputc('\n');
 160}
 161
 162void id_main(void)
 163{
 164  if (toys.optc) while(*toys.optargs) do_id(*toys.optargs++);
 165  else do_id(NULL);
 166}
 167
 168void groups_main(void)
 169{
 170  TT.is_groups = 1;
 171  toys.optflags = FLAG_G|FLAG_n;
 172  id_main();
 173}
 174
 175void logname_main(void)
 176{
 177  toys.optflags = FLAG_u|FLAG_n;
 178  id_main();
 179}
 180