]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
user-record: add helper that checks if a provided user name matches a record
authorLennart Poettering <lennart@poettering.net>
Fri, 3 Jan 2025 16:53:33 +0000 (17:53 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 21 Jan 2025 08:58:29 +0000 (09:58 +0100)
This ensures that user names can be specified either in the regular
short syntax or with a realm appended, and both are accepted. (The
latter of course only if the record actually defines a realm)

src/home/homed-varlink.c
src/home/pam_systemd_home.c
src/login/pam_systemd.c
src/shared/group-record.c
src/shared/group-record.h
src/shared/user-record.c
src/shared/user-record.h
src/shared/userdb-dropin.c
src/userdb/userwork.c

index f6dd27594f55244213755f8ff48bb7232812ab1d..cfd46ea51a6131eb6a7254c456cf4476020af294 100644 (file)
@@ -62,7 +62,7 @@ static bool home_user_match_lookup_parameters(LookupParameters *p, Home *h) {
         assert(p);
         assert(h);
 
-        if (p->user_name && !streq(p->user_name, h->user_name))
+        if (p->user_name && !user_record_matches_user_name(h->record, p->user_name))
                 return false;
 
         if (uid_is_valid(p->uid) && h->uid != p->uid)
@@ -175,7 +175,7 @@ static bool home_group_match_lookup_parameters(LookupParameters *p, Home *h) {
         assert(p);
         assert(h);
 
-        if (p->group_name && !streq(h->user_name, p->group_name))
+        if (p->group_name && !user_record_matches_user_name(h->record, p->group_name))
                 return false;
 
         if (gid_is_valid(p->gid) && h->uid != (uid_t) p->gid)
index 0d28e99ba2320453f8c61aa711cd91a510199628..fb61105295c9b7020f2b4c512c52b20dc553d42c 100644 (file)
@@ -220,7 +220,7 @@ static int acquire_user_record(
                 return pam_syslog_errno(handle, LOG_ERR, r, "Failed to load user record: %m");
 
         /* Safety check if cached record actually matches what we are looking for */
-        if (!streq_ptr(username, ur->user_name))
+        if (!user_record_matches_user_name(ur, username))
                 return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR,
                                             "Acquired user record does not match user name.");
 
index 9a0ec294f0dca579d594f10d8816c86bbbd3d578..dc8c727035d484e9c7d2f905c02003533118bdfd 100644 (file)
@@ -216,7 +216,7 @@ static int acquire_user_record(
                         return pam_syslog_errno(handle, LOG_ERR, r, "Failed to load user record: %m");
 
                 /* Safety check if cached record actually matches what we are looking for */
-                if (!streq_ptr(username, ur->user_name))
+                if (!user_record_matches_user_name(ur, username))
                         return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR,
                                                     "Acquired user record does not match user name.");
         } else {
index eea60af3346f80b8fca8a85b1d34834e4d2e0388..3aa26657185ff24cec98542b9c299f641feb7810 100644 (file)
@@ -331,6 +331,19 @@ int group_record_clone(GroupRecord *h, UserRecordLoadFlags flags, GroupRecord **
         return 0;
 }
 
+bool group_record_matches_group_name(const GroupRecord *g, const char *group_name) {
+        assert(g);
+        assert(group_name);
+
+        if (streq_ptr(g->group_name, group_name))
+                return true;
+
+        if (streq_ptr(g->group_name_and_realm_auto, group_name))
+                return true;
+
+        return false;
+}
+
 int group_record_match(GroupRecord *h, const UserDBMatch *match) {
         assert(h);
         assert(match);
index a2cef81c8a2dd44c62d1d8b6ff3558cc358fe68d..5705fe25116c831bece7caa85685ca8c5de5a6e6 100644 (file)
@@ -47,3 +47,5 @@ int group_record_match(GroupRecord *h, const UserDBMatch *match);
 
 const char* group_record_group_name_and_realm(GroupRecord *h);
 UserDisposition group_record_disposition(GroupRecord *h);
+
+bool group_record_matches_group_name(const GroupRecord *g, const char *groupname);
index 88970425cc6aeba26cf4c27c8186a4c0169d8bbd..e63736a74237b4cf11f22a2c4f9e85dfa35162b8 100644 (file)
@@ -2625,6 +2625,19 @@ int user_record_is_nobody(const UserRecord *u) {
         return u->uid == UID_NOBODY || STRPTR_IN_SET(u->user_name, NOBODY_USER_NAME, "nobody");
 }
 
+bool user_record_matches_user_name(const UserRecord *u, const char *user_name) {
+        assert(u);
+        assert(user_name);
+
+        if (streq_ptr(u->user_name, user_name))
+                return true;
+
+        if (streq_ptr(u->user_name_and_realm_auto, user_name))
+                return true;
+
+        return false;
+}
+
 int suitable_blob_filename(const char *name) {
         /* Enforces filename requirements as described in docs/USER_RECORD_BULK_DIRS.md */
         return filename_is_valid(name) &&
index d3decdb5c1fd9a46fa213d62cdea50cb23f3dfc0..48b97ce28a3ed068079fe875098d9289a18231de 100644 (file)
@@ -490,6 +490,8 @@ typedef struct UserDBMatch {
 bool user_name_fuzzy_match(const char *names[], size_t n_names, char **matches);
 int user_record_match(UserRecord *u, const UserDBMatch *match);
 
+bool user_record_matches_user_name(const UserRecord *u, const char *username);
+
 const char* user_storage_to_string(UserStorage t) _const_;
 UserStorage user_storage_from_string(const char *s) _pure_;
 
index 9f027d7783fafaa7067fa3a92c9e819dcdc57f27..81fd5f3ebcb669947d74cf1597c65ed4c59eceba 100644 (file)
@@ -4,6 +4,7 @@
 #include "fd-util.h"
 #include "fileio.h"
 #include "format-util.h"
+#include "group-record.h"
 #include "path-util.h"
 #include "stdio-util.h"
 #include "user-util.h"
@@ -87,7 +88,7 @@ static int load_user(
         if (r < 0)
                 return r;
 
-        if (name && !streq_ptr(name, u->user_name))
+        if (name && !user_record_matches_user_name(u, name))
                 return -EINVAL;
 
         if (uid_is_valid(uid) && uid != u->uid)
@@ -231,7 +232,7 @@ static int load_group(
         if (r < 0)
                 return r;
 
-        if (name && !streq_ptr(name, g->group_name))
+        if (name && !group_record_matches_group_name(g, name))
                 return -EINVAL;
 
         if (gid_is_valid(gid) && gid != g->gid)
index 1e36face408c453e945d3826dd14739601574e1f..dce60e2ebdcd766d4a9a0dc88e2e0163e89741bf 100644 (file)
@@ -215,7 +215,7 @@ static int vl_method_get_user_record(sd_varlink *link, sd_json_variant *paramete
         }
 
         if ((uid_is_valid(p.uid) && hr->uid != p.uid) ||
-            (p.user_name && !streq(hr->user_name, p.user_name)))
+            (p.user_name && !user_record_matches_user_name(hr, p.user_name)))
                 return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
 
         r = build_user_json(link, hr, &v);
@@ -345,7 +345,7 @@ static int vl_method_get_group_record(sd_varlink *link, sd_json_variant *paramet
         }
 
         if ((uid_is_valid(p.gid) && g->gid != p.gid) ||
-            (p.group_name && !streq(g->group_name, p.group_name)))
+            (p.group_name && !group_record_matches_group_name(g, p.group_name)))
                 return sd_varlink_error(link, "io.systemd.UserDatabase.ConflictingRecordFound", NULL);
 
         r = build_group_json(link, g, &v);