aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-11-02 22:58:42 -0700
committerRob Landley <rob@landley.net>2019-11-03 19:20:31 -0600
commit126c317d5ceee7802d52fc6be1b695f759aa6725 (patch)
tree6e7e0e35dcf9171b5eb34aa2c9e6fa3e6c9c772b
parent3ead70e503b2809a250a70d161d525213f5328d8 (diff)
downloadtoybox-126c317d5ceee7802d52fc6be1b695f759aa6725.tar.gz
id: support numeric lookup.
Fall back to converting the "name" to an integer and calling getpwuid(). We need to update `username` for the later call to getgrouplist(). Also fix the separator printing logic to avoid a trailing ',' on `id 0`. Switch to FLAG() and move some declarations down to where they can be initialized, both for clarity. Also add simple tests. Sadly, there's no always-present user that is in multiple groups.
-rwxr-xr-xtests/id.test10
-rw-r--r--toys/posix/id.c49
2 files changed, 36 insertions, 23 deletions
diff --git a/tests/id.test b/tests/id.test
new file mode 100755
index 00000000..6d0f63a8
--- /dev/null
+++ b/tests/id.test
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+[ -f testing.sh ] && . testing.sh
+
+#testing "name" "command" "result" "infile" "stdin"
+
+testing "id 0" "id 0" "uid=0(root) gid=0(root) groups=0(root)\n" "" ""
+testing "id root" "id root" "uid=0(root) gid=0(root) groups=0(root)\n" "" ""
+testing "id no-such-user" "id no-such-user 2>/dev/null ; echo \$?" "1\n" "" ""
+testing "id 9999999" "id 9999999 2>/dev/null ; echo \$?" "1\n" "" ""
diff --git a/toys/posix/id.c b/toys/posix/id.c
index db3cc317..b3be1e6e 100644
--- a/toys/posix/id.c
+++ b/toys/posix/id.c
@@ -65,11 +65,13 @@ config WHOAMI
GLOBALS(
int is_groups;
+ int separator;
)
static void s_or_u(char *s, unsigned u, int done)
{
- if (toys.optflags&FLAG_n) printf("%s", s);
+ if (TT.separator) xputc(TT.separator);
+ if (FLAG(n)) printf("%s", s);
else printf("%u", u);
if (done) {
xputc('\n');
@@ -79,39 +81,41 @@ static void s_or_u(char *s, unsigned u, int done)
static void showid(char *header, unsigned u, char *s)
{
+ if (TT.separator) xputc(TT.separator);
printf("%s%u(%s)", header, u, s);
}
static void do_id(char *username)
{
- int flags, i, ngroups;
struct passwd *pw;
struct group *grp;
uid_t uid = getuid(), euid = geteuid();
- gid_t gid = getgid(), egid = getegid(), *groups;
-
- flags = toys.optflags;
+ gid_t gid = getgid(), egid = getegid();
// check if a username is given
if (username) {
- pw = xgetpwnam(username);
+ pw = getpwnam(username);
+ if (!pw) {
+ uid = atolx_range(username, 0, INT_MAX);
+ if ((pw = getpwuid(uid))) username = pw->pw_name;
+ }
+ if (!pw) perror_exit("no such user '%s'", username);
uid = euid = pw->pw_uid;
gid = egid = pw->pw_gid;
if (TT.is_groups) printf("%s : ", pw->pw_name);
}
- i = flags & FLAG_r;
- pw = xgetpwuid(i ? uid : euid);
- if (toys.optflags&FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1);
+ pw = xgetpwuid(FLAG(r) ? uid : euid);
+ if (FLAG(u)) s_or_u(pw->pw_name, pw->pw_uid, 1);
- grp = xgetgrgid(i ? gid : egid);
- if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);
+ grp = xgetgrgid(FLAG(r) ? gid : egid);
+ if (FLAG(g)) s_or_u(grp->gr_name, grp->gr_gid, 1);
if (!(toys.optflags&(FLAG_G|FLAG_g|FLAG_Z))) {
showid("uid=", pw->pw_uid, pw->pw_name);
showid(" gid=", grp->gr_gid, grp->gr_name);
- if (!i) {
+ if (!FLAG(r)) {
if (uid != euid) {
pw = xgetpwuid(euid);
showid(" euid=", pw->pw_uid, pw->pw_name);
@@ -125,23 +129,22 @@ static void do_id(char *username)
showid(" groups=", grp->gr_gid, grp->gr_name);
}
- if (!(toys.optflags&FLAG_Z)) {
- groups = (gid_t *)toybuf;
- i = sizeof(toybuf)/sizeof(gid_t);
+ if (!FLAG(Z)) {
+ gid_t *groups = (gid_t *)toybuf;
+ int i = sizeof(toybuf)/sizeof(gid_t), ngroups;
+
ngroups = username ? getgrouplist(username, gid, groups, &i)
: getgroups(i, groups);
if (ngroups<0) perror_exit(0);
- int show_separator = !(toys.optflags&FLAG_G);
for (i = 0; i<ngroups; i++) {
- if (show_separator) xputc((toys.optflags&FLAG_G) ? ' ' : ',');
- show_separator = 1;
+ TT.separator = FLAG(G) ? ' ' : ',';
if (!(grp = getgrgid(groups[i]))) perror_msg(0);
- else if (toys.optflags&FLAG_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
+ else if (FLAG(G)) s_or_u(grp->gr_name, grp->gr_gid, 0);
else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
- else show_separator = 0; // Because we didn't show anything this time.
+ else TT.separator = 0; // Because we didn't show anything this time.
}
- if (toys.optflags&FLAG_G) {
+ if (FLAG(G)) {
xputc('\n');
xexit();
}
@@ -151,9 +154,9 @@ static void do_id(char *username)
if (lsm_enabled()) {
char *context = lsm_context();
- printf(" context=%s"+!!(toys.optflags&FLAG_Z), context);
+ printf(" context=%s"+!!FLAG(Z), context);
if (CFG_TOYBOX_FREE) free(context);
- } else if (toys.optflags&FLAG_Z) error_exit("%s disabled", lsm_name());
+ } else if (FLAG(Z)) error_exit("%s disabled", lsm_name());
}
xputc('\n');