From 170d7d49f527100495fb1251d11fd56acd523a8e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jun 2025 10:08:25 +0200 Subject: [PATCH] user-record: also support "aliases" in the "status" section of user records MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some user record providers might want to implement case-insensitive user record matching, or other forms of non-normalized matching. So far uderdb didn't allow that, because client's typically revalidate the returned user records against the search keys (at least our clients do) – they check if the search user name is actually part of the user record and its aliases. In order to support such lookups we thus need to allow the looup keys to be part of the user record, but also not be persisted in it, because the number of casings/spellings of a username might be ridiculously high. A nice way out is to allow "aliases" not only in the main part of the record, but also in the "status" part, that contains information dynamically determined at query time. We can insert a second "aliases" field there, which the parser will then merge with the primary "aliases" field, but the existing rules around "status" ensure tha the data is never persisted. Follow-up: e2e1f38f5a9d442d0a027986024f4ea75ce97d2f --- docs/USER_RECORD.md | 12 ++++++++++++ src/shared/user-record.c | 1 + 2 files changed, 13 insertions(+) diff --git a/docs/USER_RECORD.md b/docs/USER_RECORD.md index 4ec6f4fa73..60c78ce1c5 100644 --- a/docs/USER_RECORD.md +++ b/docs/USER_RECORD.md @@ -872,6 +872,18 @@ sub-object of the top-level user record object is keyed by the machine ID, which points to the object with the fields defined here. The following fields are defined: +`aliases` → An array of strings, each being a valid UNIX user name. This is +similar to the top-level field of the same name. The purpose of this field is +to allow user record providers to dynamically insert additional alias names +into the user record, depending on the precise query. This is useful to +implement case-insensitive user names (or support for similar non-normalized +user record naming), as it allows the provider to insert the precise +casing/spelling of the user name used for the look-up in the record data, +without this being part of the persisted record. Note that clients doing a +look-up typically re-validate user records against the lookup keys they +provided, hence it's essential that any dynamic alias name appears in the +user record, without this being part of the persistent part of the record. + `diskUsage` → An unsigned 64-bit integer. The currently used disk space of the home directory in bytes. This value might be determined in different ways, depending on the selected storage mechanism. diff --git a/src/shared/user-record.c b/src/shared/user-record.c index 09e96f0c9a..dfe4379e9f 100644 --- a/src/shared/user-record.c +++ b/src/shared/user-record.c @@ -1403,6 +1403,7 @@ static int dispatch_status(const char *name, sd_json_variant *variant, sd_json_d { "fallbackHomeDirectory", SD_JSON_VARIANT_STRING, json_dispatch_home_directory, offsetof(UserRecord, fallback_home_directory), 0 }, { "useFallback", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(UserRecord, use_fallback), 0 }, { "defaultArea", SD_JSON_VARIANT_STRING, json_dispatch_filename, offsetof(UserRecord, default_area), 0 }, + { "aliases", SD_JSON_VARIANT_ARRAY, json_dispatch_user_group_list, offsetof(UserRecord, aliases), SD_JSON_RELAX }, {}, };