From e3ed7f76c543bcaf915931d92b05355778e899c5 Mon Sep 17 00:00:00 2001 From: Peter Elliott Date: Sat, 9 Oct 2021 23:30:50 -0600 Subject: [PATCH] LoginServer: Process logins and start SystemServer in user mode --- Base/etc/SystemServer.ini | 3 + Userland/Services/LoginServer/main.cpp | 101 +++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/Base/etc/SystemServer.ini b/Base/etc/SystemServer.ini index 425ac0e6bb..0796cb9190 100644 --- a/Base/etc/SystemServer.ini +++ b/Base/etc/SystemServer.ini @@ -166,3 +166,6 @@ KeepAlive=0 [SystemServer] Arguments=--user User=anon + +#[LoginServer] +#User=root diff --git a/Userland/Services/LoginServer/main.cpp b/Userland/Services/LoginServer/main.cpp index a7329568e9..42e93b7d9a 100644 --- a/Userland/Services/LoginServer/main.cpp +++ b/Userland/Services/LoginServer/main.cpp @@ -4,14 +4,115 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include +#include +#include +#include +#include + +static void child_process(Core::Account const& account) +{ + if (!account.login()) { + dbgln("failed to switch users: {}", strerror(errno)); + exit(1); + } + + setenv("HOME", account.home_directory().characters(), true); + pid_t rc = setsid(); + if (rc == -1) { + dbgln("failed to setsid: {}", strerror(errno)); + exit(1); + } + dbgln("login with sid={}", rc); + + execlp("/bin/SystemServer", "SystemServer", "--user", nullptr); + dbgln("failed to exec SystemServer --user: {}", strerror(errno)); + exit(127); +} + +static void login(Core::Account const& account, LoginWindow& window) +{ + pid_t pid = fork(); + if (pid == 0) + child_process(account); + + int wstatus; + pid_t rc = waitpid(pid, &wstatus, 0); + if (rc == -1) + dbgln("waitpid failed: {}", strerror(errno)); + if (rc != 0) + dbgln("SystemServer exited with non-zero status: {}", rc); + + window.show(); +} int main(int argc, char** argv) { auto app = GUI::Application::construct(argc, argv); + if (pledge("stdio recvfd sendfd rpath exec proc id", nullptr) < 0) { + perror("pledge"); + return 1; + } + + if (unveil("/home", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/etc/passwd", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/etc/shadow", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/etc/group", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/bin/SystemServer", "x") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/res", "r") < 0) { + perror("unveil"); + return 1; + } + + unveil(nullptr, nullptr); + auto window = LoginWindow::construct(); + window->on_submit = [&]() { + auto username = window->username(); + auto password = Core::SecretString::take_ownership(window->password().to_byte_buffer()); + + window->set_password(""); + + auto account = Core::Account::from_name(username.characters()); + if (account.is_error()) { + dbgln("failed graphical login for user {}: {}", username, account.error()); + return; + } + + if (!account.value().authenticate(password)) { + dbgln("failed graphical login for user {}: invalid password", username); + return; + } + + window->set_username(""); + window->hide(); + + login(account.value(), *window); + }; + window->show(); return app->exec();