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] [USER...]
  19
  20    Print user and group ID.
  21
  22    -G  Show all group IDs
  23    -g  Show only the effective group ID
  24    -n  Print names instead of numeric IDs (to be used with -Ggu)
  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 showone(char *prefix, char *s, unsigned u, int done)
  71{
  72  if (FLAG(n)) printf("%s%s", prefix, s);
  73  else printf("%s%u", prefix, u);
  74  if (done) {
  75    xputc('\n');
  76    xexit();
  77  }
  78}
  79
  80static void showid(char *prefix, unsigned u, char *s)
  81{
  82  printf("%s%u(%s)", prefix, u, s);
  83}
  84
  85static void do_id(char *username)
  86{
  87  struct passwd *pw;
  88  struct group *grp;
  89  uid_t uid = getuid(), euid = geteuid();
  90  gid_t gid = getgid(), egid = getegid();
  91  gid_t *groups = (gid_t *)toybuf;
  92  int i = sizeof(toybuf)/sizeof(gid_t), ngroups;
  93
  94  // check if a username is given
  95  if (username) {
  96    pw = getpwnam(username);
  97    if (!pw) {
  98      uid = atolx_range(username, 0, INT_MAX);
  99      if ((pw = getpwuid(uid))) username = pw->pw_name;
 100    }
 101    if (!pw) error_exit("no such user '%s'", username);
 102    uid = euid = pw->pw_uid;
 103    gid = egid = pw->pw_gid;
 104    if (TT.is_groups) printf("%s : ", pw->pw_name);
 105  }
 106
 107  pw = xgetpwuid(FLAG(r) ? uid : euid);
 108  if (FLAG(u)) showone("", pw->pw_name, pw->pw_uid, 1);
 109
 110  grp = xgetgrgid(FLAG(r) ? gid : egid);
 111  if (FLAG(g)) showone("", grp->gr_name, grp->gr_gid, 1);
 112
 113  ngroups = username ? getgrouplist(username, gid, groups, &i)
 114    : getgroups(i, groups);
 115  if (ngroups<0) perror_exit("getgroups");
 116
 117  if (FLAG(G)) {
 118    showone("", grp->gr_name, grp->gr_gid, 0);
 119    for (i = 0; i<ngroups; i++) {
 120      if (groups[i] != egid) {
 121        if ((grp=getgrgid(groups[i]))) showone(" ",grp->gr_name,grp->gr_gid,0);
 122        else printf(" %u", groups[i]);
 123      }
 124    }
 125    xputc('\n');
 126    return;
 127  }
 128
 129  if (!FLAG(Z)) {
 130    showid("uid=", pw->pw_uid, pw->pw_name);
 131    showid(" gid=", grp->gr_gid, grp->gr_name);
 132
 133    if (!FLAG(r)) {
 134      if (uid != euid) {
 135        pw = xgetpwuid(euid);
 136        showid(" euid=", pw->pw_uid, pw->pw_name);
 137      }
 138      if (gid != egid) {
 139        grp = xgetgrgid(egid);
 140        showid(" egid=", grp->gr_gid, grp->gr_name);
 141      }
 142    }
 143
 144    showid(" groups=", gid, grp->gr_name);
 145    for (i = 0; i<ngroups; i++) {
 146      if (groups[i] != egid) {
 147        if ((grp=getgrgid(groups[i]))) showid(",", grp->gr_gid, grp->gr_name);
 148        else printf(",%u", groups[i]);
 149      }
 150    }
 151  }
 152
 153  if (!CFG_TOYBOX_LSM_NONE) {
 154    if (lsm_enabled()) {
 155      char *context = lsm_context();
 156
 157      printf("%s%s", FLAG(Z) ? "" : " context=", context);
 158      if (CFG_TOYBOX_FREE) free(context);
 159    } else if (FLAG(Z)) error_exit("%s disabled", lsm_name());
 160  }
 161
 162  xputc('\n');
 163}
 164
 165void id_main(void)
 166{
 167  if (toys.optc) while(*toys.optargs) do_id(*toys.optargs++);
 168  else do_id(NULL);
 169}
 170
 171void groups_main(void)
 172{
 173  TT.is_groups = 1;
 174  toys.optflags = FLAG_G|FLAG_n;
 175  id_main();
 176}
 177
 178void logname_main(void)
 179{
 180  toys.optflags = FLAG_u|FLAG_n;
 181  id_main();
 182}
 183