mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:27:45 +00:00
SystemServer: Port to Core::Account
We now have a handy Core::Account class that we can use instead of iterating over the passwd database ourselves.
This commit is contained in:
parent
7babe5ade6
commit
95157f8b81
2 changed files with 21 additions and 49 deletions
|
@ -40,43 +40,8 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
struct UidAndGids {
|
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
Vector<gid_t> extra_gids;
|
|
||||||
};
|
|
||||||
|
|
||||||
static HashMap<String, UidAndGids>* s_user_map;
|
|
||||||
static HashMap<pid_t, Service*> s_service_map;
|
static HashMap<pid_t, Service*> s_service_map;
|
||||||
|
|
||||||
void Service::resolve_user()
|
|
||||||
{
|
|
||||||
if (s_user_map == nullptr) {
|
|
||||||
s_user_map = new HashMap<String, UidAndGids>;
|
|
||||||
for (struct passwd* passwd = getpwent(); passwd; passwd = getpwent()) {
|
|
||||||
Vector<gid_t> extra_gids;
|
|
||||||
for (struct group* group = getgrent(); group; group = getgrent()) {
|
|
||||||
for (size_t m = 0; group->gr_mem[m]; ++m) {
|
|
||||||
if (!strcmp(group->gr_mem[m], passwd->pw_name))
|
|
||||||
extra_gids.append(group->gr_gid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endgrent();
|
|
||||||
s_user_map->set(passwd->pw_name, { passwd->pw_uid, passwd->pw_gid, move(extra_gids) });
|
|
||||||
}
|
|
||||||
endpwent();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto user = s_user_map->get(m_user);
|
|
||||||
if (!user.has_value()) {
|
|
||||||
dbg() << "Failed to resolve user name " << m_user;
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
m_uid = user.value().uid;
|
|
||||||
m_gid = user.value().gid;
|
|
||||||
m_extra_gids = user.value().extra_gids;
|
|
||||||
}
|
|
||||||
|
|
||||||
Service* Service::find_by_pid(pid_t pid)
|
Service* Service::find_by_pid(pid_t pid)
|
||||||
{
|
{
|
||||||
auto it = s_service_map.find(pid);
|
auto it = s_service_map.find(pid);
|
||||||
|
@ -102,9 +67,12 @@ void Service::setup_socket()
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fchown(m_socket_fd, m_uid, m_gid) < 0) {
|
if (m_account.has_value()) {
|
||||||
perror("fchown");
|
auto& account = m_account.value();
|
||||||
ASSERT_NOT_REACHED();
|
if (fchown(m_socket_fd, account.uid(), account.gid()) < 0) {
|
||||||
|
perror("fchown");
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fchmod(m_socket_fd, m_socket_permissions) < 0) {
|
if (fchmod(m_socket_fd, m_socket_permissions) < 0) {
|
||||||
|
@ -240,9 +208,10 @@ void Service::spawn(int socket_fd)
|
||||||
setenv("SOCKET_TAKEOVER", "1", true);
|
setenv("SOCKET_TAKEOVER", "1", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_user.is_null()) {
|
if (m_account.has_value()) {
|
||||||
if (setgid(m_gid) < 0 || setgroups(m_extra_gids.size(), m_extra_gids.data()) < 0 || setuid(m_uid) < 0) {
|
auto& account = m_account.value();
|
||||||
dbgprintf("Failed to drop privileges (GID=%u, UID=%u)\n", m_gid, m_uid);
|
if (setgid(account.gid()) < 0 || setgroups(account.extra_gids().size(), account.extra_gids().data()) < 0 || setuid(account.uid()) < 0) {
|
||||||
|
dbgprintf("Failed to drop privileges (GID=%u, UID=%u)\n", account.gid(), account.uid());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,8 +293,13 @@ Service::Service(const Core::ConfigFile& config, const StringView& name)
|
||||||
m_lazy = config.read_bool_entry(name, "Lazy");
|
m_lazy = config.read_bool_entry(name, "Lazy");
|
||||||
|
|
||||||
m_user = config.read_entry(name, "User");
|
m_user = config.read_entry(name, "User");
|
||||||
if (!m_user.is_null())
|
if (!m_user.is_null()) {
|
||||||
resolve_user();
|
auto result = Core::Account::from_name(m_user.characters());
|
||||||
|
if (result.is_error())
|
||||||
|
warnln("Failed to resolve user {}: {}", m_user, result.error());
|
||||||
|
else
|
||||||
|
m_account = result.value();
|
||||||
|
}
|
||||||
|
|
||||||
m_working_directory = config.read_entry(name, "WorkingDirectory");
|
m_working_directory = config.read_entry(name, "WorkingDirectory");
|
||||||
m_environment = config.read_entry(name, "Environment").split(' ');
|
m_environment = config.read_entry(name, "Environment").split(' ');
|
||||||
|
@ -382,8 +356,6 @@ void Service::save_to(JsonObject& json)
|
||||||
json.set("socket_permissions", m_socket_permissions);
|
json.set("socket_permissions", m_socket_permissions);
|
||||||
json.set("lazy", m_lazy);
|
json.set("lazy", m_lazy);
|
||||||
json.set("user", m_user);
|
json.set("user", m_user);
|
||||||
json.set("uid", m_uid);
|
|
||||||
json.set("gid", m_gid);
|
|
||||||
json.set("multi_instance", m_multi_instance);
|
json.set("multi_instance", m_multi_instance);
|
||||||
json.set("accept_socket_connections", m_accept_socket_connections);
|
json.set("accept_socket_connections", m_accept_socket_connections);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <LibCore/Account.h>
|
||||||
#include <LibCore/ElapsedTimer.h>
|
#include <LibCore/ElapsedTimer.h>
|
||||||
#include <LibCore/Notifier.h>
|
#include <LibCore/Notifier.h>
|
||||||
#include <LibCore/Object.h>
|
#include <LibCore/Object.h>
|
||||||
|
@ -71,9 +72,6 @@ private:
|
||||||
bool m_lazy;
|
bool m_lazy;
|
||||||
// The name of the user we should run this service as.
|
// The name of the user we should run this service as.
|
||||||
String m_user;
|
String m_user;
|
||||||
uid_t m_uid { 0 };
|
|
||||||
gid_t m_gid { 0 };
|
|
||||||
Vector<gid_t> m_extra_gids;
|
|
||||||
// The working directory in which to spawn the service.
|
// The working directory in which to spawn the service.
|
||||||
String m_working_directory;
|
String m_working_directory;
|
||||||
// Boot modes to run this service in. By default, this is the graphical mode.
|
// Boot modes to run this service in. By default, this is the graphical mode.
|
||||||
|
@ -83,6 +81,9 @@ private:
|
||||||
// Environment variables to pass to the service.
|
// Environment variables to pass to the service.
|
||||||
Vector<String> m_environment;
|
Vector<String> m_environment;
|
||||||
|
|
||||||
|
// The resolved user account to run this service as.
|
||||||
|
Optional<Core::Account> m_account;
|
||||||
|
|
||||||
// For single-instance services, PID of the running instance of this service.
|
// For single-instance services, PID of the running instance of this service.
|
||||||
pid_t m_pid { -1 };
|
pid_t m_pid { -1 };
|
||||||
// An open fd to the socket.
|
// An open fd to the socket.
|
||||||
|
@ -95,7 +96,6 @@ private:
|
||||||
// times where it has exited unsuccessfully and too quickly.
|
// times where it has exited unsuccessfully and too quickly.
|
||||||
int m_restart_attempts { 0 };
|
int m_restart_attempts { 0 };
|
||||||
|
|
||||||
void resolve_user();
|
|
||||||
void setup_socket();
|
void setup_socket();
|
||||||
void setup_notifier();
|
void setup_notifier();
|
||||||
void handle_socket_connection();
|
void handle_socket_connection();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue