summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibCore
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibCore')
-rw-r--r--Userland/Libraries/LibCore/Account.cpp40
-rw-r--r--Userland/Libraries/LibCore/Account.h1
-rw-r--r--Userland/Libraries/LibCore/Group.cpp23
-rw-r--r--Userland/Libraries/LibCore/Group.h2
4 files changed, 66 insertions, 0 deletions
diff --git a/Userland/Libraries/LibCore/Account.cpp b/Userland/Libraries/LibCore/Account.cpp
index a88e63b5bd..c9d27ce53f 100644
--- a/Userland/Libraries/LibCore/Account.cpp
+++ b/Userland/Libraries/LibCore/Account.cpp
@@ -125,6 +125,46 @@ ErrorOr<Account> Account::from_uid(uid_t uid, [[maybe_unused]] Read options)
return from_passwd(*pwd, spwd);
}
+ErrorOr<Vector<Account>> Account::all([[maybe_unused]] Read options)
+{
+ Vector<Account> accounts;
+
+#ifndef AK_OS_MACOS
+ struct passwd pwd;
+ struct passwd* ptr = nullptr;
+ char buffer[1024] = { 0 };
+#endif
+
+ ScopeGuard pwent_guard([] { endpwent(); });
+ setpwent();
+ errno = 0;
+
+#ifndef AK_OS_MACOS
+ while (getpwent_r(&pwd, buffer, sizeof(buffer), &ptr) == 0 && ptr) {
+#else
+ while (auto const* ptr = getpwent()) {
+#endif
+ spwd spwd = {};
+
+#ifndef AK_OS_BSD_GENERIC
+ ScopeGuard spent_guard([] { endspent(); });
+ if (options != Read::PasswdOnly) {
+ auto maybe_spwd = TRY(Core::System::getspnam({ ptr->pw_name, strlen(ptr->pw_name) }));
+ if (!maybe_spwd.has_value())
+ return Error::from_string_literal("No shadow entry for user");
+ spwd = maybe_spwd.release_value();
+ }
+#endif
+
+ accounts.append({ *ptr, spwd, get_extra_gids(*ptr) });
+ }
+
+ if (errno)
+ return Error::from_errno(errno);
+
+ return accounts;
+}
+
bool Account::authenticate(SecretString const& password) const
{
// If there was no shadow entry for this account, authentication always fails.
diff --git a/Userland/Libraries/LibCore/Account.h b/Userland/Libraries/LibCore/Account.h
index 9141282c58..397fad28e8 100644
--- a/Userland/Libraries/LibCore/Account.h
+++ b/Userland/Libraries/LibCore/Account.h
@@ -35,6 +35,7 @@ public:
static ErrorOr<Account> self(Read options = Read::All);
static ErrorOr<Account> from_name(StringView username, Read options = Read::All);
static ErrorOr<Account> from_uid(uid_t uid, Read options = Read::All);
+ static ErrorOr<Vector<Account>> all(Read options = Read::All);
bool authenticate(SecretString const& password) const;
ErrorOr<void> login() const;
diff --git a/Userland/Libraries/LibCore/Group.cpp b/Userland/Libraries/LibCore/Group.cpp
index e38aace24e..e97d1eaf2e 100644
--- a/Userland/Libraries/LibCore/Group.cpp
+++ b/Userland/Libraries/LibCore/Group.cpp
@@ -6,8 +6,10 @@
#include <AK/CharacterTypes.h>
#include <AK/ScopeGuard.h>
+#include <LibCore/File.h>
#include <LibCore/Group.h>
#include <LibCore/System.h>
+#include <errno.h>
namespace Core {
@@ -60,6 +62,27 @@ ErrorOr<void> Group::add_group(Group& group)
}
#endif
+ErrorOr<Vector<Group>> Group::all()
+{
+ Vector<Group> groups;
+
+ ScopeGuard grent_guard([] { endgrent(); });
+ setgrent();
+ errno = 0;
+ for (auto const* gr = getgrent(); gr; gr = getgrent()) {
+ Vector<String> members;
+ for (size_t i = 0; gr->gr_mem[i]; ++i)
+ members.append(*gr->gr_mem);
+
+ groups.append({ gr->gr_name, gr->gr_gid, members });
+ }
+
+ if (errno)
+ return Error::from_errno(errno);
+
+ return groups;
+}
+
Group::Group(String name, gid_t id, Vector<String> members)
: m_name(move(name))
, m_id(id)
diff --git a/Userland/Libraries/LibCore/Group.h b/Userland/Libraries/LibCore/Group.h
index 1e291e7a53..53dcf12d41 100644
--- a/Userland/Libraries/LibCore/Group.h
+++ b/Userland/Libraries/LibCore/Group.h
@@ -19,6 +19,8 @@ public:
static ErrorOr<void> add_group(Group& group);
#endif
+ static ErrorOr<Vector<Group>> all();
+
Group() = default;
Group(String name, gid_t id = 0, Vector<String> members = {});