summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-10-18 21:36:34 +0200
committerLennart Poettering <lennart@poettering.net>2024-10-21 14:14:16 +0200
commit2ee6fa552eb802baf901983b556b3e7f8ad60f1e (patch)
tree870206cac4a4321a3e272f907818c4a66d5b3710
parentman: update PASSWORD_AGENTS spec, and introduce unpriv pw queries (diff)
downloadsystemd-2ee6fa552eb802baf901983b556b3e7f8ad60f1e.tar.xz
systemd-2ee6fa552eb802baf901983b556b3e7f8ad60f1e.zip
ask-password-api: don't accidentally create a dir, when we don't want one
Previously, we were using touch(), which usually works fine, because the path should always refer to an existing directory, in which case it just updates the timestamp. However, if the dir does not exist yet (which shouldn't happen), it would be created as regular file, which is just wrong. Hence, let's instead create the dir as dir if it is missing, and then update its timestamp.
-rw-r--r--src/basic/fs-util.c24
-rw-r--r--src/basic/fs-util.h2
-rw-r--r--src/shared/ask-password-api.c6
3 files changed, 21 insertions, 11 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 97f36df8e7..35cebfc849 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -371,9 +371,21 @@ int fd_warn_permissions(const char *path, int fd) {
return stat_warn_permissions(path, &st);
}
+int touch_fd(int fd, usec_t stamp) {
+ assert(fd >= 0);
+
+ if (stamp == USEC_INFINITY)
+ return futimens_opath(fd, /* ts= */ NULL);
+
+ struct timespec ts[2];
+ timespec_store(ts + 0, stamp);
+ ts[1] = ts[0];
+ return futimens_opath(fd, ts);
+}
+
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
_cleanup_close_ int fd = -EBADF;
- int r, ret;
+ int ret;
assert(path);
@@ -405,15 +417,7 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
* something fchown(), fchmod(), futimensat() don't allow. */
ret = fchmod_and_chown(fd, mode, uid, gid);
- if (stamp != USEC_INFINITY) {
- struct timespec ts;
- timespec_store(&ts, stamp);
-
- r = futimens_opath(fd, (const struct timespec[2]) { ts, ts });
- } else
- r = futimens_opath(fd, /* ts = */ NULL);
-
- return RET_GATHER(ret, r);
+ return RET_GATHER(ret, touch_fd(fd, stamp));
}
int symlinkat_idempotent(const char *from, int atfd, const char *to, bool make_relative) {
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index 06c95a3b08..93af685eef 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -54,6 +54,8 @@ int stat_warn_permissions(const char *path, const struct stat *st);
#define access_nofollow(path, mode) \
RET_NERRNO(faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW))
+int touch_fd(int fd, usec_t stamp);
+
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
static inline int touch(const char *path) {
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index 1c4f357fbe..7b9cdadc54 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -102,7 +102,11 @@ static int touch_ask_password_directory(AskPasswordFlags flags) {
if (r <= 0)
return r;
- r = touch(p);
+ _cleanup_close_ int fd = open_mkdir(p, O_CLOEXEC, 0755);
+ if (fd < 0)
+ return fd;
+
+ r = touch_fd(fd, USEC_INFINITY);
if (r < 0)
return r;