mirror of
https://github.com/systemd/systemd.git
synced 2025-01-06 17:18:12 +03:00
Compare commits
26 Commits
5449885e88
...
5811a0117c
Author | SHA1 | Date | |
---|---|---|---|
|
5811a0117c | ||
|
d69ee5acdc | ||
|
0cc496b2d2 | ||
|
b6b8527cd1 | ||
|
4d5d574906 | ||
|
967c586e9c | ||
|
f0b974050d | ||
|
82d8a2c810 | ||
|
efaa5e0539 | ||
|
c7c9e3c7c0 | ||
|
53c5073858 | ||
|
1bf9e308eb | ||
|
4096fcde09 | ||
|
bd91f23acf | ||
|
b9633ebb2a | ||
|
4ffecbbbee | ||
|
4e4ed4b64d | ||
|
3a7ae4ba62 | ||
|
aec1262a2e | ||
|
8eeb870971 | ||
|
4946dd4197 | ||
|
64053bed08 | ||
|
da3d81cccd | ||
|
d49449c89b | ||
|
652371a3c1 | ||
|
12620ca1fb |
2
TODO
2
TODO
@ -129,6 +129,8 @@ Deprecations and removals:
|
||||
|
||||
Features:
|
||||
|
||||
* port copy.c over to use LabelOps for all labelling.
|
||||
|
||||
* port remaining getmntent() users over to libmount. There are subtle
|
||||
differences in the parsers (see #25371 for example), and it hence makes sense
|
||||
if we stick to one set of parsers on this, not mix both.
|
||||
|
@ -1245,6 +1245,10 @@ node /org/freedesktop/login1/session/1 {
|
||||
readonly b IdleHint = ...;
|
||||
readonly t IdleSinceHint = ...;
|
||||
readonly t IdleSinceHintMonotonic = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b CanIdle = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b CanLock = ...;
|
||||
readonly b LockedHint = ...;
|
||||
};
|
||||
interface org.freedesktop.DBus.Peer { ... };
|
||||
@ -1349,6 +1353,10 @@ node /org/freedesktop/login1/session/1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IdleSinceHintMonotonic"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CanIdle"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CanLock"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="LockedHint"/>
|
||||
|
||||
<!--End of Autogenerated section-->
|
||||
@ -1538,6 +1546,10 @@ node /org/freedesktop/login1/session/1 {
|
||||
|
||||
<para><varname>LockedHint</varname> shows the locked hint state of this session, as set by the
|
||||
<function>SetLockedHint()</function> method described above.</para>
|
||||
|
||||
<para><varname>CanIdle</varname> indicates whether the session supports the idle hint
|
||||
concept. Similarly, <varname>CanLock</varname> indicates whether the session supports the screen lock
|
||||
concept.</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
@ -1619,10 +1631,9 @@ node /org/freedesktop/login1/session/1 {
|
||||
<function>CanSleep()</function>,
|
||||
<varname>SleepOperation</varname>, and
|
||||
<function>ListSessionsEx()</function> were added in version 256.</para>
|
||||
<para><varname>HandleSecureAttentionKey</varname>,
|
||||
<function>SecureAttentionKey()</function>,
|
||||
<varname>PreparingForShutdownWithMetadata</varname>, and
|
||||
<varname>DesignatedMaintenanceTime</varname> were added in version 257.</para>
|
||||
<para><varname>HandleSecureAttentionKey</varname>, <function>SecureAttentionKey()</function>,
|
||||
<varname>PreparingForShutdownWithMetadata</varname>, <varname>DesignatedMaintenanceTime</varname>,
|
||||
<varname>CanIdle</varname> and <varname>CanLock</varname> were added in version 257.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Session Objects</title>
|
||||
|
@ -6277,7 +6277,7 @@ DHCP=ipv6
|
||||
|
||||
# If the upstream network does not provides any Router Advertisement (RA) messages,
|
||||
# then uncomment the lines below to make the DHCPv6 client forcibly started in the
|
||||
# manageed mode.
|
||||
# managed mode.
|
||||
#[Network]
|
||||
#IPv6AcceptRA=no
|
||||
#[DHCPv6]
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "label.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "mkdir.h"
|
||||
@ -230,22 +231,40 @@ static int write_string_file_atomic_at(
|
||||
/* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement
|
||||
* semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */
|
||||
|
||||
mode_t mode = write_string_file_flags_to_mode(flags);
|
||||
|
||||
bool call_label_ops_post = false;
|
||||
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL)) {
|
||||
r = label_ops_pre(dir_fd, fn, mode);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
call_label_ops_post = true;
|
||||
}
|
||||
|
||||
r = fopen_temporary_at(dir_fd, fn, &f, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto fail;
|
||||
|
||||
if (call_label_ops_post) {
|
||||
call_label_ops_post = false;
|
||||
|
||||
r = label_ops_post(fileno(f), /* path= */ NULL, /* created= */ true);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = write_string_stream_full(f, line, flags, ts);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
r = fchmod_umask(fileno(f), write_string_file_flags_to_mode(flags));
|
||||
r = fchmod_umask(fileno(f), mode);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (renameat(dir_fd, p, dir_fd, fn) < 0) {
|
||||
r = -errno;
|
||||
r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn));
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
|
||||
/* Sync the rename, too */
|
||||
@ -257,7 +276,11 @@ static int write_string_file_atomic_at(
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
(void) unlinkat(dir_fd, p, 0);
|
||||
if (call_label_ops_post)
|
||||
(void) label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f);
|
||||
|
||||
if (f)
|
||||
(void) unlinkat(dir_fd, p, 0);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -268,9 +291,10 @@ int write_string_file_full(
|
||||
WriteStringFileFlags flags,
|
||||
const struct timespec *ts) {
|
||||
|
||||
bool call_label_ops_post = false, made_file = false;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int q, r;
|
||||
int r;
|
||||
|
||||
assert(fn);
|
||||
assert(line);
|
||||
@ -292,21 +316,40 @@ int write_string_file_full(
|
||||
goto fail;
|
||||
|
||||
return r;
|
||||
} else
|
||||
assert(!ts);
|
||||
}
|
||||
|
||||
mode_t mode = write_string_file_flags_to_mode(flags);
|
||||
|
||||
if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) {
|
||||
r = label_ops_pre(dir_fd, fn, mode);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
call_label_ops_post = true;
|
||||
}
|
||||
|
||||
/* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
|
||||
fd = openat(dir_fd, fn, O_CLOEXEC|O_NOCTTY |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
|
||||
write_string_file_flags_to_mode(flags));
|
||||
fd = openat_report_new(
|
||||
dir_fd, fn, O_CLOEXEC | O_NOCTTY |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) |
|
||||
(FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY),
|
||||
mode,
|
||||
&made_file);
|
||||
if (fd < 0) {
|
||||
r = -errno;
|
||||
r = fd;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (call_label_ops_post) {
|
||||
call_label_ops_post = false;
|
||||
|
||||
r = label_ops_post(fd, /* path= */ NULL, made_file);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = take_fdopen_unlocked(&fd, "w", &f);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
@ -321,19 +364,24 @@ int write_string_file_full(
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (call_label_ops_post)
|
||||
(void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file);
|
||||
|
||||
if (made_file)
|
||||
(void) unlinkat(dir_fd, fn, 0);
|
||||
|
||||
if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
|
||||
return r;
|
||||
|
||||
f = safe_fclose(f);
|
||||
fd = safe_close(fd);
|
||||
|
||||
/* OK, the operation failed, but let's see if the right
|
||||
* contents in place already. If so, eat up the error. */
|
||||
/* OK, the operation failed, but let's see if the right contents in place already. If so, eat up the
|
||||
* error. */
|
||||
if (verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE)) > 0)
|
||||
return 0;
|
||||
|
||||
q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE));
|
||||
if (q <= 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
int write_string_filef(
|
||||
|
@ -28,11 +28,7 @@ typedef enum {
|
||||
WRITE_STRING_FILE_MODE_0600 = 1 << 10,
|
||||
WRITE_STRING_FILE_MODE_0444 = 1 << 11,
|
||||
WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL = 1 << 12,
|
||||
|
||||
/* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
|
||||
more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
|
||||
and friends. */
|
||||
|
||||
WRITE_STRING_FILE_LABEL = 1 << 13,
|
||||
} WriteStringFileFlags;
|
||||
|
||||
typedef enum {
|
||||
|
@ -1077,65 +1077,50 @@ int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_
|
||||
}
|
||||
|
||||
int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created) {
|
||||
unsigned attempts = 7;
|
||||
int fd;
|
||||
|
||||
/* Just like openat(), but adds one thing: optionally returns whether we created the file anew or if
|
||||
* it already existed before. This is only relevant if O_CREAT is set without O_EXCL, and thus will
|
||||
* shortcut to openat() otherwise */
|
||||
|
||||
if (!ret_newly_created)
|
||||
return RET_NERRNO(openat(dirfd, pathname, flags, mode));
|
||||
* shortcut to openat() otherwise.
|
||||
*
|
||||
* Note that this routine is a bit more strict with symlinks than regular openat() is. If O_NOFOLLOW
|
||||
* is not specified, then we'll follow the symlink when opening an existing file but we will *not*
|
||||
* follow it when creating a new one (because that's a terrible UNIX misfeature and generally a
|
||||
* security hole). */
|
||||
|
||||
if (!FLAGS_SET(flags, O_CREAT) || FLAGS_SET(flags, O_EXCL)) {
|
||||
fd = openat(dirfd, pathname, flags, mode);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
*ret_newly_created = FLAGS_SET(flags, O_CREAT);
|
||||
if (ret_newly_created)
|
||||
*ret_newly_created = FLAGS_SET(flags, O_CREAT);
|
||||
return fd;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
for (unsigned attempts = 7;;) {
|
||||
/* First, attempt to open without O_CREAT/O_EXCL, i.e. open existing file */
|
||||
fd = openat(dirfd, pathname, flags & ~(O_CREAT | O_EXCL), mode);
|
||||
if (fd >= 0) {
|
||||
*ret_newly_created = false;
|
||||
if (ret_newly_created)
|
||||
*ret_newly_created = false;
|
||||
return fd;
|
||||
}
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
/* So the file didn't exist yet, hence create it with O_CREAT/O_EXCL. */
|
||||
fd = openat(dirfd, pathname, flags | O_CREAT | O_EXCL, mode);
|
||||
/* So the file didn't exist yet, hence create it with O_CREAT/O_EXCL/O_NOFOLLOW. */
|
||||
fd = openat(dirfd, pathname, flags | O_CREAT | O_EXCL | O_NOFOLLOW, mode);
|
||||
if (fd >= 0) {
|
||||
*ret_newly_created = true;
|
||||
if (ret_newly_created)
|
||||
*ret_newly_created = true;
|
||||
return fd;
|
||||
}
|
||||
if (errno != EEXIST)
|
||||
return -errno;
|
||||
|
||||
/* Hmm, so now we got EEXIST? This can indicate two things. First, if the path points to a
|
||||
* dangling symlink, the first openat() will fail with ENOENT because the symlink is resolved
|
||||
* and the second openat() will fail with EEXIST because symlinks are not followed when
|
||||
* O_CREAT|O_EXCL is specified. Let's check for this explicitly and fall back to opening with
|
||||
* just O_CREAT and assume we're the ones that created the file. */
|
||||
|
||||
struct stat st;
|
||||
if (fstatat(dirfd, pathname, &st, AT_SYMLINK_NOFOLLOW) < 0)
|
||||
return -errno;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
fd = openat(dirfd, pathname, flags | O_CREAT, mode);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
*ret_newly_created = true;
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* If we're not operating on a symlink, someone might have created the file between the first
|
||||
* and second call to openat(). Let's try again but with a limit so we don't spin forever. */
|
||||
/* Hmm, so now we got EEXIST? Then someone might have created the file between the first and
|
||||
* second call to openat(). Let's try again but with a limit so we don't spin forever. */
|
||||
|
||||
if (--attempts == 0) /* Give up eventually, somebody is playing with us */
|
||||
return -EEXIST;
|
||||
@ -1164,10 +1149,14 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
return fd_reopen(dir_fd, open_flags & ~O_NOFOLLOW);
|
||||
}
|
||||
|
||||
bool call_label_ops_post = false;
|
||||
|
||||
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
|
||||
r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
call_label_ops_post = true;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(open_flags, O_DIRECTORY|O_CREAT)) {
|
||||
@ -1183,37 +1172,19 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
else
|
||||
made_dir = true;
|
||||
|
||||
if (FLAGS_SET(xopen_flags, XO_LABEL)) {
|
||||
r = label_ops_post(dir_fd, path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
open_flags &= ~(O_EXCL|O_CREAT);
|
||||
xopen_flags &= ~XO_LABEL;
|
||||
}
|
||||
|
||||
fd = RET_NERRNO(openat_report_new(dir_fd, path, open_flags, mode, &made_file));
|
||||
fd = openat_report_new(dir_fd, path, open_flags, mode, &made_file);
|
||||
if (fd < 0) {
|
||||
if (IN_SET(fd,
|
||||
/* We got ENOENT? then someone else immediately removed it after we
|
||||
* created it. In that case let's return immediately without unlinking
|
||||
* anything, because there simply isn't anything to unlink anymore. */
|
||||
-ENOENT,
|
||||
/* is a symlink? exists already → created by someone else, don't unlink */
|
||||
-ELOOP,
|
||||
/* not a directory? exists already → created by someone else, don't unlink */
|
||||
-ENOTDIR))
|
||||
return fd;
|
||||
|
||||
if (made_dir)
|
||||
(void) unlinkat(dir_fd, path, AT_REMOVEDIR);
|
||||
|
||||
return fd;
|
||||
r = fd;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
|
||||
r = label_ops_post(dir_fd, path);
|
||||
if (call_label_ops_post) {
|
||||
call_label_ops_post = false;
|
||||
|
||||
r = label_ops_post(fd, /* path= */ NULL, made_file || made_dir);
|
||||
if (r < 0)
|
||||
goto error;
|
||||
}
|
||||
@ -1227,6 +1198,9 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
return TAKE_FD(fd);
|
||||
|
||||
error:
|
||||
if (call_label_ops_post)
|
||||
(void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : path, made_dir || made_file);
|
||||
|
||||
if (made_dir || made_file)
|
||||
(void) unlinkat(dir_fd, path, made_dir ? AT_REMOVEDIR : 0);
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "gunicode.h"
|
||||
#include "macro.h"
|
||||
|
||||
#define unichar uint32_t
|
||||
|
||||
@ -92,7 +93,7 @@ unichar_iswide (unichar c)
|
||||
{0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
|
||||
};
|
||||
|
||||
if (bsearch ((void *)(uintptr_t)c, wide, (sizeof (wide) / sizeof ((wide)[0])), sizeof wide[0],
|
||||
if (bsearch ((void *)(uintptr_t)c, wide, ELEMENTSOF(wide), sizeof wide[0],
|
||||
interval_compare))
|
||||
return true;
|
||||
|
||||
|
@ -4,10 +4,13 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "label.h"
|
||||
#include "macro.h"
|
||||
|
||||
static const LabelOps *label_ops = NULL;
|
||||
|
||||
int label_ops_set(const LabelOps *ops) {
|
||||
assert(ops);
|
||||
|
||||
if (label_ops)
|
||||
return -EBUSY;
|
||||
|
||||
@ -15,6 +18,10 @@ int label_ops_set(const LabelOps *ops) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void label_ops_reset(void) {
|
||||
label_ops = NULL;
|
||||
}
|
||||
|
||||
int label_ops_pre(int dir_fd, const char *path, mode_t mode) {
|
||||
if (!label_ops || !label_ops->pre)
|
||||
return 0;
|
||||
@ -22,13 +29,9 @@ int label_ops_pre(int dir_fd, const char *path, mode_t mode) {
|
||||
return label_ops->pre(dir_fd, path, mode);
|
||||
}
|
||||
|
||||
int label_ops_post(int dir_fd, const char *path) {
|
||||
int label_ops_post(int dir_fd, const char *path, bool created) {
|
||||
if (!label_ops || !label_ops->post)
|
||||
return 0;
|
||||
|
||||
return label_ops->post(dir_fd, path);
|
||||
}
|
||||
|
||||
void label_ops_reset(void) {
|
||||
label_ops = NULL;
|
||||
return label_ops->post(dir_fd, path, created);
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct LabelOps {
|
||||
int (*pre)(int dir_fd, const char *path, mode_t mode);
|
||||
int (*post)(int dir_fd, const char *path);
|
||||
int (*post)(int dir_fd, const char *path, bool created);
|
||||
} LabelOps;
|
||||
|
||||
int label_ops_set(const LabelOps *label_ops);
|
||||
void label_ops_reset(void);
|
||||
|
||||
int label_ops_pre(int dir_fd, const char *path, mode_t mode);
|
||||
int label_ops_post(int dir_fd, const char *path);
|
||||
void label_ops_reset(void);
|
||||
int label_ops_post(int dir_fd, const char *path, bool created);
|
||||
|
@ -530,7 +530,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
|
||||
/* Our EFI stub measures VirtualSize bytes of the .linux section into PCR 11.
|
||||
* Notably, VirtualSize can be larger than the section's size on disk. In
|
||||
* that case the extra space is initialized with zeros, so the stub ends up
|
||||
* measuring a bunch of zeros. To accomodate this, we have to measure the
|
||||
* measuring a bunch of zeros. To accommodate this, we have to measure the
|
||||
* same number of zeros here. We opt to measure extra zeros here instead of
|
||||
* modifying the stub to only measure the number of bytes on disk as we want
|
||||
* newer ukify + systemd-measure to work with older versions of the stub and
|
||||
|
@ -59,7 +59,6 @@ typedef enum MountMode {
|
||||
MOUNT_BIND,
|
||||
MOUNT_BIND_RECURSIVE,
|
||||
MOUNT_PRIVATE_TMP,
|
||||
MOUNT_PRIVATE_TMP_READ_ONLY,
|
||||
MOUNT_PRIVATE_DEV,
|
||||
MOUNT_BIND_DEV,
|
||||
MOUNT_EMPTY_DIR,
|
||||
@ -221,7 +220,7 @@ static const MountEntry protect_system_full_table[] = {
|
||||
* left writable, as ProtectHome= shall manage those, orthogonally).
|
||||
*/
|
||||
static const MountEntry protect_system_strict_table[] = {
|
||||
{ "/", MOUNT_READ_ONLY, false },
|
||||
{ "/", MOUNT_READ_ONLY, false },
|
||||
{ "/proc", MOUNT_READ_WRITE_IMPLICIT, false }, /* ProtectKernelTunables= */
|
||||
{ "/sys", MOUNT_READ_WRITE_IMPLICIT, false }, /* ProtectKernelTunables= */
|
||||
{ "/dev", MOUNT_READ_WRITE_IMPLICIT, false }, /* PrivateDevices= */
|
||||
@ -243,7 +242,6 @@ static const char * const mount_mode_table[_MOUNT_MODE_MAX] = {
|
||||
[MOUNT_BIND] = "bind",
|
||||
[MOUNT_BIND_RECURSIVE] = "bind-recursive",
|
||||
[MOUNT_PRIVATE_TMP] = "private-tmp",
|
||||
[MOUNT_PRIVATE_TMP_READ_ONLY] = "private-tmp-read-only",
|
||||
[MOUNT_PRIVATE_DEV] = "private-dev",
|
||||
[MOUNT_BIND_DEV] = "bind-dev",
|
||||
[MOUNT_EMPTY_DIR] = "empty-dir",
|
||||
@ -280,7 +278,7 @@ static const struct {
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(mount_mode, MountMode);
|
||||
|
||||
static const char *mount_entry_path(const MountEntry *p) {
|
||||
static const char* mount_entry_path(const MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
/* Returns the path of this bind mount. If the malloc()-allocated ->path_buffer field is set we return that,
|
||||
@ -289,7 +287,7 @@ static const char *mount_entry_path(const MountEntry *p) {
|
||||
return p->path_malloc ?: p->path_const;
|
||||
}
|
||||
|
||||
static const char *mount_entry_unprefixed_path(const MountEntry *p) {
|
||||
static const char* mount_entry_unprefixed_path(const MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
/* Returns the unprefixed path (ie: before prefix_where_needed() ran), if any */
|
||||
@ -315,7 +313,7 @@ static void mount_entry_consume_prefix(MountEntry *p, char *new_path) {
|
||||
static bool mount_entry_read_only(const MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
return p->read_only || IN_SET(p->mode, MOUNT_READ_ONLY, MOUNT_INACCESSIBLE, MOUNT_PRIVATE_TMP_READ_ONLY);
|
||||
return p->read_only || IN_SET(p->mode, MOUNT_READ_ONLY, MOUNT_INACCESSIBLE);
|
||||
}
|
||||
|
||||
static bool mount_entry_noexec(const MountEntry *p) {
|
||||
@ -330,13 +328,13 @@ static bool mount_entry_exec(const MountEntry *p) {
|
||||
return p->exec || p->mode == MOUNT_EXEC;
|
||||
}
|
||||
|
||||
static const char *mount_entry_source(const MountEntry *p) {
|
||||
static const char* mount_entry_source(const MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
return p->source_malloc ?: p->source_const;
|
||||
}
|
||||
|
||||
static const char *mount_entry_options(const MountEntry *p) {
|
||||
static const char* mount_entry_options(const MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
return p->options_malloc ?: p->options_const;
|
||||
@ -363,7 +361,7 @@ static void mount_list_done(MountList *ml) {
|
||||
ml->n_mounts = 0;
|
||||
}
|
||||
|
||||
static MountEntry *mount_list_extend(MountList *ml) {
|
||||
static MountEntry* mount_list_extend(MountList *ml) {
|
||||
assert(ml);
|
||||
|
||||
if (!GREEDY_REALLOC0(ml->mounts, ml->n_mounts+1))
|
||||
@ -714,11 +712,16 @@ static int append_static_mounts(MountList *ml, const MountEntry *mounts, size_t
|
||||
if (!me)
|
||||
return log_oom_debug();
|
||||
|
||||
*me = (MountEntry) {
|
||||
.path_const = mount_entry_path(m),
|
||||
.mode = m->mode,
|
||||
.ignore = m->ignore || ignore_protect,
|
||||
};
|
||||
/* No dynamic values allowed. */
|
||||
assert(m->path_const);
|
||||
assert(!m->path_malloc);
|
||||
assert(!m->unprefixed_path_malloc);
|
||||
assert(!m->source_malloc);
|
||||
assert(!m->options_malloc);
|
||||
assert(!m->overlay_layers);
|
||||
|
||||
*me = *m;
|
||||
me->ignore = me->ignore || ignore_protect;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1741,7 +1744,6 @@ static int apply_one_mount(
|
||||
return mount_tmpfs(m);
|
||||
|
||||
case MOUNT_PRIVATE_TMP:
|
||||
case MOUNT_PRIVATE_TMP_READ_ONLY:
|
||||
what = mount_entry_source(m);
|
||||
make = true;
|
||||
break;
|
||||
@ -2397,29 +2399,27 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) {
|
||||
assert(p->private_tmp == PRIVATE_TMP_CONNECTED);
|
||||
|
||||
if (p->tmp_dir) {
|
||||
bool ro = streq(p->tmp_dir, RUN_SYSTEMD_EMPTY);
|
||||
|
||||
MountEntry *me = mount_list_extend(&ml);
|
||||
if (!me)
|
||||
return log_oom_debug();
|
||||
|
||||
*me = (MountEntry) {
|
||||
.path_const = "/tmp",
|
||||
.mode = ro ? MOUNT_PRIVATE_TMP_READ_ONLY : MOUNT_PRIVATE_TMP,
|
||||
.mode = MOUNT_PRIVATE_TMP,
|
||||
.read_only = streq(p->tmp_dir, RUN_SYSTEMD_EMPTY),
|
||||
.source_const = p->tmp_dir,
|
||||
};
|
||||
}
|
||||
|
||||
if (p->var_tmp_dir) {
|
||||
bool ro = streq(p->var_tmp_dir, RUN_SYSTEMD_EMPTY);
|
||||
|
||||
MountEntry *me = mount_list_extend(&ml);
|
||||
if (!me)
|
||||
return log_oom_debug();
|
||||
|
||||
*me = (MountEntry) {
|
||||
.path_const = "/var/tmp",
|
||||
.mode = ro ? MOUNT_PRIVATE_TMP_READ_ONLY : MOUNT_PRIVATE_TMP,
|
||||
.mode = MOUNT_PRIVATE_TMP,
|
||||
.read_only = streq(p->var_tmp_dir, RUN_SYSTEMD_EMPTY),
|
||||
.source_const = p->var_tmp_dir,
|
||||
};
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "bpf-socket-bind.h"
|
||||
#include "bus-util.h"
|
||||
#include "dbus.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "parse-util.h"
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "exec-credential.h"
|
||||
#include "execute.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "id128-util.h"
|
||||
@ -4620,7 +4619,7 @@ int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const ch
|
||||
return r;
|
||||
}
|
||||
|
||||
r = write_string_file_atomic_label(q, wrapped);
|
||||
r = write_string_file(q, wrapped, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "dropin.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "generator.h"
|
||||
#include "initrd-util.h"
|
||||
#include "parse-util.h"
|
||||
@ -206,7 +206,7 @@ static int process_unit_credentials(const char *credentials_dir) {
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
r = write_string_file_at_label(AT_FDCWD, p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
|
||||
r = write_string_file(p, d, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to write unit file '%s' from credential '%s', ignoring: %m",
|
||||
unit, de->d_name);
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "env-file-label.h"
|
||||
#include "env-file.h"
|
||||
#include "env-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "hostname-setup.h"
|
||||
#include "hostname-util.h"
|
||||
@ -619,7 +618,7 @@ static int context_write_data_static_hostname(Context *c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = write_string_file_atomic_label("/etc/hostname", c->data[PROP_STATIC_HOSTNAME]);
|
||||
r = write_string_file("/etc/hostname", c->data[PROP_STATIC_HOSTNAME], WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "env-file.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "kbd-util.h"
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "escape.h"
|
||||
#include "event-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
@ -1593,7 +1592,7 @@ static int trigger_device(Manager *m, sd_device *parent) {
|
||||
|
||||
static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus_error *error) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
|
||||
_cleanup_free_ char *rule = NULL, *file = NULL;
|
||||
_cleanup_free_ char *file = NULL;
|
||||
const char *id_for_seat;
|
||||
int r;
|
||||
|
||||
@ -1614,11 +1613,10 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs, sd_bus
|
||||
if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
(void) mkdir_p_label("/etc/udev/rules.d", 0755);
|
||||
r = write_string_file_atomic_label(file, rule);
|
||||
r = write_string_filef(
|
||||
file,
|
||||
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL,
|
||||
"TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -3286,11 +3284,9 @@ static int method_set_reboot_to_boot_loader_menu(
|
||||
if (unlink("/run/systemd/reboot-to-boot-loader-menu") < 0 && errno != ENOENT)
|
||||
return -errno;
|
||||
} else {
|
||||
char buf[DECIMAL_STR_MAX(uint64_t) + 1];
|
||||
|
||||
xsprintf(buf, "%" PRIu64, x); /* μs granularity */
|
||||
|
||||
r = write_string_file_atomic_label("/run/systemd/reboot-to-boot-loader-menu", buf);
|
||||
r = write_string_filef("/run/systemd/reboot-to-boot-loader-menu",
|
||||
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL,
|
||||
"%" PRIu64, x); /* μs granularity */
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -3479,7 +3475,7 @@ static int method_set_reboot_to_boot_loader_entry(
|
||||
if (unlink("/run/systemd/reboot-to-boot-loader-entry") < 0 && errno != ENOENT)
|
||||
return -errno;
|
||||
} else {
|
||||
r = write_string_file_atomic_label("/run/systemd/reboot-boot-to-loader-entry", v);
|
||||
r = write_string_file("/run/systemd/reboot-boot-to-loader-entry", v, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -109,6 +109,40 @@ static int property_get_idle_hint(
|
||||
return sd_bus_message_append(reply, "b", session_get_idle_hint(s, NULL) > 0);
|
||||
}
|
||||
|
||||
static int property_get_can_idle(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Session *s = ASSERT_PTR(userdata);
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "b", SESSION_CLASS_CAN_IDLE(s->class));
|
||||
}
|
||||
|
||||
static int property_get_can_lock(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Session *s = ASSERT_PTR(userdata);
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "b", SESSION_CLASS_CAN_LOCK(s->class));
|
||||
}
|
||||
|
||||
static int property_get_idle_since_hint(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@ -855,14 +889,11 @@ int session_send_lock_all(Manager *m, bool lock) {
|
||||
assert(m);
|
||||
|
||||
HASHMAP_FOREACH(session, m->sessions) {
|
||||
int k;
|
||||
|
||||
if (!SESSION_CLASS_CAN_LOCK(session->class))
|
||||
continue;
|
||||
|
||||
k = session_send_lock(session, lock);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
RET_GATHER(r, session_send_lock(session, lock));
|
||||
}
|
||||
|
||||
return r;
|
||||
@ -983,6 +1014,8 @@ static const sd_bus_vtable session_vtable[] = {
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("CanIdle", "b", property_get_can_idle, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CanLock", "b", property_get_can_lock, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LockedHint", "b", property_get_locked_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
||||
SD_BUS_METHOD("Terminate",
|
||||
|
@ -1098,6 +1098,9 @@ int session_get_idle_hint(Session *s, dual_timestamp *t) {
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!SESSION_CLASS_CAN_IDLE(s->class))
|
||||
return false;
|
||||
|
||||
/* Graphical sessions have an explicit idle hint */
|
||||
if (SESSION_TYPE_IS_GRAPHICAL(s->type)) {
|
||||
if (t)
|
||||
|
@ -601,11 +601,11 @@ static void serialize_resolvers(
|
||||
|
||||
r = sd_dhcp_lease_get_dnr(lease, &resolvers);
|
||||
if (r < 0)
|
||||
return (void) log_warning_errno(r, "Failed to get DNR from DHCP lease, ignoring.");
|
||||
return (void) log_debug_errno(r, "Failed to get DNR from DHCP lease, ignoring: %m");
|
||||
|
||||
r = dns_resolvers_to_dot_strv(resolvers, r, &names);
|
||||
if (r < 0)
|
||||
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCP DNR, ignoring.");
|
||||
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCP DNR, ignoring: %m");
|
||||
if (r > 0)
|
||||
fputstrv(f, names, NULL, space);
|
||||
}
|
||||
@ -617,11 +617,11 @@ static void serialize_resolvers(
|
||||
|
||||
r = sd_dhcp6_lease_get_dnr(lease6, &resolvers);
|
||||
if (r < 0)
|
||||
return (void) log_warning_errno(r, "Failed to get DNR from DHCPv6 lease, ignoring.");
|
||||
return (void) log_debug_errno(r, "Failed to get DNR from DHCPv6 lease, ignoring: %m");
|
||||
|
||||
r = dns_resolvers_to_dot_strv(resolvers, r, &names);
|
||||
if (r < 0)
|
||||
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCPv6 DNR, ignoring.");
|
||||
return (void) log_warning_errno(r, "Failed to get DoT servers from DHCPv6 DNR, ignoring: %m");
|
||||
if (r > 0)
|
||||
fputstrv(f, names, NULL, space);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "dropin.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "hashmap.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
@ -87,7 +87,7 @@ int write_drop_in(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return write_string_file_at_label(AT_FDCWD, p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755);
|
||||
return write_string_file(p, data, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MKDIR_0755|WRITE_STRING_FILE_LABEL);
|
||||
}
|
||||
|
||||
int write_drop_in_format(
|
||||
|
@ -1,43 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "selinux-util.h"
|
||||
|
||||
int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
|
||||
int r;
|
||||
|
||||
r = mac_selinux_create_file_prepare_at(atfd, fn, S_IFREG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = write_string_file_full(atfd, fn, line, flags, ts);
|
||||
|
||||
mac_selinux_create_file_clear();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int create_shutdown_run_nologin_or_warn(void) {
|
||||
int r;
|
||||
|
||||
/* This is used twice: once in systemd-user-sessions.service, in order to block logins when we
|
||||
* actually go down, and once in systemd-logind.service when shutdowns are scheduled, and logins are
|
||||
* to be turned off a bit in advance. We use the same wording of the message in both cases.
|
||||
*
|
||||
* Traditionally, there was only /etc/nologin, and we managed that. Then, in PAM 1.1
|
||||
* support for /run/nologin was added as alternative
|
||||
* (https://github.com/linux-pam/linux-pam/commit/e9e593f6ddeaf975b7fe8446d184e6bc387d450b).
|
||||
* 13 years later we stopped managing /etc/nologin, leaving it for the administrator to manage.
|
||||
*/
|
||||
|
||||
r = write_string_file_atomic_label("/run/nologin",
|
||||
"System is going down. Unprivileged users are not permitted to log in anymore. "
|
||||
"For technical details, see pam_nologin(8).");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create /run/nologin: %m");
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* These functions are split out of fileio.h (and not for example just flags to the functions they wrap) in order to
|
||||
* optimize linking: This way, -lselinux is needed only for the callers of these functions that need selinux, but not
|
||||
* for all */
|
||||
|
||||
#include "fileio.h"
|
||||
|
||||
int write_string_file_full_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
|
||||
static inline int write_string_file_at_label(int atfd, const char *fn, const char *line, WriteStringFileFlags flags) {
|
||||
return write_string_file_full_label(atfd, fn, line, flags, /* ts= */ NULL);
|
||||
}
|
||||
static inline int write_string_file_atomic_label(const char *fn, const char *line) {
|
||||
return write_string_file_at_label(AT_FDCWD, fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
|
||||
}
|
||||
|
||||
int create_shutdown_run_nologin_or_warn(void);
|
@ -72,7 +72,6 @@ shared_sources = files(
|
||||
'extension-util.c',
|
||||
'fdset.c',
|
||||
'fido2-util.c',
|
||||
'fileio-label.c',
|
||||
'find-esp.c',
|
||||
'firewall-util-nft.c',
|
||||
'firewall-util.c',
|
||||
|
@ -204,3 +204,26 @@ bool kexec_loaded(void) {
|
||||
|
||||
return s[0] == '1';
|
||||
}
|
||||
|
||||
int create_shutdown_run_nologin_or_warn(void) {
|
||||
int r;
|
||||
|
||||
/* This is used twice: once in systemd-user-sessions.service, in order to block logins when we
|
||||
* actually go down, and once in systemd-logind.service when shutdowns are scheduled, and logins are
|
||||
* to be turned off a bit in advance. We use the same wording of the message in both cases.
|
||||
*
|
||||
* Traditionally, there was only /etc/nologin, and we managed that. Then, in PAM 1.1
|
||||
* support for /run/nologin was added as alternative
|
||||
* (https://github.com/linux-pam/linux-pam/commit/e9e593f6ddeaf975b7fe8446d184e6bc387d450b).
|
||||
* 13 years later we stopped managing /etc/nologin, leaving it for the administrator to manage.
|
||||
*/
|
||||
|
||||
r = write_string_file("/run/nologin",
|
||||
"System is going down. Unprivileged users are not permitted to log in anymore. "
|
||||
"For technical details, see pam_nologin(8).",
|
||||
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create /run/nologin: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool reboot_parameter_is_valid(const char *parameter);
|
||||
int update_reboot_parameter_and_warn(const char *parameter, bool keep);
|
||||
|
||||
@ -16,3 +18,5 @@ int reboot_with_parameter(RebootFlags flags);
|
||||
bool shall_restore_state(void);
|
||||
|
||||
bool kexec_loaded(void);
|
||||
|
||||
int create_shutdown_run_nologin_or_warn(void);
|
||||
|
@ -64,7 +64,7 @@ static int mac_selinux_label_pre(int dir_fd, const char *path, mode_t mode) {
|
||||
return mac_selinux_create_file_prepare_at(dir_fd, path, mode);
|
||||
}
|
||||
|
||||
static int mac_selinux_label_post(int dir_fd, const char *path) {
|
||||
static int mac_selinux_label_post(int dir_fd, const char *path, bool created) {
|
||||
mac_selinux_create_file_clear();
|
||||
return 0;
|
||||
}
|
||||
|
@ -294,7 +294,10 @@ static int mac_smack_label_pre(int dir_fd, const char *path, mode_t mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mac_smack_label_post(int dir_fd, const char *path) {
|
||||
static int mac_smack_label_post(int dir_fd, const char *path, bool created) {
|
||||
if (!created)
|
||||
return 0;
|
||||
|
||||
return mac_smack_fix_full(dir_fd, path, NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -670,6 +670,9 @@ TEST(openat_report_new) {
|
||||
|
||||
ASSERT_OK_ERRNO(symlinkat("target", tfd, "link"));
|
||||
fd = openat_report_new(tfd, "link", O_RDWR|O_CREAT, 0666, &b);
|
||||
ASSERT_ERROR(fd, EEXIST);
|
||||
|
||||
fd = openat_report_new(tfd, "target", O_RDWR|O_CREAT, 0666, &b);
|
||||
ASSERT_OK(fd);
|
||||
fd = safe_close(fd);
|
||||
ASSERT_TRUE(b);
|
||||
|
@ -286,9 +286,8 @@ TEST(id128_at) {
|
||||
ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
|
||||
ASSERT_OK(id128_write_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, id));
|
||||
ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
|
||||
ASSERT_OK(id128_write_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, id));
|
||||
ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
|
||||
ASSERT_OK(id128_write_at(tfd, "etc2/hoge-id", ID128_FORMAT_PLAIN, id));
|
||||
ASSERT_ERROR(id128_write_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, id), EEXIST);
|
||||
ASSERT_OK(id128_write_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, id));
|
||||
|
||||
/* id128_read_at() */
|
||||
i = SD_ID128_NULL; /* Not necessary in real code, but for testing that the id is really assigned. */
|
||||
|
@ -43,7 +43,7 @@ static int pre_labelling_func(int dir_fd, const char *path, mode_t mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int post_labelling_func(int dir_fd, const char *path) {
|
||||
static int post_labelling_func(int dir_fd, const char *path, bool created) {
|
||||
int r;
|
||||
|
||||
/* assume label policies that restrict certain labels */
|
||||
@ -140,17 +140,17 @@ TEST(label_ops_post) {
|
||||
text1 = "Add initial texts to file for testing label operations to file1\n";
|
||||
|
||||
assert(labelling_op(fd, text1, "file1.txt", 0644) == 0);
|
||||
assert_se(label_ops_post(fd, "file1.txt") == 0);
|
||||
assert_se(label_ops_post(fd, "file1.txt", true) == 0);
|
||||
assert_se(strlen(text1) == (size_t)buf.st_size);
|
||||
text2 = "Add text2 data to file2\n";
|
||||
|
||||
assert(labelling_op(fd, text2, "file2.txt", 0644) == 0);
|
||||
assert_se(label_ops_post(fd, "file2.txt") == 0);
|
||||
assert_se(label_ops_post(fd, "file2.txt", true) == 0);
|
||||
assert_se(strlen(text2) == (size_t)buf.st_size);
|
||||
assert_se(label_ops_post(fd, "file3.txt") == -ENOENT);
|
||||
assert_se(label_ops_post(fd, "/abcd") == -ENOENT);
|
||||
assert_se(label_ops_post(fd, "/restricted_directory") == -EACCES);
|
||||
assert_se(label_ops_post(fd, "") == -EINVAL);
|
||||
assert_se(label_ops_post(fd, "file3.txt", true) == -ENOENT);
|
||||
assert_se(label_ops_post(fd, "/abcd", true) == -ENOENT);
|
||||
assert_se(label_ops_post(fd, "/restricted_directory", true) == -EACCES);
|
||||
assert_se(label_ops_post(fd, "", true) == -EINVAL);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO)
|
||||
|
@ -74,16 +74,15 @@ TEST(tpm2_util_pbkdf2_hmac_sha256) {
|
||||
};
|
||||
|
||||
uint8_t res[SHA256_DIGEST_SIZE];
|
||||
for (size_t i = 0; i < sizeof(test_vectors)/sizeof(test_vectors[0]); i++) {
|
||||
|
||||
FOREACH_ELEMENT(vector, test_vectors) {
|
||||
int rc = tpm2_util_pbkdf2_hmac_sha256(
|
||||
test_vectors[i].pass,
|
||||
test_vectors[i].passlen,
|
||||
test_vectors[i].salt,
|
||||
test_vectors[i].saltlen,
|
||||
vector->pass,
|
||||
vector->passlen,
|
||||
vector->salt,
|
||||
vector->saltlen,
|
||||
res);
|
||||
assert_se(rc == 0);
|
||||
assert_se(memcmp(test_vectors[i].expected, res, SHA256_DIGEST_SIZE) == 0);
|
||||
assert_se(memcmp(vector->expected, res, SHA256_DIGEST_SIZE) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "constants.h"
|
||||
#include "daemon-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "hashmap.h"
|
||||
@ -395,7 +394,7 @@ static int context_write_data_local_rtc(Context *c) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return write_string_file_atomic_label("/etc/adjtime", w);
|
||||
return write_string_file("/etc/adjtime", w, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
}
|
||||
|
||||
static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m) {
|
||||
|
@ -557,7 +557,6 @@ static int do_scsi_page83_inquiry(struct scsi_id_device *dev_scsi, int fd,
|
||||
char *unit_serial_number, char *wwn,
|
||||
char *wwn_vendor_extension, char *tgpt_group) {
|
||||
int retval;
|
||||
unsigned id_ind, j;
|
||||
unsigned char page_83[SCSI_INQ_BUFF_LEN];
|
||||
|
||||
/* also pick up the page 80 serial number */
|
||||
@ -611,16 +610,14 @@ static int do_scsi_page83_inquiry(struct scsi_id_device *dev_scsi, int fd,
|
||||
* Search for a match in the prioritized id_search_list - since WWN ids
|
||||
* come first we can pick up the WWN in check_fill_0x83_id().
|
||||
*/
|
||||
for (id_ind = 0;
|
||||
id_ind < sizeof(id_search_list)/sizeof(id_search_list[0]);
|
||||
id_ind++) {
|
||||
FOREACH_ELEMENT(search_value, id_search_list) {
|
||||
/*
|
||||
* Examine each descriptor returned. There is normally only
|
||||
* one or a small number of descriptors.
|
||||
*/
|
||||
for (j = 4; j <= ((unsigned)page_83[2] << 8) + (unsigned)page_83[3] + 3; j += page_83[j + 3] + 4) {
|
||||
for (unsigned j = 4; j <= ((unsigned)page_83[2] << 8) + (unsigned)page_83[3] + 3; j += page_83[j + 3] + 4) {
|
||||
retval = check_fill_0x83_id(dev_scsi, page_83 + j,
|
||||
id_search_list + id_ind,
|
||||
search_value,
|
||||
serial, serial_short, len,
|
||||
wwn, wwn_vendor_extension,
|
||||
tgpt_group);
|
||||
|
@ -356,7 +356,7 @@ static bool test_key(
|
||||
i * BITS_PER_LONG, yes_no(found));
|
||||
}
|
||||
/* If there are no keys in the lower block, check the higher blocks */
|
||||
for (size_t block = 0; block < sizeof(high_key_blocks) / sizeof(struct range) && !found; block++)
|
||||
for (size_t block = 0; block < ELEMENTSOF(high_key_blocks) && !found; block++)
|
||||
for (unsigned i = high_key_blocks[block].start; i < high_key_blocks[block].end && !found; i++)
|
||||
if (test_bit(i, bitmask_key)) {
|
||||
log_device_debug(dev, "test_key: Found key %x in high block", i);
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fileio.h"
|
||||
#include "selinux-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
@ -29,7 +29,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
|
||||
timespec_load_nsec(ts)) < 0)
|
||||
return log_oom();
|
||||
|
||||
r = write_string_file_full_label(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC, ts);
|
||||
r = write_string_file_full(AT_FDCWD, path, message, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL, ts);
|
||||
if (r == -EROFS)
|
||||
log_debug_errno(r, "Cannot create \"%s\", file system is read-only.", path);
|
||||
else if (r < 0)
|
||||
|
@ -6,11 +6,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "fileio.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fs-util.h"
|
||||
#include "main-func.h"
|
||||
#include "log.h"
|
||||
#include "main-func.h"
|
||||
#include "reboot-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
|
@ -55,13 +55,22 @@ if [[ -z "${COVERAGE_BUILD_DIR:-}" ]]; then
|
||||
bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test ! -e $MARK"
|
||||
systemd-run --wait --pipe -p ProtectHome=read-only \
|
||||
bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test -e $MARK"
|
||||
systemd-run --wait --pipe -p ProtectHome=tmpfs \
|
||||
bash -xec "test -w /home; test -w /root; test -w /run/user; test ! -e $MARK"
|
||||
systemd-run --wait --pipe -p ProtectHome=tmpfs -p TemporaryFileSystem=/home/foo \
|
||||
bash -xec "test ! -w /home; test ! -w /root; test ! -w /run/user; test ! -e $MARK; test -w /home/foo"
|
||||
systemd-run --wait --pipe -p ProtectHome=no \
|
||||
bash -xec "test -w /home; test -w /root; test -w /run/user; test -e $MARK"
|
||||
rm -f "$MARK"
|
||||
fi
|
||||
|
||||
systemd-run --wait --pipe -p PrivateMounts=true -p MountAPIVFS=yes \
|
||||
bash -xec '[[ "$(findmnt --mountpoint /proc --noheadings -o FSTYPE)" == proc ]];
|
||||
[[ "$$(findmnt --mountpoint /dev --noheadings -o FSTYPE)" =~ (devtmpfs|tmpfs) ]];
|
||||
[[ "$$(findmnt --mountpoint /sys --noheadings -o FSTYPE)" =~ (sysfs|tmpfs) ]];
|
||||
[[ "$$(findmnt --mountpoint /run --noheadings -o FSTYPE)" == tmpfs ]];
|
||||
[[ "$$(findmnt --mountpoint /run --noheadings -o VFS-OPTIONS)" =~ rw ]];
|
||||
[[ "$$(findmnt --mountpoint /run --noheadings -o VFS-OPTIONS)" =~ nosuid ]];
|
||||
[[ "$$(findmnt --mountpoint /run --noheadings -o VFS-OPTIONS)" =~ nodev ]]'
|
||||
|
||||
if proc_supports_option "hidepid=off"; then
|
||||
systemd-run --wait --pipe -p ProtectProc=noaccess -p User=testuser \
|
||||
bash -xec 'test -e /proc/1; test ! -r /proc/1; test -r /proc/$$$$/comm'
|
||||
|
@ -575,6 +575,8 @@ testcase_list_users_sessions_seats() {
|
||||
session=$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $1 }')
|
||||
: check that we got a valid session id
|
||||
busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session Id
|
||||
busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session CanIdle
|
||||
busctl get-property org.freedesktop.login1 "/org/freedesktop/login1/session/_3${session?}" org.freedesktop.login1.Session CanLock
|
||||
assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $2 }')" "$(id -ru logind-test-user)"
|
||||
seat=$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $4 }')
|
||||
assert_eq "$(loginctl list-sessions --no-legend | grep -v manager | awk '$3 == "logind-test-user" { print $6 }')" user
|
||||
|
@ -226,7 +226,7 @@ EOF
|
||||
}
|
||||
|
||||
testcase_duration_override() {
|
||||
# Verify memory pressure duration can be overriden to non-zero values
|
||||
# Verify memory pressure duration can be overridden to non-zero values
|
||||
mkdir -p /run/systemd/system/TEST-55-OOMD-testmunch.service.d/
|
||||
cat >/run/systemd/system/TEST-55-OOMD-testmunch.service.d/99-duration-test.conf <<EOF
|
||||
[Service]
|
||||
|
Loading…
Reference in New Issue
Block a user