Serenity Operating System
at master 60 lines 1.8 kB view raw
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 <LibCore/System.h> 11#include <LibMain/Main.h> 12#include <grp.h> 13#include <unistd.h> 14 15static void print_account_gids(Core::Account const& account) 16{ 17 auto* gr = getgrgid(account.gid()); 18 if (!gr) { 19 outln(); 20 return; 21 } 22 23 out("{}", gr->gr_name); 24 for (auto& gid : account.extra_gids()) { 25 gr = getgrgid(gid); 26 out(" {}", gr->gr_name); 27 } 28 outln(); 29} 30 31ErrorOr<int> serenity_main(Main::Arguments arguments) 32{ 33 TRY(Core::System::unveil("/etc/passwd", "r")); 34 TRY(Core::System::unveil("/etc/group", "r")); 35 TRY(Core::System::unveil(nullptr, nullptr)); 36 TRY(Core::System::pledge("stdio rpath")); 37 38 Vector<DeprecatedString> usernames; 39 40 Core::ArgsParser args_parser; 41 args_parser.set_general_help("Print group memberships for each username or, if no username is specified, for the current process."); 42 args_parser.add_positional_argument(usernames, "Usernames to list group memberships for", "usernames", Core::ArgsParser::Required::No); 43 args_parser.parse(arguments); 44 45 if (usernames.is_empty()) { 46 auto account = TRY(Core::Account::from_uid(geteuid(), Core::Account::Read::PasswdOnly)); 47 print_account_gids(account); 48 } 49 50 for (auto const& username : usernames) { 51 auto result = Core::Account::from_name(username, Core::Account::Read::PasswdOnly); 52 if (result.is_error()) { 53 warnln("{} '{}'", result.error(), username); 54 continue; 55 } 56 out("{} : ", username); 57 print_account_gids(result.value()); 58 } 59 return 0; 60}