diff options
-rw-r--r-- | Userland/Libraries/LibCore/Account.cpp | 40 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/Account.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/Group.cpp | 23 | ||||
-rw-r--r-- | Userland/Libraries/LibCore/Group.h | 2 |
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 = {}); |