Merge pull request #9144 from yuwata/sysusers-spec

sysusers: support specifier expansion for GECOS and home directory
This commit is contained in:
Lennart Poettering 2018-05-31 11:41:29 +02:00 committed by GitHub
commit 309ee4c26c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 11 deletions

3
TODO
View file

@ -24,9 +24,6 @@ Janitorial Clean-ups:
Features:
* document specifiers systemd-sysusers understands in its man page (the way
it's already documented in tmpfiles.d(5)' man page)
* add O_TMPFILE support to copy_file_atomic()
* nspawn: greater control over selinux label?

View file

@ -229,6 +229,66 @@ u root 0 "Superuser" /root /bin/zsh</pro
</refsect2>
</refsect1>
<refsect1>
<title>Specifiers</title>
<para>Specifiers can be used in the "Name", "ID", "GECOS", "Home directory", and "Shell" fields.
An unknown or unresolvable specifier is treated as invalid configuration.
The following expansions are understood:</para>
<table>
<title>Specifiers available</title>
<tgroup cols='3' align='left' colsep='1' rowsep='1'>
<colspec colname="spec" />
<colspec colname="mean" />
<colspec colname="detail" />
<thead>
<row>
<entry>Specifier</entry>
<entry>Meaning</entry>
<entry>Details</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>%b</literal></entry>
<entry>Boot ID</entry>
<entry>The boot ID of the running system, formatted as string. See <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry> for more information.</entry>
</row>
<row>
<entry><literal>%H</literal></entry>
<entry>Host name</entry>
<entry>The hostname of the running system.</entry>
</row>
<row>
<entry><literal>%m</literal></entry>
<entry>Machine ID</entry>
<entry>The machine ID of the running system, formatted as string. See <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
</row>
<row>
<entry><literal>%T</literal></entry>
<entry>Directory for temporary files</entry>
<entry>This is either <filename>/tmp</filename> or the path <literal>$TMPDIR</literal>, <literal>$TEMP</literal> or <literal>$TMP</literal> are set to.</entry>
</row>
<row>
<entry><literal>%v</literal></entry>
<entry>Kernel release</entry>
<entry>Identical to <command>uname -r</command> output.</entry>
</row>
<row>
<entry><literal>%V</literal></entry>
<entry>Directory for larger and persistent temporary files</entry>
<entry>This is either <filename>/var/tmp</filename> or the path <literal>$TMPDIR</literal>, <literal>$TEMP</literal> or <literal>$TMP</literal> are set to.</entry>
</row>
<row>
<entry><literal>%%</literal></entry>
<entry>Escaped <literal>%</literal></entry>
<entry>Single percent sign.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
<title>Idempotence</title>

View file

@ -1371,8 +1371,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
_cleanup_free_ char *action = NULL,
*name = NULL, *resolved_name = NULL,
*id = NULL, *resolved_id = NULL,
*description = NULL,
*home = NULL,
*description = NULL, *resolved_description = NULL,
*home = NULL, *resolved_home = NULL,
*shell, *resolved_shell = NULL;
_cleanup_(item_freep) Item *i = NULL;
Item *existing;
@ -1446,8 +1446,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
description = mfree(description);
if (description) {
if (!valid_gecos(description)) {
log_error("[%s:%u] '%s' is not a valid GECOS field.", fname, line, description);
r = specifier_printf(description, specifier_table, NULL, &resolved_description);
if (r < 0) {
log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, description);
return r;
}
if (!valid_gecos(resolved_description)) {
log_error("[%s:%u] '%s' is not a valid GECOS field.", fname, line, resolved_description);
return -EINVAL;
}
}
@ -1457,8 +1463,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
home = mfree(home);
if (home) {
if (!valid_home(home)) {
log_error("[%s:%u] '%s' is not a valid home directory field.", fname, line, home);
r = specifier_printf(home, specifier_table, NULL, &resolved_home);
if (r < 0) {
log_error("[%s:%u] Failed to replace specifiers: %s", fname, line, home);
return r;
}
if (!valid_home(resolved_home)) {
log_error("[%s:%u] '%s' is not a valid home directory field.", fname, line, resolved_home);
return -EINVAL;
}
}
@ -1608,8 +1620,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
}
}
i->description = TAKE_PTR(description);
i->home = TAKE_PTR(home);
i->description = TAKE_PTR(resolved_description);
i->home = TAKE_PTR(resolved_home);
i->shell = TAKE_PTR(resolved_shell);
h = users;