Merge pull request #9144 from yuwata/sysusers-spec
sysusers: support specifier expansion for GECOS and home directory
This commit is contained in:
commit
309ee4c26c
3
TODO
3
TODO
|
@ -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?
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue