commit: 6c7a8fea8f3ae32209167739cd144fd9084b0b73
parent 906c0af0ec4c4ba8dc4d68feea25e555c0ad6cc2
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 15 May 2022 16:24:09 +0200
bin/id: Get groups from runtime instead of /etc
Diffstat:
M | bin/id.c | 51 | ++++++++++++++++++++++++++++++++------------------- |
M | test-bin/id | 45 | ++++++++++++++++++++++----------------------- |
2 files changed, 54 insertions(+), 42 deletions(-)
diff --git a/bin/id.c b/bin/id.c
@@ -2,9 +2,8 @@
// Copyright 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
-#define _DEFAULT_SOURCE // for getgrouplist
-
-#include <grp.h> // getgrgid, getgrouplist
+#define _POSIX_C_SOURCE 200809L
+#include <grp.h> // getgrgid, getgroups
#include <pwd.h> // getpwuid
#include <stdbool.h> // bool
#include <stdio.h> // printf, perror
@@ -17,20 +16,19 @@ bool name_flag = false;
static int
simple_list_groups(struct passwd *pw)
{
- int ngroups = (int)sysconf(_SC_NGROUPS_MAX) + 1;
- gid_t *groups = malloc(sizeof(gid_t) * ngroups);
+ int ngroups_max = (int)sysconf(_SC_NGROUPS_MAX) + 1;
+ gid_t *groups = malloc(sizeof(gid_t) * ngroups_max);
if(groups == NULL)
{
perror("groups malloc");
return 1;
}
- // getgrouplist(3) BSD extension might not be in all Unixes
- int grls = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
+ int ngroups = getgroups(ngroups_max, groups);
- // note: FreeBSD returns 0 on success
- if(grls < 0)
+ if(ngroups < 0)
{
+ perror("getgroups");
goto failure;
}
@@ -83,18 +81,22 @@ failure:
static int
list_groups(struct passwd *pw)
{
- int ngroups = (int)sysconf(_SC_NGROUPS_MAX) + 1;
- gid_t *groups = malloc(sizeof(gid_t) * ngroups);
+ int ngroups_max = (int)sysconf(_SC_NGROUPS_MAX) + 1;
+ gid_t *groups = malloc(sizeof(gid_t) * ngroups_max);
if(groups == NULL)
{
perror("groups malloc");
return 1;
}
- // getgrouplist(3) BSD extension might not be in all Unixes
- int grls = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
- // note: FreeBSD returns 0 on success
- if(grls >= 0)
+ int ngroups = getgroups(ngroups_max, groups);
+
+ if(ngroups < 0)
+ {
+ perror("getgroups");
+ goto failure;
+ }
+ else
{
printf(" groups=");
@@ -312,13 +314,15 @@ main(int argc, char *argv[])
}
else
{
- if(gr != NULL)
+ if(gr == NULL || gr->gr_name == NULL)
{
- ret = printf("%s\n", gr->gr_name);
+ ret--;
+ fprintf(stderr, "id: cannot find name for group ID %u\n", gid);
+ printf("%u\n", gid);
}
else
{
- return 1;
+ ret = printf("%s\n", gr->gr_name);
}
}
@@ -343,7 +347,16 @@ main(int argc, char *argv[])
}
else
{
- ret = printf("%s\n", pw.pw_name);
+ if(pw.pw_name == NULL)
+ {
+ ret--;
+ fprintf(stderr, "id: cannot find name for user ID %u\n", uid);
+ printf("%u\n", uid);
+ }
+ else
+ {
+ ret = printf("%s\n", pw.pw_name);
+ }
}
if(ret < 0)
diff --git a/test-bin/id b/test-bin/id
@@ -64,20 +64,27 @@ noetc_body() {
set -f
- # shellcheck disable=SC2086
- atf_check -o "inline:uid=$(id -u) gid=$(id -g) groups=$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id
- # shellcheck disable=SC2086
- atf_check -o "inline:uid=$(id -ur) gid=$(id -gr) groups=$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -r
+ atf_check -o "inline:$(id -u)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -u
+ atf_check -s exit:1 -e "inline:id: cannot find name for user ID $(id -u)\n" -o "inline:$(id -u)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -un
- # shellcheck disable=SC2086
- atf_check -s exit:1 -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -n
- # shellcheck disable=SC2086
- atf_check -s exit:1 -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -nr
+ atf_check -o "inline:$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -g
+ atf_check -s exit:1 -e "inline:id: cannot find name for group ID $(id -g)\n" -o "inline:$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -gn
+}
+
+atf_test_case nopasswd
+nopasswd_body() {
+ bwrap_args="--bind / / --bind /dev/null /etc/passwd"
+
+ command -v "${BWRAP:-bwrap}" >/dev/null 2>/dev/null || atf_skip "${BWRAP:-bwrap} command not found"
+ [ -n "${NO_BWRAP}" ] && atf_skip "'NO_BWRAP' set"
+
+ set -f
+
+ atf_check -o "inline:$(id -u)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -u
+ atf_check -s exit:1 -e "inline:id: cannot find name for user ID $(id -u)\n" -o "inline:$(id -u)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -un
- # shellcheck disable=SC2086
atf_check -o "inline:$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -g
- # shellcheck disable=SC2086
- atf_check -o "inline:$(id -gr)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -gr
+ atf_check -o "inline:$(id -gn)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -gn
}
atf_test_case nogroup
@@ -89,20 +96,11 @@ nogroup_body() {
set -f
- # shellcheck disable=SC2086
- atf_check -o "inline:uid=$(id -u)($(id -un)) gid=$(id -g) groups=$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id
- # shellcheck disable=SC2086
- atf_check -o "inline:uid=$(id -ur)($(id -unr)) gid=$(id -gr) groups=$(id -gr)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id
-
- # shellcheck disable=SC2086
- atf_check -s exit:1 -o "inline:uid=$(id -un)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -n
- # shellcheck disable=SC2086
- atf_check -s exit:1 -o "inline:uid=$(id -unr)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -nr
+ atf_check -o "inline:$(id -u)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -u
+ atf_check -o "inline:$(id -un)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -un
- # shellcheck disable=SC2086
atf_check -o "inline:$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -g
- # shellcheck disable=SC2086
- atf_check -o "inline:$(id -gr)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -gr
+ atf_check -s exit:1 -e "inline:id: cannot find name for group ID $(id -g)\n" -o "inline:$(id -g)\n" -- "${BWRAP:-bwrap}" ${bwrap_args} ../bin/id -gn
}
atf_test_case badarg
@@ -135,6 +133,7 @@ atf_init_test_cases() {
atf_add_test_case noetc
atf_add_test_case nogroup
+ atf_add_test_case nopasswd
atf_add_test_case root
}