Compare commits

..

12 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 67f5b9e06e
Merge pull request #14003 from keszybz/user-path-configurable
meson: make user $PATH configurable
2019-11-14 10:08:40 +01:00
Lennart Poettering e013e10d0e ask-password: don't hit assert() when we query pw which the user C-d and caching is enabled 2019-11-14 10:04:11 +01:00
Dimitri John Ledkov 07d5ed536e boot: Add ARM64 support to the EFI stub 2019-11-14 10:03:08 +01:00
Zbigniew Jędrzejewski-Szmek a079077340
Merge pull request #14013 from keszybz/cryptsetup-keyfile-with-colons
Support cryptsetup keyfiles with colons agains
2019-11-14 10:02:20 +01:00
Dimitri John Ledkov 53a2045521 boot: Load LoadOptions cmdline, if none is available.
Fixes #13694
2019-11-14 10:01:20 +01:00
Zbigniew Jędrzejewski-Szmek 5bc655cd20 meson: avoid ternary op in .format()
meson 0.49 can't parse that for some reason. I'm keeping this separate so it
can be reverted easily when we bump required meson version.
2019-11-13 22:34:33 +01:00
Zbigniew Jędrzejewski-Szmek 3602ca6f0c meson: make user $PATH configurable
This partially reverts db11487d10 (the logic to
calculate the correct value is removed, we always use the same setting as for
the system manager). Distributions have an easy mechanism to override this if
they wish.

I think making this configurable is better, because different distros clearly
want different defaults here, and making this configurable is nice and clean.
If we don't make it configurable, distros which either have to carry patches,
or what would be worse, rely on some other configuration mechanism, like
/etc/profile. Those other solutions do not apply everywhere (they usually
require the shell to be used at some point), so it is better if we provide
a nice way to override the default.

Fixes  #13469.
2019-11-13 22:34:14 +01:00
Zbigniew Jędrzejewski-Szmek 1f6597a84c man: mention $RUNTIME_DIRECTORY & friends in environment list 2019-11-13 22:05:11 +01:00
Zbigniew Jędrzejewski-Szmek ed4ad48897 Allow overriding /etc/fstab with $SYSTEMD_FSTAB 2019-11-13 22:04:51 +01:00
Zbigniew Jędrzejewski-Szmek 32c6237a7c cryptsetup-generator: guess whether the keyfile argument is two items or one
Fixes #13615.

See the inline comment for documentation.
2019-11-13 22:04:45 +01:00
Zbigniew Jędrzejewski-Szmek 3f5ac3038e cryptsetup-generator: allow overriding /run/systemd/cryptsetup with $RUNTIME_DIRECTORY
I added a fairly vague entry to docs/ENVIRONMENT because I think it is worth
mentioning there (in case someone is looking for any environment variable that
might be relevant).
2019-11-13 22:04:38 +01:00
Zbigniew Jędrzejewski-Szmek a6c57e74c5 cryptsetup-generator: allow overriding crypttab path with $SYSTEMD_CRYPTAB 2019-11-13 17:55:51 +01:00
15 changed files with 127 additions and 58 deletions

View File

