]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
homectl: port has_regular_user() + acquire_group_list() to use server-side filtering
authorLennart Poettering <lennart@poettering.net>
Wed, 22 Jan 2025 15:53:01 +0000 (16:53 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 27 Jan 2025 22:51:57 +0000 (23:51 +0100)
src/home/homectl.c

index fa91e55c75d6a40711b4f58b07f5a5f8ed2441d8..724925553d84a98b48a05c25f25742bd88716e8e 100644 (file)
@@ -5,6 +5,7 @@
 #include "sd-bus.h"
 
 #include "ask-password-api.h"
+#include "bitfield.h"
 #include "build.h"
 #include "bus-common-errors.h"
 #include "bus-error.h"
@@ -2403,36 +2404,35 @@ static int create_from_credentials(void) {
 
 static int has_regular_user(void) {
         _cleanup_(userdb_iterator_freep) UserDBIterator *iterator = NULL;
+        UserDBMatch match = USERDB_MATCH_NULL;
         int r;
 
-        r = userdb_all(/* match= */ NULL, USERDB_SUPPRESS_SHADOW, &iterator);
+        match.disposition_mask = INDEX_TO_MASK(uint64_t, USER_REGULAR);
+
+        r = userdb_all(&match, USERDB_SUPPRESS_SHADOW, &iterator);
         if (r < 0)
                 return log_error_errno(r, "Failed to create user enumerator: %m");
 
-        for (;;) {
-                _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
-
-                r = userdb_iterator_get(iterator, /* match= */ NULL, &ur);
-                if (r == -ESRCH)
-                        break;
-                if (r < 0)
-                        return log_error_errno(r, "Failed to enumerate users: %m");
-
-                if (user_record_disposition(ur) == USER_REGULAR)
-                        return true;
-        }
+        r = userdb_iterator_get(iterator, &match, /* ret= */ NULL);
+        if (r == -ESRCH)
+                return false;
+        if (r < 0)
+                return log_error_errno(r, "Failed to enumerate users: %m");
 
-        return false;
+        return true;
 }
 
 static int acquire_group_list(char ***ret) {
         _cleanup_(userdb_iterator_freep) UserDBIterator *iterator = NULL;
         _cleanup_strv_free_ char **groups = NULL;
+        UserDBMatch match = USERDB_MATCH_NULL;
         int r;
 
         assert(ret);
 
-        r = groupdb_all(/* match= */ NULL, USERDB_SUPPRESS_SHADOW|USERDB_EXCLUDE_DYNAMIC_USER, &iterator);
+        match.disposition_mask = INDEXES_TO_MASK(uint64_t, USER_REGULAR, USER_SYSTEM);
+
+        r = groupdb_all(&match, USERDB_SUPPRESS_SHADOW, &iterator);
         if (r == -ENOLINK)
                 log_debug_errno(r, "No groups found. (Didn't check via Varlink.)");
         else if (r == -ESRCH)
@@ -2443,25 +2443,25 @@ static int acquire_group_list(char ***ret) {
                 for (;;) {
                         _cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
 
-                        r = groupdb_iterator_get(iterator, /* match= */ NULL, &gr);
+                        r = groupdb_iterator_get(iterator, &match, &gr);
                         if (r == -ESRCH)
                                 break;
                         if (r < 0)
                                 return log_debug_errno(r, "Failed acquire next group: %m");
 
-                        if (!IN_SET(group_record_disposition(gr), USER_REGULAR, USER_SYSTEM))
-                                continue;
-
                         if (group_record_disposition(gr) == USER_REGULAR) {
                                 _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
 
                                 /* Filter groups here that belong to a specific user, and are named like them */
 
-                                r = userdb_by_name(gr->group_name, /* match= */ NULL, USERDB_SUPPRESS_SHADOW|USERDB_EXCLUDE_DYNAMIC_USER, &ur);
+                                UserDBMatch user_match = USERDB_MATCH_NULL;
+                                user_match.disposition_mask = INDEX_TO_MASK(uint64_t, USER_REGULAR);
+
+                                r = userdb_by_name(gr->group_name, &user_match, USERDB_SUPPRESS_SHADOW, &ur);
                                 if (r < 0 && r != -ESRCH)
                                         return log_debug_errno(r, "Failed to check if matching user exists for group '%s': %m", gr->group_name);
 
-                                if (r >= 0 && ur->gid == gr->gid && user_record_disposition(ur) == USER_REGULAR)
+                                if (r >= 0 && ur->gid == gr->gid)
                                         continue;
                         }