Blob Blame History Raw
From 1e788a7fb535a37a8268aa7dc5130f670eb72a6b Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
Date: Tue, 23 Jul 2024 13:14:05 +0200
Subject: [PATCH] tmpfiles: make --purge hard to (mis-)use

Follow-up for https://github.com/systemd/systemd/pull/33383.
---
 src/tmpfiles/tmpfiles.c           | 17 +++++++++++++++++
 test/units/TEST-22-TMPFILES.18.sh |  4 ++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 8cc8c1ccd6..14048545db 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -4197,6 +4197,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_IMAGE_POLICY,
                 ARG_REPLACE,
                 ARG_DRY_RUN,
+                ARG_DESTROY_DATA,
                 ARG_NO_PAGER,
         };
 
@@ -4220,10 +4221,18 @@ static int parse_argv(int argc, char *argv[]) {
                 { "replace",        required_argument,   NULL, ARG_REPLACE        },
                 { "dry-run",        no_argument,         NULL, ARG_DRY_RUN        },
                 { "no-pager",       no_argument,         NULL, ARG_NO_PAGER       },
+
+                /* This is not documented on purpose.
+                 * If you think --purge should be allowed without jumping through hoops,
+                 * consider opening a bug report with the description of the use case.
+                 */
+                { "destroy-data",   no_argument,         NULL, ARG_DESTROY_DATA   },
+
                 {}
         };
 
         int c, r;
+        bool destroy_data = false;
 
         assert(argc >= 0);
         assert(argv);
@@ -4330,6 +4339,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_dry_run = true;
                         break;
 
+                case ARG_DESTROY_DATA:
+                        destroy_data = true;
+                        break;
+
                 case ARG_NO_PAGER:
                         arg_pager_flags |= PAGER_DISABLE;
                         break;
@@ -4349,6 +4362,10 @@ static int parse_argv(int argc, char *argv[]) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Refusing --purge without specification of a configuration file.");
 
+        if (FLAGS_SET(arg_operation, OPERATION_PURGE) && !arg_dry_run && !destroy_data)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "Refusing --purge without --destroy-data.");
+
         if (arg_replace && arg_cat_flags != CAT_CONFIG_OFF)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Option --replace= is not supported with --cat-config/--tldr.");
diff --git a/test/units/TEST-22-TMPFILES.18.sh b/test/units/TEST-22-TMPFILES.18.sh
index 5d24197c81..de23bbb95f 100755
--- a/test/units/TEST-22-TMPFILES.18.sh
+++ b/test/units/TEST-22-TMPFILES.18.sh
@@ -21,7 +21,7 @@ systemd-tmpfiles --purge --dry-run - <<<"$c"
 test -f /tmp/somedir/somefile
 grep -q baz /tmp/somedir/somefile
 
-systemd-tmpfiles --purge - <<<"$c"
+systemd-tmpfiles --purge --destroy-data - <<<"$c"
 test ! -f /tmp/somedir/somefile
 test ! -d /tmp/somedir/
 
@@ -29,6 +29,6 @@ systemd-tmpfiles --create --purge --dry-run - <<<"$c"
 test ! -f /tmp/somedir/somefile
 test ! -d /tmp/somedir/
 
-systemd-tmpfiles --create --purge - <<<"$c"
+systemd-tmpfiles --create --destroy-data --purge - <<<"$c"
 test -f /tmp/somedir/somefile
 grep -q baz /tmp/somedir/somefile
-- 
2.45.2