From: Lennart Poettering Date: Thu, 16 Jan 2025 13:15:52 +0000 (+0100) Subject: user-record: add support for alias user names to user record X-Git-Tag: v258-rc1~1541^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2e1f38f5a9d442d0a027986024f4ea75ce97d2f;p=thirdparty%2Fsystemd.git user-record: add support for alias user names to user record --- diff --git a/docs/USER_RECORD.md b/docs/USER_RECORD.md index 1a219fed417..a8e02b2c5ec 100644 --- a/docs/USER_RECORD.md +++ b/docs/USER_RECORD.md @@ -226,6 +226,14 @@ This field is optional, when unset the user should not be considered part of any A user record with a realm set is never compatible (for the purpose of updates, see above) with a user record without one set, even if the `userName` field matches. +`aliases` → An array of strings, each being a valid UNIX user name. If +specified, a list of additional UNIX user names this record shall be known +under. These are *alias* names only, the name in `userName` is always the +primary name. Typically, a user record that carries this field shall be +retrievable and resolvable under every name listed here, pretty much everywhere +the primary user name is. If logging in is attempted via an alias name it +should be normalized to the primary name. + `blobDirectory` → The absolute path to a world-readable copy of the user's blob directory. See [Blob Directories](/USER_RECORD_BLOB_DIRS) for more details. diff --git a/src/shared/user-record-show.c b/src/shared/user-record-show.c index a828ffa0a73..acff25d0712 100644 --- a/src/shared/user-record-show.c +++ b/src/shared/user-record-show.c @@ -65,6 +65,13 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) { printf(" User name: %s\n", user_record_user_name_and_realm(hr)); + if (!strv_isempty(hr->aliases)) { + STRV_FOREACH(i, hr->aliases) + printf(i == hr->aliases ? + " Alias: %s" : ", %s", *i); + putchar('\n'); + } + if (hr->state) { const char *color; diff --git a/src/shared/user-record.c b/src/shared/user-record.c index e63736a7423..9feac30933f 100644 --- a/src/shared/user-record.c +++ b/src/shared/user-record.c @@ -140,6 +140,7 @@ static UserRecord* user_record_free(UserRecord *h) { free(h->user_name); free(h->realm); free(h->user_name_and_realm_auto); + strv_free(h->aliases); free(h->real_name); free(h->email_address); erase_and_free(h->password_hint); @@ -1538,6 +1539,7 @@ int user_record_load(UserRecord *h, sd_json_variant *v, UserRecordLoadFlags load static const sd_json_dispatch_field user_dispatch_table[] = { { "userName", SD_JSON_VARIANT_STRING, json_dispatch_user_group_name, offsetof(UserRecord, user_name), SD_JSON_RELAX }, + { "aliases", SD_JSON_VARIANT_ARRAY, json_dispatch_user_group_list, offsetof(UserRecord, aliases), SD_JSON_RELAX }, { "realm", SD_JSON_VARIANT_STRING, json_dispatch_realm, offsetof(UserRecord, realm), 0 }, { "blobDirectory", SD_JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, blob_directory), SD_JSON_STRICT }, { "blobManifest", SD_JSON_VARIANT_OBJECT, dispatch_blob_manifest, offsetof(UserRecord, blob_manifest), 0 }, @@ -2635,6 +2637,15 @@ bool user_record_matches_user_name(const UserRecord *u, const char *user_name) { if (streq_ptr(u->user_name_and_realm_auto, user_name)) return true; + if (strv_contains(u->aliases, user_name)) + return true; + + const char *realm = strrchr(user_name, '@'); + if (realm && streq_ptr(realm+1, u->realm)) + STRV_FOREACH(a, u->aliases) + if (startswith(user_name, *a) == realm) + return true; + return false; } @@ -2704,7 +2715,8 @@ int user_record_match(UserRecord *u, const UserDBMatch *match) { u->cifs_user_name, }; - if (!user_name_fuzzy_match(names, ELEMENTSOF(names), match->fuzzy_names)) + if (!user_name_fuzzy_match(names, ELEMENTSOF(names), match->fuzzy_names) && + !user_name_fuzzy_match((const char**) u->aliases, strv_length(u->aliases), match->fuzzy_names)) return false; } diff --git a/src/shared/user-record.h b/src/shared/user-record.h index 48b97ce28a3..d80a46130a9 100644 --- a/src/shared/user-record.h +++ b/src/shared/user-record.h @@ -239,6 +239,7 @@ typedef struct UserRecord { char *user_name; char *realm; char *user_name_and_realm_auto; /* the user_name field concatenated with '@' and the realm, if the latter is defined */ + char **aliases; char *real_name; char *email_address; char *password_hint;