@ -41,6 +41,12 @@ All tools:
debugging, in order to test generators and other code against specific kernel
command lines.
* `$SYSTEMD_FSTAB` — if set, use this path instead of /etc/fstab. Only useful
for debugging.
* `$SYSTEMD_CRYPTTAB` — if set, use this path instead of /etc/crypttab. Only
useful for debugging. Currently only supported by systemd-cryptsetup-generator.
* `$SYSTEMD_EFI_OPTIONS` — if set, used instead of the string in SystemdOptions
EFI variable. Analogous to `$SYSTEMD_PROC_CMDLINE`.
@ -61,6 +67,10 @@ All tools:
this only controls use of Unicode emoji glyphs, and has no effect on other
Unicode glyphs.
* `$RUNTIME_DIRECTORY` — various tools use this variable to locate the
appropriate path under /run. This variable is also set by the manager when
RuntimeDirectory= is used, see systemd.exec(5).
systemctl:
* `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus

View File

@ -2384,10 +2384,9 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
in the system manager. When compiled for systems with "unmerged /usr" (<filename>/bin</filename> is
not a symlink to <filename>/usr/bin</filename>),
<literal>:<filename>/sbin</filename>:<filename>/bin</filename></literal> is appended. In case of the
the user manager, each <filename>bin/</filename> and <filename>sbin/</filename> pair is switched, so
that programs from <filename>/usr/bin</filename> have higher priority than programs from
<filename>/usr/sbin</filename>, etc. It is recommended to not rely on this in any way, and have only
one program with a given name in <varname>$PATH</varname>.</para></listitem>
the user manager, a different path may be configured by the distribution. It is recommended to not
rely on the order of entries, and have only one program with a given name in
<varname>$PATH</varname>.</para></listitem>
</varlistentry>
<varlistentry>
@ -2436,6 +2435,20 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
information.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>$RUNTIME_DIRECTORY</varname></term>
<term><varname>$STATE_DIRECTORY</varname></term>
<term><varname>$CACHE_DIRECTORY</varname></term>
<term><varname>$LOGS_DIRECTORY</varname></term>
<term><varname>$CONFIGURATION_DIRECTORY</varname></term>
<listitem><para>Contains and absolute paths to the directories defined with
<varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>,
<varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>, and
<varname>ConfigurationDirectory=</varname> when those settings are used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>$MAINPID</varname></term>

View File

@ -834,6 +834,16 @@ conf.set10('ENABLE_DEBUG_SIPHASH', enable_debug_siphash)
conf.set10('VALGRIND', get_option('valgrind'))
conf.set10('LOG_TRACE', get_option('log-trace'))
default_user_path = get_option('user-path')
if default_user_path != ''
conf.set_quoted('DEFAULT_USER_PATH', default_user_path)
default_user_path_display = default_user_path
else
# meson 0.49 fails when ?: is used in .format()
default_user_path_display = '(same as system services)'
endif
#####################################################################
threads = dependency('threads')
@ -3129,6 +3139,7 @@ status = [
'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme),
'default KillUserProcesses setting: @0@'.format(kill_user_processes),
'default locale: @0@'.format(default_locale),
'default user $PATH: @0@'.format(default_user_path_display),
'systemd service watchdog: @0@'.format(watchdog_opt)]
alt_dns_servers = '\n '.join(dns_servers.split(' '))

View File

@ -59,6 +59,8 @@ option('valgrind', type : 'boolean', value : false,
description : 'do extra operations to avoid valgrind warnings')
option('log-trace', type : 'boolean', value : false,
description : 'enable low level debug logging')
option('user-path', type : 'string',
description : '$PATH to use for user sessions')
option('utmp', type : 'boolean',
description : 'support for utmp/wtmp log handling')

View File

@ -11,41 +11,37 @@
#include "time-util.h"
#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin"
#define PATH_SPLIT_BIN_SBIN(x) x "bin:" x "sbin"
#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0"
#define PATH_NORMAL_SBIN_BIN(x) x "bin"
#define PATH_NORMAL_BIN_SBIN(x) x "bin"
#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0"
#if HAVE_SPLIT_BIN
# define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x)
# define PATH_BIN_SBIN(x) PATH_SPLIT_BIN_SBIN(x)
# define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x)
#else
# define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x)
# define PATH_BIN_SBIN(x) PATH_NORMAL_BIN_SBIN(x)
# define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x)
#endif
#define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
#define DEFAULT_USER_PATH_NORMAL PATH_BIN_SBIN("/usr/local/") ":" PATH_BIN_SBIN("/usr/")
#define DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/")
#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/")
#define DEFAULT_USER_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_BIN_SBIN("/")
#define DEFAULT_PATH_SPLIT_USR_NULSTR DEFAULT_PATH_NORMAL_NULSTR PATH_SBIN_BIN_NULSTR("/")
#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/")
#if HAVE_SPLIT_USR
# define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
# define DEFAULT_USER_PATH DEFAULT_USER_PATH_SPLIT_USR
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_SPLIT_USR_NULSTR
#else
# define DEFAULT_PATH DEFAULT_PATH_NORMAL
# define DEFAULT_USER_PATH DEFAULT_USER_PATH_NORMAL
# define DEFAULT_PATH_NULSTR DEFAULT_PATH_NORMAL_NULSTR
#endif
#ifndef DEFAULT_USER_PATH
# define DEFAULT_USER_PATH DEFAULT_PATH
#endif
bool is_path(const char *p) _pure_;
int path_split_and_make_absolute(const char *p, char ***ret);
bool path_is_absolute(const char *p) _pure_;

View File

@ -30,6 +30,7 @@ struct DosFileHeader {
#define PE_HEADER_MACHINE_I386 0x014c
#define PE_HEADER_MACHINE_X64 0x8664
#define PE_HEADER_MACHINE_ARM64 0xaa64
struct PeFileHeader {
UINT16 Machine;
UINT16 NumberOfSections;
@ -75,6 +76,7 @@ EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs
/* PE32+ Subsystem type */
if (pe->FileHeader.Machine != PE_HEADER_MACHINE_X64 &&
pe->FileHeader.Machine != PE_HEADER_MACHINE_ARM64 &&
pe->FileHeader.Machine != PE_HEADER_MACHINE_I386)
return EFI_LOAD_ERROR;

View File

@ -62,8 +62,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
cmdline_len = szs[0];
/* if we are not in secure boot mode, accept a custom command line and replace the built-in one */
if (!secure && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *)loaded_image->LoadOptions > 0x1F) {
/* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
if ((!secure || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *)loaded_image->LoadOptions > 0x1F) {
CHAR16 *options;
CHAR8 *line;
UINTN i;

View File

@ -37,6 +37,8 @@ typedef struct crypto_device {
static const char *arg_dest = NULL;
static bool arg_enabled = true;
static bool arg_read_crypttab = true;
static const char *arg_crypttab = NULL;
static const char *arg_runtime_directory = NULL;
static bool arg_whitelist = false;
static Hashmap *arg_disks = NULL;
static char *arg_default_options = NULL;
@ -60,17 +62,36 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key
c = strrchr(keyspec, ':');
if (c) {
keyfile = strndup(keyspec, c-keyspec);
keydev = strdup(c + 1);
if (!keyfile || !keydev)
/* The keydev part has to be either an absolute path to device node (/dev/something,
* /dev/foo/something, or even possibly /dev/foo/something:part), or a fstab device
* specification starting with LABEL= or similar. The keyfile part has the same syntax.
*
* Let's try to guess if the second part looks like a keydev specification, or just part of a
* filename with a colon. fstab_node_to_udev_node() will convert the fstab device syntax to
* an absolute path. If we didn't get an absolute path, assume that it is just part of the
* first keyfile argument. */
keydev = fstab_node_to_udev_node(c + 1);
if (!keydev)
return log_oom();
} else {
if (path_is_absolute(keydev))
keyfile = strndup(keyspec, c-keyspec);
else {
log_debug("Keyspec argument contains a colon, but \"%s\" doesn't look like a device specification.\n"
"Assuming that \"%s\" is a single device specification.",
c + 1, keyspec);
keydev = mfree(keydev);
c = NULL;
}
}
if (!c)
/* No keydev specified */
keyfile = strdup(keyspec);
keydev = NULL;
if (!keyfile)
return log_oom();
}
if (!keyfile)
return log_oom();
*ret_keyfile = TAKE_PTR(keyfile);
*ret_keydev = TAKE_PTR(keydev);
@ -79,7 +100,7 @@ static int split_keyspec(const char *keyspec, char **ret_keyfile, char **ret_key
}
static int generate_keydev_mount(const char *name, const char *keydev, const char *keydev_timeout, bool canfail, char **unit, char **mount) {
_cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL;
_cleanup_free_ char *u = NULL, *where = NULL, *name_escaped = NULL, *device_unit = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
usec_t timeout_us;
@ -89,11 +110,11 @@ static int generate_keydev_mount(const char *name, const char *keydev, const cha
assert(unit);
assert(mount);
r = mkdir_parents("/run/systemd/cryptsetup", 0755);
r = mkdir_parents(arg_runtime_directory, 0755);
if (r < 0)
return r;
r = mkdir("/run/systemd/cryptsetup", 0700);
r = mkdir(arg_runtime_directory, 0700);
if (r < 0 && errno != EEXIST)
return -errno;
@ -101,7 +122,7 @@ static int generate_keydev_mount(const char *name, const char *keydev, const cha
if (!name_escaped)
return -ENOMEM;
where = strjoin("/run/systemd/cryptsetup/keydev-", name_escaped);
where = strjoin(arg_runtime_directory, "/keydev-", name_escaped);
if (!where)
return -ENOMEM;
@ -117,22 +138,18 @@ static int generate_keydev_mount(const char *name, const char *keydev, const cha
if (r < 0)
return r;
what = fstab_node_to_udev_node(keydev);
if (!what)
return -ENOMEM;
fprintf(f,
"[Unit]\n"
"DefaultDependencies=no\n\n"
"[Mount]\n"
"What=%s\n"
"Where=%s\n"
"Options=ro%s\n", what, where, canfail ? ",nofail" : "");
"Options=ro%s\n", keydev, where, canfail ? ",nofail" : "");
if (keydev_timeout) {
r = parse_sec_fix_0(keydev_timeout, &timeout_us);
if (r >= 0) {
r = unit_name_from_path(what, ".device", &device_unit);
r = unit_name_from_path(keydev, ".device", &device_unit);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@ -271,11 +288,12 @@ static int create_disk(
"[Unit]\n"
"Description=Cryptography Setup for %%I\n"
"Documentation=man:crypttab(5) man:systemd-cryptsetup-generator(8) man:systemd-cryptsetup@.service(8)\n"
"SourcePath=/etc/crypttab\n"
"SourcePath=%s\n"
"DefaultDependencies=no\n"
"Conflicts=umount.target\n"
"IgnoreOnIsolate=true\n"
"After=%s\n",
arg_crypttab,
netdev ? "remote-fs-pre.target" : "cryptsetup-pre.target");
if (password) {
@ -558,15 +576,15 @@ static int add_crypttab_devices(void) {
if (!arg_read_crypttab)
return 0;
r = fopen_unlocked("/etc/crypttab", "re", &f);
r = fopen_unlocked(arg_crypttab, "re", &f);
if (r < 0) {
if (errno != ENOENT)
log_error_errno(errno, "Failed to open /etc/crypttab: %m");
log_error_errno(errno, "Failed to open %s: %m", arg_crypttab);
return 0;
}
if (fstat(fileno(f), &st) < 0) {
log_error_errno(errno, "Failed to stat /etc/crypttab: %m");
log_error_errno(errno, "Failed to stat %s: %m", arg_crypttab);
return 0;
}
@ -578,7 +596,7 @@ static int add_crypttab_devices(void) {
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)
return log_error_errno(r, "Failed to read /etc/crypttab: %m");
return log_error_errno(r, "Failed to read %s: %m", arg_crypttab);
if (r == 0)
break;
@ -590,7 +608,7 @@ static int add_crypttab_devices(void) {
k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &keyspec, &options);
if (k < 2 || k > 4) {
log_error("Failed to parse /etc/crypttab:%u, ignoring.", crypttab_line);
log_error("Failed to parse %s:%u, ignoring.", arg_crypttab, crypttab_line);
continue;
}
@ -667,6 +685,9 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
assert_se(arg_dest = dest);
arg_crypttab = getenv("SYSTEMD_CRYPTTAB") ?: "/etc/crypttab";
arg_runtime_directory = getenv("RUNTIME_DIRECTORY") ?: "/run/systemd/cryptsetup";
arg_disks = hashmap_new(&crypt_device_hash_ops);
if (!arg_disks)
return log_oom();

View File

@ -15,6 +15,7 @@
#include "device-util.h"
#include "escape.h"
#include "fileio.h"
#include "fstab-util.h"
#include "log.h"
#include "main-func.h"
#include "mount-util.h"
@ -302,7 +303,7 @@ static char *disk_mount_point(const char *label) {
if (asprintf(&device, "/dev/mapper/%s", label) < 0)
return NULL;
f = setmntent("/etc/fstab", "re");
f = setmntent(fstab_path(), "re");
if (!f)
return NULL;

View File

@ -112,14 +112,16 @@ static int add_swap(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
r = generator_open_unit_file(arg_dest, "/etc/fstab", name, &f);
r = generator_open_unit_file(arg_dest, fstab_path(), name, &f);
if (r < 0)
return r;
fputs("[Unit]\n"
"SourcePath=/etc/fstab\n"
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
"[Swap]\n", f);
fprintf(f,
"[Unit]\n"
"SourcePath=%s\n"
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n\n"
"[Swap]\n",
fstab_path());
r = write_what(f, what);
if (r < 0)
@ -340,7 +342,7 @@ static int add_mount(
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
r = generator_open_unit_file(dest, "/etc/fstab", name, &f);
r = generator_open_unit_file(dest, fstab_path(), name, &f);
if (r < 0)
return r;
@ -463,7 +465,7 @@ static int add_mount(
f = safe_fclose(f);
r = generator_open_unit_file(dest, "/etc/fstab", automount_name, &f);
r = generator_open_unit_file(dest, fstab_path(), automount_name, &f);
if (r < 0)
return r;
@ -515,19 +517,19 @@ static int add_mount(
static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL;
const char *fstab_path;
const char *fstab;
struct mntent *me;
int r = 0;
fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab";
log_debug("Parsing %s...", fstab_path);
fstab = initrd ? "/sysroot/etc/fstab" : fstab_path();
log_debug("Parsing %s...", fstab);
f = setmntent(fstab_path, "re");
f = setmntent(fstab, "re");
if (!f) {
if (errno == ENOENT)
return 0;
return log_error_errno(errno, "Failed to open %s: %m", fstab_path);
return log_error_errno(errno, "Failed to open %s: %m", fstab);
}
while ((me = getmntent(f))) {
@ -606,7 +608,7 @@ static int parse_fstab(bool initrd) {
me->mnt_passno,
makefs*MAKEFS | growfs*GROWFS | noauto*NOAUTO | nofail*NOFAIL | automount*AUTOMOUNT,
post,
fstab_path);
fstab);
}
if (r >= 0 && k < 0)

View File

@ -9,6 +9,7 @@
#include "env-util.h"
#include "exit-status.h"
#include "fstab-util.h"
#include "log.h"
#include "main-func.h"
#include "mount-setup.h"
@ -86,10 +87,10 @@ static int run(int argc, char *argv[]) {
umask(0022);
f = setmntent("/etc/fstab", "re");
f = setmntent(fstab_path(), "re");
if (!f) {
if (errno != ENOENT)
return log_error_errno(errno, "Failed to open /etc/fstab: %m");
return log_error_errno(errno, "Failed to open %s: %m", fstab_path());
} else
while ((me = getmntent(f))) {
/* Remount the root fs, /usr, and all API VFSs */

View File

@ -105,10 +105,11 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
int r;
assert(keyname);
assert(passwords);
if (!(flags & ASK_PASSWORD_PUSH_CACHE))
return 0;
if (strv_isempty(passwords))
return 0;
r = lookup_key(keyname, &serial);
if (r >= 0) {
@ -147,7 +148,6 @@ static int add_to_keyring_and_log(const char *keyname, AskPasswordFlags flags, c
int r;
assert(keyname);
assert(passwords);
r = add_to_keyring(keyname, flags, passwords);
if (r < 0)

View File

@ -19,7 +19,7 @@ int fstab_has_fstype(const char *fstype) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
f = setmntent("/etc/fstab", "re");
f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;
@ -39,7 +39,7 @@ int fstab_is_mount_point(const char *mount) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
f = setmntent("/etc/fstab", "re");
f = setmntent(fstab_path(), "re");
if (!f)
return errno == ENOENT ? false : -errno;

View File

@ -31,3 +31,7 @@ static inline bool fstab_test_yes_no_option(const char *opts, const char *yes_no
}
char *fstab_node_to_udev_node(const char *p);
static inline const char* fstab_path(void) {
return secure_getenv("SYSTEMD_FSTAB") ?: "/etc/fstab";
}

View File

@ -15,6 +15,11 @@
#include "tests.h"
#include "util.h"
static void test_print_paths(void) {
log_info("DEFAULT_PATH=%s", DEFAULT_PATH);
log_info("DEFAULT_USER_PATH=%s", DEFAULT_USER_PATH);
}
#define test_path_compare(a, b, result) { \
assert_se(path_compare(a, b) == result); \
assert_se(path_compare(b, a) == -result); \
@ -659,6 +664,7 @@ static void test_path_startswith_strv(void) {
int main(int argc, char **argv) {
test_setup_logging(LOG_DEBUG);
test_print_paths();
test_path();
test_path_equal_root();
test_find_binary(argv[0]);