From cc7300fc5868f6d47f3f47076100b574bf54e58d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 14 Jan 2025 18:28:27 +0100 Subject: userdb: optionally parse numeric UIDs/GIDs where a username is expected Let's move this logic from userdbctl into generic code so that we can use it elsewhere. --- src/shared/userdb.c | 14 ++++++++++++++ src/shared/userdb.h | 2 ++ src/userdb/userdbctl.c | 12 ++---------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/shared/userdb.c b/src/shared/userdb.c index c7334e820d..be7c77d950 100644 --- a/src/shared/userdb.c +++ b/src/shared/userdb.c @@ -680,6 +680,13 @@ int userdb_by_name(const char *name, UserDBFlags flags, UserRecord **ret) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *query = NULL; int r; + if (FLAGS_SET(flags, USERDB_PARSE_NUMERIC)) { + uid_t uid; + + if (parse_uid(name, &uid) >= 0) + return userdb_by_uid(uid, flags, ret); + } + if (!valid_user_group_name(name, VALID_USER_RELAX)) return -EINVAL; @@ -991,6 +998,13 @@ int groupdb_by_name(const char *name, UserDBFlags flags, GroupRecord **ret) { _cleanup_(sd_json_variant_unrefp) sd_json_variant *query = NULL; int r; + if (FLAGS_SET(flags, USERDB_PARSE_NUMERIC)) { + gid_t gid; + + if (parse_gid(name, &gid) >= 0) + return groupdb_by_gid(gid, flags, ret); + } + if (!valid_user_group_name(name, VALID_USER_RELAX)) return -EINVAL; diff --git a/src/shared/userdb.h b/src/shared/userdb.h index daf87fb5cf..9bb47efbfe 100644 --- a/src/shared/userdb.h +++ b/src/shared/userdb.h @@ -30,6 +30,8 @@ typedef enum UserDBFlags { /* Combinations */ USERDB_NSS_ONLY = USERDB_EXCLUDE_VARLINK|USERDB_EXCLUDE_DROPIN|USERDB_DONT_SYNTHESIZE_INTRINSIC|USERDB_DONT_SYNTHESIZE_FOREIGN, USERDB_DROPIN_ONLY = USERDB_EXCLUDE_NSS|USERDB_EXCLUDE_VARLINK|USERDB_DONT_SYNTHESIZE_INTRINSIC|USERDB_DONT_SYNTHESIZE_FOREIGN, + + USERDB_PARSE_NUMERIC = 1 << 8, /* if a numeric UID is specified as name, parse it and look up by UID/GID */ } UserDBFlags; /* Well-known errors we'll return here: diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c index ee6e6c869a..74057f6593 100644 --- a/src/userdb/userdbctl.c +++ b/src/userdb/userdbctl.c @@ -405,12 +405,8 @@ static int display_user(int argc, char *argv[], void *userdata) { if (argc > 1 && !arg_fuzzy) STRV_FOREACH(i, argv + 1) { _cleanup_(user_record_unrefp) UserRecord *ur = NULL; - uid_t uid; - if (parse_uid(*i, &uid) >= 0) - r = userdb_by_uid(uid, arg_userdb_flags, &ur); - else - r = userdb_by_name(*i, arg_userdb_flags, &ur); + r = userdb_by_name(*i, arg_userdb_flags|USERDB_PARSE_NUMERIC, &ur); if (r < 0) { if (r == -ESRCH) log_error_errno(r, "User %s does not exist.", *i); @@ -741,12 +737,8 @@ static int display_group(int argc, char *argv[], void *userdata) { if (argc > 1 && !arg_fuzzy) STRV_FOREACH(i, argv + 1) { _cleanup_(group_record_unrefp) GroupRecord *gr = NULL; - gid_t gid; - if (parse_gid(*i, &gid) >= 0) - r = groupdb_by_gid(gid, arg_userdb_flags, &gr); - else - r = groupdb_by_name(*i, arg_userdb_flags, &gr); + r = groupdb_by_name(*i, arg_userdb_flags|USERDB_PARSE_NUMERIC, &gr); if (r < 0) { if (r == -ESRCH) log_error_errno(r, "Group %s does not exist.", *i); -- cgit v1.2.3