homectl: add support for creating users with alias names

This commit is contained in:
Lennart Poettering
2025-01-16 14:01:15 +01:00
parent 40fd0e0423
commit 5cd7b455e0
2 changed files with 60 additions and 0 deletions

View File

@@ -226,6 +226,16 @@
<xi:include href="version-info.xml" xpointer="v245"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--alias=<replaceable>NAME</replaceable><optional>,<replaceable>NAME…</replaceable></optional></option></term>
<listitem><para>Additional names for the user. Takes one or more valid UNIX user names, separated by
commas. May be used multiple times to define multiple aliases. An alias username may be specified
wherever the primary user name may be specified, and resolves to the same user record.</para>
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--email-address=<replaceable>EMAIL</replaceable></option></term>

View File

@@ -2756,6 +2756,7 @@ static int help(int argc, char *argv[], void *userdata) {
"\n%4$sGeneral User Record Properties:%5$s\n"
" -c --real-name=REALNAME Real name for user\n"
" --realm=REALM Realm to create user in\n"
" --alias=ALIAS Define alias usernames for this account\n"
" --email-address=EMAIL Email address for user\n"
" --location=LOCATION Set location of user on earth\n"
" --icon-name=NAME Icon name for user\n"
@@ -2900,6 +2901,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_NO_ASK_PASSWORD,
ARG_OFFLINE,
ARG_REALM,
ARG_ALIAS,
ARG_EMAIL_ADDRESS,
ARG_DISK_SIZE,
ARG_ACCESS_MODE,
@@ -2991,6 +2993,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "real-name", required_argument, NULL, 'c' },
{ "comment", required_argument, NULL, 'c' }, /* Compat alias to keep thing in sync with useradd(8) */
{ "realm", required_argument, NULL, ARG_REALM },
{ "alias", required_argument, NULL, ARG_ALIAS },
{ "email-address", required_argument, NULL, ARG_EMAIL_ADDRESS },
{ "location", required_argument, NULL, ARG_LOCATION },
{ "password-hint", required_argument, NULL, ARG_PASSWORD_HINT },
@@ -3146,6 +3149,53 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_ALIAS: {
if (isempty(optarg)) {
r = drop_from_identity("aliases");
if (r < 0)
return r;
break;
}
for (const char *p = optarg;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse alias list: %m");
if (r == 0)
break;
if (!valid_user_group_name(word, 0))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid alias user name %s.", word);
_cleanup_(sd_json_variant_unrefp) sd_json_variant *av =
sd_json_variant_ref(sd_json_variant_by_key(arg_identity_extra, "aliases"));
_cleanup_strv_free_ char **list = NULL;
r = sd_json_variant_strv(av, &list);
if (r < 0)
return log_error_errno(r, "Failed to parse group list: %m");
r = strv_extend(&list, word);
if (r < 0)
return log_oom();
strv_sort_uniq(list);
av = sd_json_variant_unref(av);
r = sd_json_variant_new_array_strv(&av, list);
if (r < 0)
return log_error_errno(r, "Failed to create alias list JSON: %m");
r = sd_json_variant_set_field(&arg_identity_extra, "aliases", av);
if (r < 0)
return log_error_errno(r, "Failed to update alias list: %m");
}
break;
}
case 'd': {
_cleanup_free_ char *hd = NULL;