user-record: add helper that checks if a provided user name matches a record

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)
This commit is contained in:
Lennart Poettering
2025-01-03 17:53:33 +01:00
parent 30de569174
commit 8aacf0fee1
9 changed files with 39 additions and 8 deletions

View 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)

View 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.");

View 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 {

View 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);

View 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);

View 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) &&

View 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_;

View 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)

View 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);