Serenity Operating System
1/*
2 * Copyright (c) 2022, Ashley N. <dev-serenity@ne0ndrag0n.com>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include "EscalatorWindow.h"
9#include <AK/DeprecatedString.h>
10#include <LibCore/Account.h>
11#include <LibCore/ArgsParser.h>
12#include <LibCore/DeprecatedFile.h>
13#include <LibCore/System.h>
14#include <LibGUI/Application.h>
15#include <LibGUI/Desktop.h>
16#include <LibGUI/MessageBox.h>
17#include <LibMain/Main.h>
18
19ErrorOr<int> serenity_main(Main::Arguments arguments)
20{
21 Vector<StringView> command;
22 Core::ArgsParser args_parser;
23 StringView description;
24 bool preserve_env = false;
25 args_parser.set_general_help("Escalate privilege to root for a given command using a GUI prompt.");
26 args_parser.set_stop_on_first_non_option(true);
27 args_parser.add_option(description, "Custom prompt to use for dialog", "prompt", 'P', "prompt");
28 args_parser.add_option(preserve_env, "Preserve user environment when running command", "preserve-env", 'E');
29 args_parser.add_positional_argument(command, "Command to run at elevated privilege level", "command");
30 args_parser.parse(arguments);
31
32 TRY(Core::System::pledge("stdio recvfd sendfd thread cpath rpath wpath unix proc exec id"));
33
34 auto app = TRY(GUI::Application::try_create(arguments));
35
36 auto executable_path = Core::DeprecatedFile::resolve_executable_from_environment(command[0]);
37 if (!executable_path.has_value()) {
38 GUI::MessageBox::show_error(nullptr, DeprecatedString::formatted("Could not execute command {}: Command not found.", command[0]));
39 return 127;
40 }
41
42 auto current_user = TRY(Core::Account::self());
43 auto window = TRY(EscalatorWindow::try_create(executable_path.value(), command, EscalatorWindow::Options { description, current_user, preserve_env }));
44
45 if (current_user.uid() != 0) {
46 window->show();
47 return app->exec();
48 } else {
49 // Run directly as root if already root uid.
50 TRY(window->execute_command());
51 return 0;
52 }
53}