]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #19726 from poettering/path-event-symlink
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 26 May 2021 01:51:00 +0000 (10:51 +0900)
committerGitHub <noreply@github.com>
Wed, 26 May 2021 01:51:00 +0000 (10:51 +0900)
teach .path units to notice events on paths with components that are symlinks

12 files changed:
man/crypttab.xml
man/loginctl.xml
man/systemd-cryptenroll.xml
src/core/load-fragment.c
src/core/service.c
src/cryptenroll/cryptenroll.c
src/login/loginctl.c
src/partition/repart.c
src/shared/dns-domain.c
src/shared/tpm2-util.c
src/test/meson.build
src/test/test-tpm2.c [new file with mode: 0644]

index 8f0ed5b77dc341361b4ebd87a02b7c40936b36c0..c048cd64c2168d669071d68622cbda16a82ce195 100644 (file)
       <varlistentry>
         <term><option>tpm2-pcrs=</option></term>
 
-        <listitem><para>Takes a comma separated list of numeric TPM2 PCR (i.e. "Platform Configuration
-        Register") indexes to bind the TPM2 volume unlocking to. This option is only useful when TPM2
-        enrollment metadata is not available in the LUKS2 JSON token header already, the way
+        <listitem><para>Takes a <literal>+</literal> separated list of numeric TPM2 PCR (i.e. "Platform
+        Configuration Register") indexes to bind the TPM2 volume unlocking to. This option is only useful
+        when TPM2 enrollment metadata is not available in the LUKS2 JSON token header already, the way
         <command>systemd-cryptenroll</command> writes it there. If not used (and no metadata in the LUKS2
         JSON token header defines it), defaults to a list of a single entry: PCR 7. Assign an empty string to
         encode a policy that binds the key to no PCRs, making the key accessible to local programs regardless
index 56a86e56efeb8ccb3b2587a08d9c1b9829f45ca4..bef3be71c96ebcf72eef4c57a3812649ac3bd7a4 100644 (file)
       <varlistentry>
         <term><command>terminate-session</command> <replaceable>ID</replaceable>…</term>
 
-        <listitem><para>Terminates a session. This kills all processes
-        of the session and deallocates all resources attached to the
-        session. </para></listitem>
+        <listitem><para>Terminates a session. This kills all processes of the session and deallocates all
+        resources attached to the session. If the argument is specified as empty string the session invoking
+        the command is terminated.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><command>kill-session</command> <replaceable>ID</replaceable>…</term>
 
-        <listitem><para>Send a signal to one or more processes of the
-        session. Use <option>--kill-who=</option> to select which
-        process to kill. Use <option>--signal=</option> to select the
-        signal to send.</para></listitem>
+        <listitem><para>Send a signal to one or more processes of the session. Use
+        <option>--kill-who=</option> to select which process to kill. Use <option>--signal=</option> to
+        select the signal to send. If the argument is specified as empty string the signal is sent to the
+        session invoking the command.</para></listitem>
       </varlistentry>
     </variablelist></refsect2>
 
       <varlistentry>
         <term><command>terminate-user</command> <replaceable>USER</replaceable>…</term>
 
-        <listitem><para>Terminates all sessions of a user. This kills
-        all processes of all sessions of the user and deallocates all
-        runtime resources attached to the user.</para></listitem>
+        <listitem><para>Terminates all sessions of a user. This kills all processes of all sessions of the
+        user and deallocates all runtime resources attached to the user. If the argument is specified as
+        empty string the sessions of the user invoking the command are terminated.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><command>kill-user</command> <replaceable>USER</replaceable>…</term>
 
-        <listitem><para>Send a signal to all processes of a user. Use
-        <option>--signal=</option> to select the signal to send.
-        </para></listitem>
+        <listitem><para>Send a signal to all processes of a user. Use <option>--signal=</option> to select
+        the signal to send. If the argument is specified as empty string the signal is sent to the sessions
+        of the user invoking the command.</para></listitem>
       </varlistentry>
     </variablelist></refsect2>
 
index c7f4e63f600eb33ab46a3a757db6cf8a44d701b8..097cf7518be2ea3353b2e725b933893087b11c40 100644 (file)
         <term><option>--tpm2-pcrs=</option><arg rep="repeat">PCR</arg></term>
 
         <listitem><para>Configures the TPM2 PCRs (Platform Configuration Registers) to bind the enrollment
-        requested via <option>--tpm2-device=</option> to. Takes a comma separated list of numeric PCR indexes
-        in the range 0…23. If not used, defaults to PCR 7 only. If an empty string is specified, binds the
-        enrollment to no PCRs at all. PCRs allow binding the enrollment to specific software versions and
-        system state, so that the enrolled unlocking key is only accessible (may be "unsealed") if specific
-        trusted software and/or configuration is used.</para></listitem>
+        requested via <option>--tpm2-device=</option> to. Takes a <literal>+</literal> separated list of
+        numeric PCR indexes in the range 0…23. If not used, defaults to PCR 7 only. If an empty string is
+        specified, binds the enrollment to no PCRs at all. PCRs allow binding the enrollment to specific
+        software versions and system state, so that the enrolled unlocking key is only accessible (may be
+        "unsealed") if specific trusted software and/or configuration is used.</para></listitem>
 
         <table>
           <title>Well-known PCR Definitions</title>
index 72378a408276daf6abc3ac590d3d956c39f258f2..ff6eaf32ef6233d2ccc71fb847feaa843ff04832 100644 (file)
@@ -789,7 +789,7 @@ int config_parse_exec(
                         return ignore ? 0 : -ENOEXEC;
                 }
 
-                if (!path_is_absolute(path) && !filename_is_valid(path)) {
+                if (!(path_is_absolute(path) ? path_is_valid(path) : filename_is_valid(path))) {
                         log_syntax(unit, ignore ? LOG_WARNING : LOG_ERR, filename, line, 0,
                                    "Neither a valid executable name nor an absolute path%s: %s",
                                    ignore ? ", ignoring" : "", path);
index baad85e8b6aa3ca487d68572ab16012f51bb78c5..f11b8f55579223e0440837ff9b849899baae719a 100644 (file)
@@ -2936,7 +2936,7 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
 
                 r = extract_first_word(&value, &fdn, NULL, EXTRACT_CUNESCAPE | EXTRACT_UNQUOTE);
                 if (r <= 0) {
-                        log_unit_debug_errno(u, r, "Failed to parse fd-store-fd value \"%s\": %m", value);
+                        log_unit_debug(u, "Failed to parse fd-store-fd value: %s", value);
                         return 0;
                 }
 
index 559a3468043117c46f0c40f1f4d014d0a10a9906..83b0b42ff2a866236a5a3ff81bc81c8e6bf45769 100644 (file)
@@ -97,7 +97,7 @@ static int help(void) {
                "                       Whether to require user verification to unlock the volume\n"
                "     --tpm2-device=PATH\n"
                "                       Enroll a TPM2 device\n"
-               "     --tpm2-pcrs=PCR1,PCR2,PCR3,…\n"
+               "     --tpm2-pcrs=PCR1+PCR2+PCR3,…\n"
                "                       Specify TPM2 PCRs to seal against\n"
                "     --wipe-slot=SLOT1,SLOT2,…\n"
                "                       Wipe specified slots\n"
index 7a2b13e4426781ae496a14d283c8be0d2e546670..cbb6518f4d2031d6ac8fed65c5d8ada59162b63b 100644 (file)
@@ -1086,9 +1086,15 @@ static int terminate_user(int argc, char *argv[], void *userdata) {
         for (int i = 1; i < argc; i++) {
                 uid_t uid;
 
-                r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
+                if (isempty(argv[i]))
+                        uid = getuid();
+                else {
+                        const char *u = argv[i];
+
+                        r = get_user_creds(&u, &uid, NULL, NULL, NULL, 0);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
+                }
 
                 r = bus_call_method(bus, bus_login_mgr, "TerminateUser", &error, NULL, "u", (uint32_t) uid);
                 if (r < 0)
@@ -1114,9 +1120,15 @@ static int kill_user(int argc, char *argv[], void *userdata) {
         for (int i = 1; i < argc; i++) {
                 uid_t uid;
 
-                r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
+                if (isempty(argv[i]))
+                        uid = getuid();
+                else {
+                        const char *u = argv[i];
+
+                        r = get_user_creds(&u, &uid, NULL, NULL, NULL, 0);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to look up user %s: %m", argv[i]);
+                }
 
                 r = bus_call_method(
                         bus,
index 341cae33a6c62384072f5f44584828dfd40c1f83..877d2a091d792d1b6ff21ae8fb993d28a863be44 100644 (file)
@@ -4070,7 +4070,7 @@ static int help(void) {
                "     --definitions=DIR    Find partition definitions in specified directory\n"
                "     --key-file=PATH      Key to use when encrypting partitions\n"
                "     --tpm2-device=PATH   Path to TPM2 device node to use\n"
-               "     --tpm2-pcrs=PCR1,PCR2,…\n"
+               "     --tpm2-pcrs=PCR1+PCR2+PCR3+…\n"
                "                          TPM2 PCR indexes to use for TPM2 enrollment\n"
                "     --seed=UUID          128bit seed UUID to derive all UUIDs from\n"
                "     --size=BYTES         Grow loopback file to specified size\n"
index 216e1a0647173a5fd916d25cb86f7923da60084b..787bb8fec944b013fcfaf4339c20432d486aa011 100644 (file)
@@ -1335,7 +1335,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
         return -EINVAL;
 #elif HAVE_LIBIDN
         _cleanup_free_ char *buf = NULL;
-        size_t n = 0, allocated = 0;
+        size_t n = 0;
         bool first = true;
         int r, q;
 
@@ -1357,7 +1357,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
                 if (q > 0)
                         r = q;
 
-                if (!GREEDY_REALLOC(buf, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
+                if (!GREEDY_REALLOC(buf, n + !first + DNS_LABEL_ESCAPED_MAX))
                         return -ENOMEM;
 
                 r = dns_label_escape(label, r, buf + n + !first, DNS_LABEL_ESCAPED_MAX);
@@ -1375,7 +1375,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
         if (n > DNS_HOSTNAME_MAX)
                 return -EINVAL;
 
-        if (!GREEDY_REALLOC(buf, allocated, n + 1))
+        if (!GREEDY_REALLOC(buf, n + 1))
                 return -ENOMEM;
 
         buf[n] = 0;
index 4d17f3c96a2238ea92bc93e24c0ae9057e34e44f..b2540c62fef38170e0b3d72b6ec0d0a0b4711fe6 100644 (file)
@@ -920,13 +920,23 @@ int tpm2_parse_pcrs(const char *s, uint32_t *ret) {
         uint32_t mask = 0;
         int r;
 
-        /* Parses a comma-separated list of PCR indexes */
+        assert(s);
+
+        if (isempty(s)) {
+                *ret = 0;
+                return 0;
+        }
+
+        /* Parses a "," or "+" separated list of PCR indexes. We support "," since this is a list after all,
+         * and most other tools expect comma separated PCR specifications. We also support "+" since in
+         * /etc/crypttab the "," is already used to separate options, hence a different separator is nice to
+         * avoid escaping. */
 
         for (;;) {
                 _cleanup_free_ char *pcr = NULL;
                 unsigned n;
 
-                r = extract_first_word(&p, &pcr, ",", EXTRACT_DONT_COALESCE_SEPARATORS);
+                r = extract_first_word(&p, &pcr, ",+", EXTRACT_DONT_COALESCE_SEPARATORS);
                 if (r == 0)
                         break;
                 if (r < 0)
index e02eaf78ff9e1e6e1644d9ab1673c4729d1139f6..c7b2bbfedc36cea550c6b2d025aa9362cc393c36 100644 (file)
@@ -422,6 +422,8 @@ tests += [
 
         [['src/test/test-sleep.c']],
 
+        [['src/test/test-tpm2.c']],
+
         [['src/test/test-replace-var.c']],
 
         [['src/test/test-calendarspec.c']],
diff --git a/src/test/test-tpm2.c b/src/test/test-tpm2.c
new file mode 100644 (file)
index 0000000..a1fd0aa
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "tpm2-util.h"
+#include "tests.h"
+
+static void test_tpm2_parse_pcrs(const char *s, uint32_t mask, int ret) {
+        uint32_t m;
+
+        assert_se(tpm2_parse_pcrs(s, &m) == ret);
+
+        if (ret >= 0)
+                assert_se(m == mask);
+}
+
+int main(int argc, char *argv[]) {
+
+        test_setup_logging(LOG_DEBUG);
+
+        test_tpm2_parse_pcrs("", 0, 0);
+        test_tpm2_parse_pcrs("0", 1, 0);
+        test_tpm2_parse_pcrs("1", 2, 0);
+        test_tpm2_parse_pcrs("0,1", 3, 0);
+        test_tpm2_parse_pcrs("0+1", 3, 0);
+        test_tpm2_parse_pcrs("0-1", 0, -EINVAL);
+        test_tpm2_parse_pcrs("0,1,2", 7, 0);
+        test_tpm2_parse_pcrs("0+1+2", 7, 0);
+        test_tpm2_parse_pcrs("0+1,2", 7, 0);
+        test_tpm2_parse_pcrs("0,1+2", 7, 0);
+        test_tpm2_parse_pcrs("0,2", 5, 0);
+        test_tpm2_parse_pcrs("0+2", 5, 0);
+        test_tpm2_parse_pcrs("foo", 0, -EINVAL);
+
+        return 0;
+}