瀏覽代碼

LibCore: Add query for all accounts and groups

ne0ndrag0n 2 年之前
父節點
當前提交
9ddb86f7db

+ 40 - 0
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.

+ 1 - 0
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;

+ 23 - 0
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)

+ 2 - 0
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 = {});