mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 11:47:45 +00:00
LibCore: Sync groups, getgrent to getgrent_r, fix gr_mem bug
This commit is contained in:
parent
8a09895bc1
commit
d8f25ad644
2 changed files with 70 additions and 1 deletions
|
@ -6,13 +6,71 @@
|
||||||
|
|
||||||
#include <AK/CharacterTypes.h>
|
#include <AK/CharacterTypes.h>
|
||||||
#include <AK/ScopeGuard.h>
|
#include <AK/ScopeGuard.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
#include <LibCore/Group.h>
|
#include <LibCore/Group.h>
|
||||||
#include <LibCore/System.h>
|
#include <LibCore/System.h>
|
||||||
|
#include <LibCore/UmaskScope.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace Core {
|
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)
|
#if !defined(AK_OS_BSD_GENERIC) && !defined(AK_OS_ANDROID)
|
||||||
ErrorOr<void> Group::add_group(Group& group)
|
ErrorOr<void> Group::add_group(Group& group)
|
||||||
{
|
{
|
||||||
|
@ -69,10 +127,17 @@ ErrorOr<Vector<Group>> Group::all()
|
||||||
ScopeGuard grent_guard([] { endgrent(); });
|
ScopeGuard grent_guard([] { endgrent(); });
|
||||||
setgrent();
|
setgrent();
|
||||||
errno = 0;
|
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()) {
|
for (auto const* gr = getgrent(); gr; gr = getgrent()) {
|
||||||
|
#endif
|
||||||
Vector<String> members;
|
Vector<String> members;
|
||||||
for (size_t i = 0; gr->gr_mem[i]; ++i)
|
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 });
|
groups.append({ gr->gr_name, gr->gr_gid, members });
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,15 @@ public:
|
||||||
|
|
||||||
Vector<String>& members() { return m_members; }
|
Vector<String>& members() { return m_members; }
|
||||||
|
|
||||||
|
ErrorOr<void> sync();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ErrorOr<bool> name_exists(StringView name);
|
static ErrorOr<bool> name_exists(StringView name);
|
||||||
static ErrorOr<bool> id_exists(gid_t id);
|
static ErrorOr<bool> id_exists(gid_t id);
|
||||||
ErrorOr<struct group> to_libc_group();
|
ErrorOr<struct group> to_libc_group();
|
||||||
|
|
||||||
|
ErrorOr<String> generate_group_file() const;
|
||||||
|
|
||||||
String m_name;
|
String m_name;
|
||||||
gid_t m_id { 0 };
|
gid_t m_id { 0 };
|
||||||
Vector<String> m_members;
|
Vector<String> m_members;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue