10f66f451Sopenharmony_ci/* id.c - print real and effective user and group IDs
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2012 Sony Network Entertainment, Inc.
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * by Tim Bird <tim.bird@am.sony.com>
60f66f451Sopenharmony_ci *
70f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/id.html
80f66f451Sopenharmony_ci
90f66f451Sopenharmony_ciUSE_ID(NEWTOY(id, ">1"USE_ID_Z("Z")"nGgru[!"USE_ID_Z("Z")"Ggu]", TOYFLAG_USR|TOYFLAG_BIN))
100f66f451Sopenharmony_ciUSE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN))
110f66f451Sopenharmony_ciUSE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_USR|TOYFLAG_BIN))
120f66f451Sopenharmony_ciUSE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_USR|TOYFLAG_BIN))
130f66f451Sopenharmony_ci
140f66f451Sopenharmony_ciconfig ID
150f66f451Sopenharmony_ci  bool "id"
160f66f451Sopenharmony_ci  default y
170f66f451Sopenharmony_ci  help
180f66f451Sopenharmony_ci    usage: id [-nGgru] [USER...]
190f66f451Sopenharmony_ci
200f66f451Sopenharmony_ci    Print user and group ID.
210f66f451Sopenharmony_ci
220f66f451Sopenharmony_ci    -n	Print names instead of numeric IDs (to be used with -Ggu)
230f66f451Sopenharmony_ci    -G	Show only the group IDs
240f66f451Sopenharmony_ci    -g	Show only the effective group ID
250f66f451Sopenharmony_ci    -r	Show real ID instead of effective ID
260f66f451Sopenharmony_ci    -u	Show only the effective user ID
270f66f451Sopenharmony_ci
280f66f451Sopenharmony_ciconfig ID_Z
290f66f451Sopenharmony_ci  bool
300f66f451Sopenharmony_ci  default y
310f66f451Sopenharmony_ci  depends on ID && !TOYBOX_LSM_NONE
320f66f451Sopenharmony_ci  help
330f66f451Sopenharmony_ci    usage: id [-Z]
340f66f451Sopenharmony_ci
350f66f451Sopenharmony_ci    -Z	Show only security context
360f66f451Sopenharmony_ci
370f66f451Sopenharmony_ciconfig GROUPS
380f66f451Sopenharmony_ci  bool "groups"
390f66f451Sopenharmony_ci  default y
400f66f451Sopenharmony_ci  help
410f66f451Sopenharmony_ci    usage: groups [user]
420f66f451Sopenharmony_ci
430f66f451Sopenharmony_ci    Print the groups a user is in.
440f66f451Sopenharmony_ci
450f66f451Sopenharmony_ciconfig LOGNAME
460f66f451Sopenharmony_ci  bool "logname"
470f66f451Sopenharmony_ci  default y
480f66f451Sopenharmony_ci  help
490f66f451Sopenharmony_ci    usage: logname
500f66f451Sopenharmony_ci
510f66f451Sopenharmony_ci    Print the current user name.
520f66f451Sopenharmony_ci
530f66f451Sopenharmony_ciconfig WHOAMI
540f66f451Sopenharmony_ci  bool "whoami"
550f66f451Sopenharmony_ci  default y
560f66f451Sopenharmony_ci  help
570f66f451Sopenharmony_ci    usage: whoami
580f66f451Sopenharmony_ci
590f66f451Sopenharmony_ci    Print the current user name.
600f66f451Sopenharmony_ci*/
610f66f451Sopenharmony_ci
620f66f451Sopenharmony_ci#define FOR_id
630f66f451Sopenharmony_ci#define FORCE_FLAGS
640f66f451Sopenharmony_ci#include "toys.h"
650f66f451Sopenharmony_ci
660f66f451Sopenharmony_ciGLOBALS(
670f66f451Sopenharmony_ci  int is_groups;
680f66f451Sopenharmony_ci)
690f66f451Sopenharmony_ci
700f66f451Sopenharmony_cistatic void s_or_u(char *s, unsigned u, int done)
710f66f451Sopenharmony_ci{
720f66f451Sopenharmony_ci  if (toys.optflags&FLAG_n) printf("%s", s);
730f66f451Sopenharmony_ci  else printf("%u", u);
740f66f451Sopenharmony_ci  if (done) {
750f66f451Sopenharmony_ci    xputc('\n');
760f66f451Sopenharmony_ci    xexit();
770f66f451Sopenharmony_ci  }
780f66f451Sopenharmony_ci}
790f66f451Sopenharmony_ci
800f66f451Sopenharmony_cistatic void showid(char *header, unsigned u, char *s)
810f66f451Sopenharmony_ci{
820f66f451Sopenharmony_ci  printf("%s%u(%s)", header, u, s);
830f66f451Sopenharmony_ci}
840f66f451Sopenharmony_ci
850f66f451Sopenharmony_cistatic void do_id(char *username)
860f66f451Sopenharmony_ci{
870f66f451Sopenharmony_ci  int flags, i, ngroups;
880f66f451Sopenharmony_ci  struct passwd *pw;
890f66f451Sopenharmony_ci  struct group *grp;
900f66f451Sopenharmony_ci  uid_t uid = getuid(), euid = geteuid();
910f66f451Sopenharmony_ci  gid_t gid = getgid(), egid = getegid(), *groups;
920f66f451Sopenharmony_ci
930f66f451Sopenharmony_ci  flags = toys.optflags;
940f66f451Sopenharmony_ci
950f66f451Sopenharmony_ci  // check if a username is given
960f66f451Sopenharmony_ci  if (username) {
970f66f451Sopenharmony_ci    pw = xgetpwnam(username);
980f66f451Sopenharmony_ci    uid = euid = pw->pw_uid;
990f66f451Sopenharmony_ci    gid = egid = pw->pw_gid;
1000f66f451Sopenharmony_ci    if (TT.is_groups) printf("%s : ", pw->pw_name);
1010f66f451Sopenharmony_ci  }
1020f66f451Sopenharmony_ci
1030f66f451Sopenharmony_ci  i = flags & FLAG_r;
1040f66f451Sopenharmony_ci  pw = xgetpwuid(i ? uid : euid);
1050f66f451Sopenharmony_ci  if (toys.optflags&FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1);
1060f66f451Sopenharmony_ci
1070f66f451Sopenharmony_ci  grp = xgetgrgid(i ? gid : egid);
1080f66f451Sopenharmony_ci  if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
1090f66f451Sopenharmony_ci
1100f66f451Sopenharmony_ci  if (!(toys.optflags&(FLAG_G|FLAG_g|FLAG_Z))) {
1110f66f451Sopenharmony_ci    showid("uid=", pw->pw_uid, pw->pw_name);
1120f66f451Sopenharmony_ci    showid(" gid=", grp->gr_gid, grp->gr_name);
1130f66f451Sopenharmony_ci
1140f66f451Sopenharmony_ci    if (!i) {
1150f66f451Sopenharmony_ci      if (uid != euid) {
1160f66f451Sopenharmony_ci        pw = xgetpwuid(euid);
1170f66f451Sopenharmony_ci        showid(" euid=", pw->pw_uid, pw->pw_name);
1180f66f451Sopenharmony_ci      }
1190f66f451Sopenharmony_ci      if (gid != egid) {
1200f66f451Sopenharmony_ci        grp = xgetgrgid(egid);
1210f66f451Sopenharmony_ci        showid(" egid=", grp->gr_gid, grp->gr_name);
1220f66f451Sopenharmony_ci      }
1230f66f451Sopenharmony_ci    }
1240f66f451Sopenharmony_ci
1250f66f451Sopenharmony_ci    showid(" groups=", grp->gr_gid, grp->gr_name);
1260f66f451Sopenharmony_ci  }
1270f66f451Sopenharmony_ci
1280f66f451Sopenharmony_ci  if (!(toys.optflags&FLAG_Z)) {
1290f66f451Sopenharmony_ci    groups = (gid_t *)toybuf;
1300f66f451Sopenharmony_ci    i = sizeof(toybuf)/sizeof(gid_t);
1310f66f451Sopenharmony_ci    ngroups = username ? getgrouplist(username, gid, groups, &i)
1320f66f451Sopenharmony_ci      : getgroups(i, groups);
1330f66f451Sopenharmony_ci    if (ngroups<0) perror_exit(0);
1340f66f451Sopenharmony_ci
1350f66f451Sopenharmony_ci    int show_separator = !(toys.optflags&FLAG_G);
1360f66f451Sopenharmony_ci    for (i = 0; i<ngroups; i++) {
1370f66f451Sopenharmony_ci      if (show_separator) xputc((toys.optflags&FLAG_G) ? ' ' : ',');
1380f66f451Sopenharmony_ci      show_separator = 1;
1390f66f451Sopenharmony_ci      if (!(grp = getgrgid(groups[i]))) perror_msg(0);
1400f66f451Sopenharmony_ci      else if (toys.optflags&FLAG_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
1410f66f451Sopenharmony_ci      else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
1420f66f451Sopenharmony_ci      else show_separator = 0; // Because we didn't show anything this time.
1430f66f451Sopenharmony_ci    }
1440f66f451Sopenharmony_ci    if (toys.optflags&FLAG_G) {
1450f66f451Sopenharmony_ci      xputc('\n');
1460f66f451Sopenharmony_ci      xexit();
1470f66f451Sopenharmony_ci    }
1480f66f451Sopenharmony_ci  }
1490f66f451Sopenharmony_ci
1500f66f451Sopenharmony_ci  if (!CFG_TOYBOX_LSM_NONE) {
1510f66f451Sopenharmony_ci    if (lsm_enabled()) {
1520f66f451Sopenharmony_ci      char *context = lsm_context();
1530f66f451Sopenharmony_ci
1540f66f451Sopenharmony_ci      printf(" context=%s"+!!(toys.optflags&FLAG_Z), context);
1550f66f451Sopenharmony_ci      if (CFG_TOYBOX_FREE) free(context);
1560f66f451Sopenharmony_ci    } else if (toys.optflags&FLAG_Z) error_exit("%s disabled", lsm_name());
1570f66f451Sopenharmony_ci  }
1580f66f451Sopenharmony_ci
1590f66f451Sopenharmony_ci  xputc('\n');
1600f66f451Sopenharmony_ci}
1610f66f451Sopenharmony_ci
1620f66f451Sopenharmony_civoid id_main(void)
1630f66f451Sopenharmony_ci{
1640f66f451Sopenharmony_ci  if (toys.optc) while(*toys.optargs) do_id(*toys.optargs++);
1650f66f451Sopenharmony_ci  else do_id(NULL);
1660f66f451Sopenharmony_ci}
1670f66f451Sopenharmony_ci
1680f66f451Sopenharmony_civoid groups_main(void)
1690f66f451Sopenharmony_ci{
1700f66f451Sopenharmony_ci  TT.is_groups = 1;
1710f66f451Sopenharmony_ci  toys.optflags = FLAG_G|FLAG_n;
1720f66f451Sopenharmony_ci  id_main();
1730f66f451Sopenharmony_ci}
1740f66f451Sopenharmony_ci
1750f66f451Sopenharmony_civoid logname_main(void)
1760f66f451Sopenharmony_ci{
1770f66f451Sopenharmony_ci  toys.optflags = FLAG_u|FLAG_n;
1780f66f451Sopenharmony_ci  id_main();
1790f66f451Sopenharmony_ci}
180