1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:07:35 +00:00

LibCore: Sync groups, getgrent to getgrent_r, fix gr_mem bug

This commit is contained in:
ne0ndrag0n 2022-11-12 19:42:27 -05:00 committed by Andreas Kling
parent 8a09895bc1
commit d8f25ad644
2 changed files with 70 additions and 1 deletions

View file

@ -6,13 +6,71 @@
#include <AK/CharacterTypes.h>
#include <AK/ScopeGuard.h>
#include <AK/StringBuilder.h>
#include <LibCore/File.h>
#include <LibCore/Group.h>
#include <LibCore/System.h>
#include <LibCore/UmaskScope.h>
#include <errno.h>
#include <unistd.h>
namespace Core {
ErrorOr<String> Group::generate_group_file() const
{
StringBuilder builder;
ScopeGuard grent_guard([] { endgrent(); });
setgrent();
errno = 0;
#ifndef AK_OS_MACOS
struct group group;
struct group* gr = nullptr;
char buffer[1024] = { 0 };
while (getgrent_r(&group, buffer, sizeof(buffer), &gr) == 0 && gr) {
#else
for (auto const* gr = getgrent(); gr; gr = getgrent()) {
#endif
if (gr->gr_name == m_name)
builder.appendff("{}:x:{}:{}\n", m_name, m_id, String::join(',', m_members));
else {
Vector<String> members;
for (size_t i = 0; gr->gr_mem[i]; ++i)
members.append(gr->gr_mem[i]);
builder.appendff("{}:x:{}:{}\n", gr->gr_name, gr->gr_gid, String::join(',', members));
}
}
if (errno)
return Error::from_errno(errno);
return builder.to_string();
}
ErrorOr<void> Group::sync()
{
Core::UmaskScope umask_scope(0777);
auto new_group_file_content = TRY(generate_group_file());
char new_group_name[] = "/etc/group.XXXXXX";
size_t new_group_name_length = strlen(new_group_name);
{
auto new_group_fd = TRY(Core::System::mkstemp({ new_group_name, new_group_name_length }));
ScopeGuard new_group_fd_guard([new_group_fd] { close(new_group_fd); });
TRY(Core::System::fchmod(new_group_fd, 0664));
auto nwritten = TRY(Core::System::write(new_group_fd, new_group_file_content.bytes()));
VERIFY(static_cast<size_t>(nwritten) == new_group_file_content.length());
}
TRY(Core::System::rename({ new_group_name, new_group_name_length }, "/etc/group"sv));
return {};
}
#if !defined(AK_OS_BSD_GENERIC) && !defined(AK_OS_ANDROID)
ErrorOr<void> Group::add_group(Group& group)
{
@ -69,10 +127,17 @@ ErrorOr<Vector<Group>> Group::all()
ScopeGuard grent_guard([] { endgrent(); });
setgrent();
errno = 0;
#ifndef AK_OS_MACOS
struct group group;
struct group* gr = nullptr;
char buffer[1024] = { 0 };
while (getgrent_r(&group, buffer, sizeof(buffer), &gr) == 0 && gr) {
#else
for (auto const* gr = getgrent(); gr; gr = getgrent()) {
#endif
Vector<String> members;
for (size_t i = 0; gr->gr_mem[i]; ++i)
members.append(*gr->gr_mem);
members.append(gr->gr_mem[i]);
groups.append({ gr->gr_name, gr->gr_gid, members });
}