diff --git a/Base/usr/share/man/man1/su.md b/Base/usr/share/man/man1/su.md index f55f46821b..3cf14efe4f 100644 --- a/Base/usr/share/man/man1/su.md +++ b/Base/usr/share/man/man1/su.md @@ -5,7 +5,7 @@ su - switch to another user ## Synopsis ```sh -$ su +$ su [-] ``` ## Description @@ -14,6 +14,10 @@ $ su When called with no user-specified, `su` defaults to switch to the *root* user. Need to enter the password if the user switch to has one. +## Options: + +* `-`, `-l`, `--login`: Start the shell as it was a real login + ## Arguments * `user`: User to switch to (defaults to the user with UID 0) diff --git a/Userland/Utilities/su.cpp b/Userland/Utilities/su.cpp index b39a415fec..ba1ffadb0e 100644 --- a/Userland/Utilities/su.cpp +++ b/Userland/Utilities/su.cpp @@ -5,13 +5,11 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include #include #include #include #include -#include #include ErrorOr serenity_main(Main::Arguments arguments) @@ -21,18 +19,29 @@ ErrorOr serenity_main(Main::Arguments arguments) if (!TRY(Core::System::isatty(STDIN_FILENO))) return Error::from_string_literal("Standard input is not a terminal"); - StringView user; + StringView first_positional; + StringView second_positional; + bool simulate_login = false; Core::ArgsParser args_parser; - args_parser.add_positional_argument(user, "User to switch to (defaults to user with UID 0)", "user", Core::ArgsParser::Required::No); + args_parser.add_positional_argument(first_positional, "See --login", "-", Core::ArgsParser::Required::No); + args_parser.add_positional_argument(second_positional, "User to switch to (defaults to user with UID 0)", "user", Core::ArgsParser::Required::No); + args_parser.add_option(simulate_login, "Simulate login", "login", 'l'); args_parser.parse(arguments); + StringView user = first_positional; + + if (first_positional == '-') { + simulate_login = true; + user = second_positional; + } + if (geteuid() != 0) return Error::from_string_literal("Not running as root :("); auto account = TRY(user.is_empty() ? Core::Account::from_uid(0) : Core::Account::from_name(user)); - TRY(Core::System::pledge("stdio tty exec id")); + TRY(Core::System::pledge("stdio rpath tty exec id")); if (getuid() != 0 && account.has_password()) { auto password = TRY(Core::get_password()); @@ -40,13 +49,16 @@ ErrorOr serenity_main(Main::Arguments arguments) return Error::from_string_literal("Incorrect or disabled password."); } - TRY(Core::System::pledge("stdio exec id")); + TRY(Core::System::pledge("stdio rpath exec id")); if (!account.login()) { perror("Core::Account::login"); return 1; } + if (simulate_login) + TRY(Core::System::chdir(account.home_directory())); + TRY(Core::System::pledge("stdio exec")); TRY(Core::System::setenv("HOME"sv, account.home_directory(), true));