mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 04:38:11 +00:00
SystemServer: Fetch any extra GIDs and call setgroups() before spawn
We now pick up all the user's extra GIDs from /etc/group and make sure those are set before exec'ing a service. This means we finally get to enjoy being in more than one group. :^)
This commit is contained in:
parent
b4b8b8850a
commit
c2b7c43f3c
3 changed files with 20 additions and 7 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <LibCore/CConfigFile.h>
|
||||
#include <LibCore/CLocalSocket.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <libgen.h>
|
||||
#include <pwd.h>
|
||||
#include <sched.h>
|
||||
|
@ -13,20 +14,30 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct UidAndGid {
|
||||
struct UidAndGids {
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
Vector<gid_t> extra_gids;
|
||||
};
|
||||
|
||||
static HashMap<String, UidAndGid>* s_user_map;
|
||||
static HashMap<String, UidAndGids>* s_user_map;
|
||||
static HashMap<pid_t, Service*> s_service_map;
|
||||
|
||||
void Service::resolve_user()
|
||||
{
|
||||
if (s_user_map == nullptr) {
|
||||
s_user_map = new HashMap<String, UidAndGid>;
|
||||
for (struct passwd* passwd = getpwent(); passwd; passwd = getpwent())
|
||||
s_user_map->set(passwd->pw_name, { passwd->pw_uid, passwd->pw_gid });
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -37,6 +48,7 @@ void Service::resolve_user()
|
|||
}
|
||||
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)
|
||||
|
@ -189,7 +201,7 @@ void Service::spawn()
|
|||
}
|
||||
|
||||
if (!m_user.is_null()) {
|
||||
if (setgid(m_gid) < 0 || setuid(m_uid) < 0) {
|
||||
if (setgid(m_gid) < 0 || setgroups(m_extra_gids.size(), m_extra_gids.data()) < 0 || setuid(m_uid) < 0) {
|
||||
dbgprintf("Failed to drop privileges (GID=%u, UID=%u)\n", m_gid, m_uid);
|
||||
exit(1);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue