init: Support starting services as a separate user
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
cfb60fad25
commit
ba3e32917e
@ -9,6 +9,7 @@
|
|||||||
#include <os/File.h>
|
#include <os/File.h>
|
||||||
#include <os/Process.h>
|
#include <os/Process.h>
|
||||||
#include <os/Security.h>
|
#include <os/Security.h>
|
||||||
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -19,6 +20,8 @@
|
|||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static bool g_is_system = false;
|
||||||
|
|
||||||
FILE* g_init_log = nullptr;
|
FILE* g_init_log = nullptr;
|
||||||
|
|
||||||
// Request a successful exit from the system (for tests)
|
// Request a successful exit from the system (for tests)
|
||||||
@ -42,6 +45,8 @@ struct Service
|
|||||||
String standard_output;
|
String standard_output;
|
||||||
String standard_error;
|
String standard_error;
|
||||||
String standard_input;
|
String standard_input;
|
||||||
|
Option<uid_t> user {};
|
||||||
|
Option<gid_t> group {};
|
||||||
bool wait { false };
|
bool wait { false };
|
||||||
Option<pid_t> pid {};
|
Option<pid_t> pid {};
|
||||||
};
|
};
|
||||||
@ -67,6 +72,12 @@ static Result<void> service_child(const Service& service, SharedPtr<os::File> ou
|
|||||||
if (error) dup2(error->fd(), STDERR_FILENO);
|
if (error) dup2(error->fd(), STDERR_FILENO);
|
||||||
if (input) dup2(input->fd(), STDIN_FILENO);
|
if (input) dup2(input->fd(), STDIN_FILENO);
|
||||||
|
|
||||||
|
if (service.user.has_value())
|
||||||
|
{
|
||||||
|
setgid(service.group.value());
|
||||||
|
setuid(service.user.value());
|
||||||
|
}
|
||||||
|
|
||||||
if (service.environment.is_empty()) { TRY(os::Process::exec(args[0].view(), args.slice(), false)); }
|
if (service.environment.is_empty()) { TRY(os::Process::exec(args[0].view(), args.slice(), false)); }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -216,6 +227,15 @@ static Result<void> load_service(const os::Path& path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_is_system && parts[0].view() == "User")
|
||||||
|
{
|
||||||
|
auto* pw = getpwnam(parts[1].chars());
|
||||||
|
if (!pw) continue;
|
||||||
|
service.user = pw->pw_uid;
|
||||||
|
service.group = pw->pw_gid;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (parts[0].view() == "Wait")
|
if (parts[0].view() == "Wait")
|
||||||
{
|
{
|
||||||
if (parts[1].view() == "true" || parts[1].view().to_uint().value_or(0) == 1)
|
if (parts[1].view() == "true" || parts[1].view().to_uint().value_or(0) == 1)
|
||||||
@ -311,6 +331,8 @@ Result<int> sysinit()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_is_system = true;
|
||||||
|
|
||||||
// Before this point, we don't even have an stdin, stdout and stderr. Set it up now so that child processes (and us)
|
// Before this point, we don't even have an stdin, stdout and stderr. Set it up now so that child processes (and us)
|
||||||
// can print stuff.
|
// can print stuff.
|
||||||
stdin = fopen("/dev/console", "r");
|
stdin = fopen("/dev/console", "r");
|
||||||
|
Loading…
Reference in New Issue
Block a user