mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
userdb: introduce USERDB_SYNTHESIZE_NUMERIC flag
When the flag is set, even if the specified UID/GID does not exist, create a synthetic user record for the UID/GID. Currently, only system UID/GID are supported.
This commit is contained in:
@@ -742,6 +742,31 @@ static int synthetic_foreign_user_build(uid_t foreign_uid, UserRecord **ret) {
|
||||
SD_JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("foreign")));
|
||||
}
|
||||
|
||||
static int synthetic_numeric_user_build(uid_t uid, UserRecord **ret) {
|
||||
assert(ret);
|
||||
|
||||
if (uid == 0) /* This should be handled by synthetic_root_user_build() */
|
||||
return -ESRCH;
|
||||
|
||||
if (!uid_is_system(uid))
|
||||
return -ESRCH;
|
||||
|
||||
_cleanup_free_ char *un = NULL;
|
||||
if (asprintf(&un, "unknown-" UID_FMT, uid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
_cleanup_free_ char *rn = NULL;
|
||||
if (asprintf(&rn, "Unknown System UID " UID_FMT, uid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
return user_record_buildo(
|
||||
ret,
|
||||
SD_JSON_BUILD_PAIR_STRING("userName", un),
|
||||
SD_JSON_BUILD_PAIR_STRING("realName", rn),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("uid", uid),
|
||||
SD_JSON_BUILD_PAIR_STRING("disposition", "system"));
|
||||
}
|
||||
|
||||
static int user_name_foreign_extract_uid(const char *name, uid_t *ret_uid) {
|
||||
int r;
|
||||
|
||||
@@ -963,6 +988,9 @@ static int userdb_by_uid_fallbacks(
|
||||
if (!FLAGS_SET(flags, USERDB_DONT_SYNTHESIZE_FOREIGN) && uid_is_foreign(uid))
|
||||
return synthetic_foreign_user_build(uid - FOREIGN_UID_BASE, ret);
|
||||
|
||||
if (FLAGS_SET(flags, USERDB_SYNTHESIZE_NUMERIC))
|
||||
return synthetic_numeric_user_build(uid, ret);
|
||||
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
@@ -1232,6 +1260,31 @@ static int synthetic_foreign_group_build(gid_t foreign_gid, GroupRecord **ret) {
|
||||
SD_JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("foreign")));
|
||||
}
|
||||
|
||||
static int synthetic_numeric_group_build(gid_t gid, GroupRecord **ret) {
|
||||
assert(ret);
|
||||
|
||||
if (gid == 0) /* This should be handled by synthetic_root_group_build() */
|
||||
return -ESRCH;
|
||||
|
||||
if (!gid_is_system(gid))
|
||||
return -ESRCH;
|
||||
|
||||
_cleanup_free_ char *gn = NULL;
|
||||
if (asprintf(&gn, "unknown-" GID_FMT, gid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
_cleanup_free_ char *d = NULL;
|
||||
if (asprintf(&d, "Unknown System GID " UID_FMT, gid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
return group_record_buildo(
|
||||
ret,
|
||||
SD_JSON_BUILD_PAIR_STRING("groupName", gn),
|
||||
SD_JSON_BUILD_PAIR_STRING("description", d),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("gid", gid),
|
||||
SD_JSON_BUILD_PAIR_STRING("disposition", "system"));
|
||||
}
|
||||
|
||||
static int query_append_gid_match(sd_json_variant **query, const UserDBMatch *match) {
|
||||
int r;
|
||||
|
||||
@@ -1387,6 +1440,9 @@ static int groupdb_by_gid_fallbacks(
|
||||
if (!FLAGS_SET(flags, USERDB_DONT_SYNTHESIZE_FOREIGN) && gid_is_foreign(gid))
|
||||
return synthetic_foreign_group_build(gid - FOREIGN_UID_BASE, ret);
|
||||
|
||||
if (FLAGS_SET(flags, USERDB_SYNTHESIZE_NUMERIC))
|
||||
return synthetic_numeric_group_build(gid, ret);
|
||||
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef enum UserDBFlags {
|
||||
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 */
|
||||
USERDB_SYNTHESIZE_NUMERIC = 1 << 8, /* synthesize system UID/GID even if it does not exist */
|
||||
} UserDBFlags;
|
||||
|
||||
/* Well-known errors we'll return here:
|
||||
|
||||
Reference in New Issue
Block a user