commit: bd6c19ef913c397e39e091e201c0cef65f0e20bf
parent 25c0414efc8e2f0f9b0e88996136602e28365c6c
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sat, 12 Mar 2022 03:57:37 +0100
bin/id: Add support for -G
Diffstat:
M | bin/id.c | 74 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | test-bin/id | 11 | +++++++++++ |
2 files changed, 85 insertions(+), 0 deletions(-)
diff --git a/bin/id.c b/bin/id.c
@@ -16,6 +16,65 @@
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);
+ 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);
+ for(int i = 0; i < ngroups; i++)
+ {
+ if(name_flag)
+ {
+ struct group *lgr = getgrgid(groups[i]);
+ if(lgr == NULL)
+ {
+ goto failure;
+ }
+
+ int sep = ' ';
+ if(i == ngroups - 1)
+ {
+ sep = '\n';
+ }
+
+ int ret = printf("%s%c", lgr->gr_name, sep);
+ if(ret < 0)
+ {
+ goto failure;
+ }
+ }
+ else
+ {
+ int sep = ' ';
+ if(i == ngroups - 1)
+ {
+ sep = '\n';
+ }
+
+ int ret = printf("%u%c", groups[i], sep);
+ if(ret < 0)
+ {
+ goto failure;
+ }
+ }
+ }
+
+ free(groups);
+ return 0;
+
+failure:
+ free(groups);
+ return 1;
+}
+
+static int
list_groups(struct passwd *pw)
{
int ngroups = (int)sysconf(_SC_NGROUPS_MAX) + 1;
@@ -253,6 +312,21 @@ main(int argc, char *argv[])
struct passwd *epw = getpwuid(euid);
// can return NULL (ie. without /etc/passwd)
+ if(G_flag)
+ {
+ if(!real_flag)
+ {
+ pw = epw;
+ }
+
+ if(pw != NULL && simple_list_groups(pw) != 0)
+ {
+ goto failure;
+ }
+
+ return 0;
+ }
+
ret = print_uid("uid", pw, uid);
if(ret < 0)
{
diff --git a/test-bin/id b/test-bin/id
@@ -45,6 +45,16 @@ user_body() {
atf_check -o "inline:$(id -unr)\n" ../bin/id -unr
}
+atf_test_case groups
+groups_body() {
+ # sadly GNU coreutils' id(1) sorts it's grouplist
+
+ atf_check -o not-empty ../bin/id -G
+ atf_check -o not-empty ../bin/id -Gr
+ atf_check -o not-empty ../bin/id -Gn
+ atf_check -o not-empty ../bin/id -Gnr
+}
+
atf_test_case noetc
noetc_body() {
bwrap_args="--bind / / --bind /var/empty /etc"
@@ -80,6 +90,7 @@ atf_init_test_cases() {
atf_add_test_case names
atf_add_test_case group
atf_add_test_case user
+ atf_add_test_case groups
atf_add_test_case noetc
}