Skip to content

Commit 580b335

Browse files
setepenrelinusg
authored andcommitted
Userland: Add groups program
1 parent 5601037 commit 580b335

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

Userland/Utilities/groups.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright (c) 2021, the SerenityOS developers.
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <AK/Vector.h>
8+
#include <LibCore/Account.h>
9+
#include <LibCore/ArgsParser.h>
10+
#include <grp.h>
11+
#include <unistd.h>
12+
13+
static void print_account_gids(const Core::Account& account)
14+
{
15+
auto* gr = getgrgid(account.gid());
16+
if (!gr) {
17+
outln();
18+
return;
19+
}
20+
21+
out("{}", gr->gr_name);
22+
for (auto& gid : account.extra_gids()) {
23+
gr = getgrgid(gid);
24+
out(" {}", gr->gr_name);
25+
}
26+
outln();
27+
}
28+
29+
int main(int argc, char** argv)
30+
{
31+
if (unveil("/etc/passwd", "r") < 0) {
32+
perror("unveil");
33+
return 1;
34+
}
35+
36+
if (unveil("/etc/shadow", "r") < 0) {
37+
perror("unveil");
38+
return 1;
39+
}
40+
41+
if (unveil("/etc/group", "r") < 0) {
42+
perror("unveil");
43+
return 1;
44+
}
45+
46+
if (unveil(nullptr, nullptr) < 0) {
47+
perror("unveil");
48+
return 1;
49+
}
50+
51+
if (pledge("stdio rpath", nullptr) < 0) {
52+
perror("pledge");
53+
return 1;
54+
}
55+
56+
Vector<const char*> usernames;
57+
58+
Core::ArgsParser args_parser;
59+
args_parser.set_general_help("Print group memberships for each username or, if no username is specified, for the current process.");
60+
args_parser.add_positional_argument(usernames, "Usernames to list group memberships for", "usernames", Core::ArgsParser::Required::No);
61+
args_parser.parse(argc, argv);
62+
63+
if (usernames.is_empty()) {
64+
auto result = Core::Account::from_uid(geteuid());
65+
if (result.is_error()) {
66+
warnln("{}", result.error());
67+
return 1;
68+
}
69+
print_account_gids(result.value());
70+
}
71+
72+
for (auto username : usernames) {
73+
auto result = Core::Account::from_name(username);
74+
if (result.is_error()) {
75+
warnln("{} '{}'", result.error(), username);
76+
continue;
77+
}
78+
out("{} : ", username);
79+
print_account_gids(result.value());
80+
}
81+
return 0;
82+
}

0 commit comments

Comments
 (0)