From 09787dbf2742d44d9dda4172abaa24f10db1cc57 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Mon, 19 Jun 2023 07:09:55 +0100 Subject: [PATCH] groupadd: Add `-U` option for adding members to a new group --- Base/usr/share/man/man8/groupadd.md | 1 + Userland/Utilities/groupadd.cpp | 35 ++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Base/usr/share/man/man8/groupadd.md b/Base/usr/share/man/man8/groupadd.md index 8268cf62dc8..f644de449d9 100644 --- a/Base/usr/share/man/man8/groupadd.md +++ b/Base/usr/share/man/man8/groupadd.md @@ -17,6 +17,7 @@ This program must be run as root. ## Options * `-g`, `--gid` _gid_: The group identifier for the new group. If not specified, an unused GID above `100` will be auto-generated. +* `-U`, `--users` user-list: A comma-separated list of usernames to add as members of the new group ## Exit Values diff --git a/Userland/Utilities/groupadd.cpp b/Userland/Utilities/groupadd.cpp index fe7e76d39e3..c5a33d21d77 100644 --- a/Userland/Utilities/groupadd.cpp +++ b/Userland/Utilities/groupadd.cpp @@ -3,10 +3,13 @@ * Copyright (c) 2021, Brandon Pruitt * Copyright (c) 2021, Maxime Friess * Copyright (c) 2022, Kenneth Myhra + * Copyright (c) 2023, Tim Ledbetter * * SPDX-License-Identifier: BSD-2-Clause */ +#include +#include #include #include #include @@ -18,13 +21,43 @@ ErrorOr serenity_main(Main::Arguments arguments) gid_t gid = 0; StringView group_name; + Vector group_members; Core::ArgsParser args_parser; args_parser.add_option(gid, "Group ID (gid) for the new group", "gid", 'g', "gid"); + args_parser.add_option(Core::ArgsParser::Option { + .argument_mode = Core::ArgsParser::OptionArgumentMode::Required, + .help_string = "A comma-separated list of usernames to add as members of the new group", + .long_name = "users", + .short_name = 'U', + .value_name = "user-list", + .accept_value = [&group_members](StringView comma_separated_users) { + auto accounts_or_error = Core::Account::all(Core::Account::Read::PasswdOnly); + if (accounts_or_error.is_error()) + return false; + + OrderedHashTable unique_group_members; + auto accounts = accounts_or_error.release_value(); + for (auto const& username : comma_separated_users.split_view(',')) { + auto matching_account = accounts.first_matching([&](auto const& account) { return username == account.username(); }); + if (!matching_account.has_value()) { + warnln("Invalid member username: '{}'", username); + return false; + } + + unique_group_members.set(matching_account->username()); + } + + for (auto const& member : unique_group_members) + group_members.append(member); + + return true; + }, + }); args_parser.add_positional_argument(group_name, "Name of the group (groupname)", "group"); args_parser.parse(arguments); - auto group = Core::Group { group_name, gid }; + Core::Group group { group_name, gid, group_members }; TRY(Core::Group::add_group(group)); return 0;