Merge pull request #15703 from poettering/homed-tweak-default-storage

homed: avoid double encryption
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-05-08 16:57:14 +02:00 committed by GitHub
commit f2a8372e37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 441 additions and 56 deletions

4
TODO
View File

@ -51,11 +51,11 @@ Features:
* homed: add a way to "adopt" a home directory, i.e. strip foreign signatures
and insert a local signature instead.
* Maybe expose path_is_encrypted() as a new ConditionPathIsEncrypted=?
* busctl: maybe expose a verb "ping" for pinging a dbus service to see if it
exists and responds.
* homed: add homed.conf setting DefaultStorage= or so
* homed: maybe pre-create ~/.cache as subvol so that it can have separate quota
easily?

View File

@ -51,6 +51,15 @@
<variablelist id='efi-variables' />
</refsect1>
<refsect1>
<title>Home Area/User Account directives</title>
<para>Directives for configuring home areas and user accounts via
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
<variablelist id='home-directives' />
</refsect1>
<refsect1>
<title>UDEV directives</title>

View File

@ -504,9 +504,9 @@
<listitem><para>Selects the storage mechanism to use for this home directory. Takes one of
<literal>luks</literal>, <literal>fscrypt</literal>, <literal>directory</literal>,
<literal>subvolume</literal>, <literal>cifs</literal>. For details about these mechanisms, see
above. If a new home directory is created and the storage type is not specifically specified defaults
to <literal>luks</literal> if supported, <literal>subvolume</literal> as first fallback if supported,
and <literal>directory</literal> if not.</para></listitem>
above. If a new home directory is created and the storage type is not specifically specified,
<citerefentry><refentrytitle>homed.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
defines which default storage to use.</para></listitem>
</varlistentry>
<varlistentry>
@ -525,9 +525,10 @@
<listitem><para>When LUKS2 storage is used configures the file system type to use inside the home
directory LUKS2 container. One of <literal>ext4</literal>, <literal>xfs</literal>,
<literal>btrfs</literal>. If not specified defaults to <literal>ext4</literal>. Note that
<literal>xfs</literal> is not recommended as its support for file system resizing is too
limited.</para></listitem>
<literal>btrfs</literal>. If not specified
<citerefentry><refentrytitle>homed.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
defines which default file system type to use. Note that <literal>xfs</literal> is not recommended as
its support for file system resizing is too limited.</para></listitem>
</varlistentry>
<varlistentry>
@ -837,6 +838,7 @@ homectl update lafcadio --pkcs11-token-uri=…</programlisting>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>homed.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>userdbctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>useradd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>

84
man/homed.conf.xml Normal file
View File

@ -0,0 +1,84 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1+ -->
<refentry id="homed.conf" conditional='ENABLE_RESOLVE'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>homed.conf</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>homed.conf</refentrytitle>
<manvolnum>5</manvolnum>
</refmeta>
<refnamediv>
<refname>homed.conf</refname>
<refname>homed.conf.d</refname>
<refpurpose>Home area/user account manager configuration files</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>/etc/systemd/homed.conf</filename></para>
<para><filename>/etc/systemd/homed.conf.d/*.conf</filename></para>
<para><filename>/run/systemd/homed.conf.d/*.conf</filename></para>
<para><filename>/usr/lib/systemd/homed.conf.d/*.conf</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>These configuration files control default parameters for home areas/user accounts created and
managed by
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
</refsect1>
<xi:include href="standard-conf.xml" xpointer="main-conf" />
<refsect1>
<title>Options</title>
<para>The following options are available in the <literal>[Home]</literal> section:</para>
<variablelist class='home-directives'>
<varlistentry>
<term><varname>DefaultStorage=</varname></term>
<listitem><para>The default storage to use for home areas. Takes one of <literal>luks</literal>,
<literal>fscrypt</literal>, <literal>directory</literal>, <literal>subvolume</literal>,
<literal>cifs</literal>. For details about these options, see
<citerefentry><refentrytitle>homectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If not
configured or assigned the empty string, the default storage is automatically determined: if not
running in a container enviroment and <filename>/home/</filename> is not itself encrypted, defaults
to <literal>luks</literal>. Otherwise defaults to <literal>subvolume</literal> if
<filename>/home/</filename> is on a btrfs file system, and <literal>directory</literal>
otherwise. Note that the storage selected on the <command>homectl</command> command line always takes
precedence.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>DefaultFileSystemType=</varname></term>
<listitem><para>When using <literal>luks</literal> as storage (see above), selects the default file
system to use inside the user's LUKS volume. Takes one of <literal>ext4</literal>,
<literal>xfs</literal> or <literal>btrfs</literal>. If not specified defaults to
<literal>ext4</literal>. This setting has no effect if a different storage mechanism is used. The
file system type selected on the <command>homectl</command> command line always takes
precedence.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -18,6 +18,7 @@ manpages = [
['file-hierarchy', '7', [], ''],
['halt', '8', ['poweroff', 'reboot'], ''],
['homectl', '1', [], 'ENABLE_HOMED'],
['homed.conf', '5', ['homed.conf.d'], 'ENABLE_RESOLVE'],
['hostname', '5', [], ''],
['hostnamectl', '1', [], 'ENABLE_HOSTNAMED'],
['hwdb', '7', [], 'ENABLE_HWDB'],

View File

@ -100,6 +100,7 @@
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>homed.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>homectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>pam_systemd_home</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>userdbctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>

View File

@ -1492,6 +1492,7 @@ meson_apply_m4 = find_program('tools/meson-apply-m4.sh')
includes = include_directories('src/basic',
'src/boot',
'src/home',
'src/shared',
'src/systemd',
'src/journal',

View File

@ -8,8 +8,10 @@
#include <unistd.h>
#include "alloc-util.h"
#include "blockdev-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "locale-util.h"
#include "log.h"
@ -1488,3 +1490,26 @@ int open_parent(const char *path, int flags, mode_t mode) {
return fd;
}
int path_is_encrypted(const char *path) {
_cleanup_free_ char *uuids = NULL;
char p[SYS_BLOCK_PATH_MAX("/dm/uuid")];
dev_t devt;
int r;
r = get_block_device(path, &devt);
if (r < 0)
return r;
if (r == 0) /* doesn't have a block device */
return false;
xsprintf_sys_block_path(p, "/dm/uuid", devt);
r = read_one_line_file(p, &uuids);
if (r == -ENOENT)
return false;
if (r < 0)
return r;
/* The DM device's uuid attribute is prefixed with "CRYPT-" if this is a dm-crypt device. */
return !!startswith(uuids, "CRYPT-");
}

View File

@ -122,3 +122,5 @@ int fsync_path_at(int at_fd, const char *path);
int syncfs_path(int atfd, const char *path);
int open_parent(const char *path, int flags, mode_t mode);
int path_is_encrypted(const char *path);

View File

@ -64,6 +64,12 @@ int suitable_image_path(const char *path) {
path_is_absolute(path);
}
bool supported_fstype(const char *fstype) {
/* Limit the set of supported file systems a bit, as protection against little tested kernel file
* systems. Also, we only support the resize ioctls for these file systems. */
return STR_IN_SET(fstype, "ext4", "btrfs", "xfs");
}
int split_user_name_realm(const char *t, char **ret_user_name, char **ret_realm) {
_cleanup_free_ char *user_name = NULL, *realm = NULL;
const char *c;

View File

@ -12,6 +12,8 @@ bool suitable_user_name(const char *name);
int suitable_realm(const char *realm);
int suitable_image_path(const char *path);
bool supported_fstype(const char *fstype);
int split_user_name_realm(const char *t, char **ret_user_name, char **ret_realm);
int bus_message_append_secret(sd_bus_message *m, UserRecord *secret);

51
src/home/homed-conf.c Normal file
View File

@ -0,0 +1,51 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "conf-parser.h"
#include "def.h"
#include "home-util.h"
#include "homed-conf.h"
int manager_parse_config_file(Manager *m) {
int r;
assert(m);
r = config_parse_many_nulstr(PKGSYSCONFDIR "/homed.conf",
CONF_PATHS_NULSTR("systemd/homed.conf.d"),
"Home\0",
config_item_perf_lookup, homed_gperf_lookup,
CONFIG_PARSE_WARN, m);
if (r < 0)
return r;
return 0;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_default_storage, user_storage, UserStorage, "Failed to parse default storage setting");
int config_parse_default_file_system_type(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char **s = data;
assert(rvalue);
assert(s);
if (!isempty(rvalue) && !supported_fstype(rvalue)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Unsupported file system, ignoring: %s", rvalue);
return 0;
}
return free_and_strdup_warn(s, empty_to_null(rvalue));
}

12
src/home/homed-conf.h Normal file
View File

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "conf-parser.h"
#include "homed-manager.h"
int manager_parse_config_file(Manager *m);
const struct ConfigPerfItem* homed_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
CONFIG_PARSER_PROTOTYPE(config_parse_default_storage);
CONFIG_PARSER_PROTOTYPE(config_parse_default_file_system_type);

View File

@ -0,0 +1,21 @@
%{
#if __GNUC__ >= 7
_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#endif
#include <stddef.h>
#include "conf-parser.h"
#include "homed-conf.h"
%}
struct ConfigPerfItem;
%null_strings
%language=ANSI-C
%define slot-name section_and_lvalue
%define hash-function-name homed_gperf_hash
%define lookup-function-name homed_gperf_lookup
%readonly-tables
%omit-struct-type
%struct-type
%includes
%%
Home.DefaultStorage, config_parse_default_storage, 0, offsetof(Manager, default_storage)
Home.DefaultFileSystemType, config_parse_default_file_system_type, 0, offsetof(Manager, default_file_system_type)

View File

@ -1011,6 +1011,18 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord
_exit(EXIT_FAILURE);
}
if (h->manager->default_storage >= 0)
if (setenv("SYSTEMD_HOME_DEFAULT_STORAGE", user_storage_to_string(h->manager->default_storage), 1) < 0) {
log_error_errno(errno, "Failed to set $SYSTEMD_HOME_DEFAULT_STORAGE: %m");
_exit(EXIT_FAILURE);
}
if (h->manager->default_file_system_type)
if (setenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE", h->manager->default_file_system_type, 1) < 0) {
log_error_errno(errno, "Failed to set $SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE: %m");
_exit(EXIT_FAILURE);
}
r = rearrange_stdio(stdin_fd, stdout_fd, STDERR_FILENO);
if (r < 0) {
log_error_errno(r, "Failed to rearrange stdin/stdout/stderr: %m");

View File

@ -24,6 +24,7 @@
#include "fs-util.h"
#include "gpt.h"
#include "home-util.h"
#include "homed-conf.h"
#include "homed-home-bus.h"
#include "homed-home.h"
#include "homed-manager-bus.h"
@ -184,10 +185,18 @@ int manager_new(Manager **ret) {
assert(ret);
m = new0(Manager, 1);
m = new(Manager, 1);
if (!m)
return -ENOMEM;
*m = (Manager) {
.default_storage = _USER_STORAGE_INVALID,
};
r = manager_parse_config_file(m);
if (r < 0)
return r;
r = sd_event_default(&m->event);
if (r < 0)
return r;
@ -251,6 +260,8 @@ Manager* manager_free(Manager *m) {
varlink_server_unref(m->varlink_server);
free(m->default_file_system_type);
return mfree(m);
}

View File

@ -28,6 +28,8 @@ struct Manager {
Hashmap *homes_by_sysfs;
bool scan_slash_home;
UserStorage default_storage;
char *default_file_system_type;
sd_event_source *inotify_event_source;

16
src/home/homed.conf Normal file
View File

@ -0,0 +1,16 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See homed.conf(5) for details
[Resolve]
#DefaultStorage=
#DefaultFileSystemType=ext4

View File

@ -16,6 +16,7 @@
#include "fileio.h"
#include "fs-util.h"
#include "fsck-util.h"
#include "home-util.h"
#include "homework-luks.h"
#include "homework-mount.h"
#include "id128-util.h"
@ -39,12 +40,6 @@
* strictly round disk sizes down to the next 1K boundary.*/
#define DISK_SIZE_ROUND_DOWN(x) ((x) & ~UINT64_C(1023))
static bool supported_fstype(const char *fstype) {
/* Limit the set of supported file systems a bit, as protection against little tested kernel file
* systems. Also, we only support the resize ioctls for these file systems. */
return STR_IN_SET(fstype, "ext4", "btrfs", "xfs");
}
static int probe_file_system_by_fd(
int fd,
char **ret_fstype,

View File

@ -7,6 +7,7 @@
#include "copy.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "home-util.h"
#include "homework-cifs.h"
#include "homework-directory.h"
@ -862,9 +863,68 @@ static int user_record_compile_effective_passwords(
return 0;
}
static int determine_default_storage(UserStorage *ret) {
UserStorage storage = _USER_STORAGE_INVALID;
const char *e;
int r;
assert(ret);
/* homed tells us via an environment variable which default storage to use */
e = getenv("SYSTEMD_HOME_DEFAULT_STORAGE");
if (e) {
storage = user_storage_from_string(e);
if (storage < 0)
log_warning("$SYSTEMD_HOME_DEFAULT_STORAGE set to invalid storage type, ignoring: %s", e);
else {
log_info("Using configured default storage '%s'.", user_storage_to_string(storage));
*ret = storage;
return 0;
}
}
/* When neither user nor admin specified the storage type to use, fix it to be LUKS — unless we run
* in a container where loopback devices and LUKS/DM are not available. Also, if /home is encrypted
* anyway, let's avoid duplicate encryption. Note that we typically default to the assumption of
* "classic" storage for most operations. However, if we create a new home, then let's user LUKS if
* nothing is specified. */
r = detect_container();
if (r < 0)
return log_error_errno(r, "Failed to determine whether we are in a container: %m");
if (r == 0) {
r = path_is_encrypted("/home");
if (r < 0)
log_warning_errno(r, "Failed to determine if /home is encrypted, ignoring: %m");
if (r <= 0) {
log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS));
*ret = USER_LUKS;
return 0;
}
log_info("/home is encrypted, not using '%s' storage, in order to avoid double encryption.", user_storage_to_string(USER_LUKS));
} else
log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS));
r = path_is_fs_type("/home", BTRFS_SUPER_MAGIC);
if (r < 0)
log_warning_errno(r, "Failed to determine file system of /home, ignoring: %m");
if (r > 0) {
log_info("/home is on btrfs, using '%s' as storage.", user_storage_to_string(USER_SUBVOLUME));
*ret = USER_SUBVOLUME;
} else {
log_info("/home is on simple file system, using '%s' as storage.", user_storage_to_string(USER_DIRECTORY));
*ret = USER_DIRECTORY;
}
return 0;
}
static int home_create(UserRecord *h, UserRecord **ret_home) {
_cleanup_(strv_free_erasep) char **effective_passwords = NULL, **pkcs11_decrypted_passwords = NULL;
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
UserStorage new_storage = _USER_STORAGE_INVALID;
const char *new_fs = NULL;
int r;
assert(h);
@ -884,27 +944,18 @@ static int home_create(UserRecord *h, UserRecord **ret_home) {
if (r != USER_TEST_ABSENT)
return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Home directory %s already exists, refusing.", user_record_home_directory(h));
/* When the user didn't specify the storage type to use, fix it to be LUKS -- unless we run in a
* container where loopback devices and LUKS/DM are not available. Note that we typically default to
* the assumption of "classic" storage for most operations. However, if we create a new home, then
* let's user LUKS if nothing is specified. */
if (h->storage < 0) {
UserStorage new_storage;
r = detect_container();
r = determine_default_storage(&new_storage);
if (r < 0)
return log_error_errno(r, "Failed to determine whether we are in a container: %m");
if (r > 0) {
new_storage = USER_DIRECTORY;
return r;
}
r = path_is_fs_type("/home", BTRFS_SUPER_MAGIC);
if (r < 0)
log_debug_errno(r, "Failed to determine file system of /home, ignoring: %m");
new_storage = r > 0 ? USER_SUBVOLUME : USER_DIRECTORY;
} else
new_storage = USER_LUKS;
if ((h->storage == USER_LUKS ||
(h->storage < 0 && new_storage == USER_LUKS)) &&
!h->file_system_type)
new_fs = getenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE");
if (new_storage >= 0 || new_fs) {
r = user_record_add_binding(
h,
new_storage,
@ -915,18 +966,12 @@ static int home_create(UserRecord *h, UserRecord **ret_home) {
NULL,
NULL,
UINT64_MAX,
NULL,
new_fs,
NULL,
UID_INVALID,
GID_INVALID);
if (r < 0)
return log_error_errno(r, "Failed to change storage type to LUKS: %m");
if (!h->image_path_auto) {
h->image_path_auto = strjoin("/home/", user_record_user_name_and_realm(h), new_storage == USER_LUKS ? ".home" : ".homedir");
if (!h->image_path_auto)
return log_oom();
}
}
r = user_record_test_image_path_and_warn(h);

View File

@ -31,6 +31,8 @@ systemd_homed_sources = files('''
home-util.h
homed-bus.c
homed-bus.h
homed-conf.c
homed-conf.h
homed-home-bus.c
homed-home-bus.h
homed-home.c
@ -52,6 +54,14 @@ systemd_homed_sources = files('''
user-record-util.h
'''.split())
homed_gperf_c = custom_target(
'homed_gperf.c',
input : 'homed-gperf.gperf',
output : 'homed-gperf.c',
command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
systemd_homed_sources += [homed_gperf_c]
homectl_sources = files('''
home-util.c
home-util.h
@ -78,4 +88,7 @@ if conf.get('ENABLE_HOMED') == 1
install_dir : dbussystemservicedir)
install_data('org.freedesktop.home1.policy',
install_dir : polkitpolicydir)
install_data('homed.conf',
install_dir : pkgsysconfdir)
endif

View File

@ -276,7 +276,7 @@ int user_record_add_binding(
_cleanup_(json_variant_unrefp) JsonVariant *new_binding_entry = NULL, *binding = NULL;
char smid[SD_ID128_STRING_MAX], partition_uuids[37], luks_uuids[37], fs_uuids[37];
_cleanup_free_ char *ip = NULL, *hd = NULL;
_cleanup_free_ char *ip = NULL, *hd = NULL, *ip_auto = NULL, *lc = NULL, *lcm = NULL, *fst = NULL;
sd_id128_t mid;
int r;
@ -294,6 +294,10 @@ int user_record_add_binding(
ip = strdup(image_path);
if (!ip)
return -ENOMEM;
} else if (!h->image_path && storage >= 0) {
r = user_record_build_image_path(storage, user_record_user_name_and_realm(h), &ip_auto);
if (r < 0)
return r;
}
if (home_directory) {
@ -302,6 +306,24 @@ int user_record_add_binding(
return -ENOMEM;
}
if (file_system_type) {
fst = strdup(file_system_type);
if (!fst)
return -ENOMEM;
}
if (luks_cipher) {
lc = strdup(luks_cipher);
if (!lc)
return -ENOMEM;
}
if (luks_cipher_mode) {
lcm = strdup(luks_cipher_mode);
if (!lcm)
return -ENOMEM;
}
r = json_build(&new_binding_entry,
JSON_BUILD_OBJECT(
JSON_BUILD_PAIR_CONDITION(!!image_path, "imagePath", JSON_BUILD_STRING(image_path)),
@ -348,6 +370,8 @@ int user_record_add_binding(
if (ip)
free_and_replace(h->image_path, ip);
if (ip_auto)
free_and_replace(h->image_path_auto, ip_auto);
if (!sd_id128_is_null(partition_uuid))
h->partition_uuid = partition_uuid;
@ -358,11 +382,22 @@ int user_record_add_binding(
if (!sd_id128_is_null(fs_uuid))
h->file_system_uuid = fs_uuid;
if (lc)
free_and_replace(h->luks_cipher, lc);
if (lcm)
free_and_replace(h->luks_cipher_mode, lcm);
if (luks_volume_key_size != UINT64_MAX)
h->luks_volume_key_size = luks_volume_key_size;
if (fst)
free_and_replace(h->file_system_type, fst);
if (hd)
free_and_replace(h->home_directory, hd);
if (uid_is_valid(uid))
h->uid = uid;
if (gid_is_valid(gid))
h->gid = gid;
h->mask |= USER_RECORD_BINDING;
return 1;

View File

@ -1059,7 +1059,34 @@ static int dispatch_status(const char *name, JsonVariant *variant, JsonDispatchF
return json_dispatch(m, status_dispatch_table, NULL, flags, userdata);
}
int user_record_build_image_path(UserStorage storage, const char *user_name_and_realm, char **ret) {
const char *suffix;
char *z;
assert(storage >= 0);
assert(user_name_and_realm);
assert(ret);
if (storage == USER_LUKS)
suffix = ".home";
else if (IN_SET(storage, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT))
suffix = ".homedir";
else {
*ret = NULL;
return 0;
}
z = strjoin("/home/", user_name_and_realm, suffix);
if (!z)
return -ENOMEM;
*ret = z;
return 1;
}
static int user_record_augment(UserRecord *h, JsonDispatchFlags json_flags) {
int r;
assert(h);
if (!FLAGS_SET(h->mask, USER_RECORD_REGULAR))
@ -1084,22 +1111,9 @@ static int user_record_augment(UserRecord *h, JsonDispatchFlags json_flags) {
}
if (!h->image_path && !h->image_path_auto) {
const char *suffix;
UserStorage storage;
storage = user_record_storage(h);
if (storage == USER_LUKS)
suffix = ".home";
else if (IN_SET(storage, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT))
suffix = ".homedir";
else
suffix = NULL;
if (suffix) {
h->image_path_auto = strjoin("/home/", user_record_user_name_and_realm(h), suffix);
if (!h->image_path_auto)
return json_log_oom(h->json, json_flags);
}
r = user_record_build_image_path(user_record_storage(h), user_record_user_name_and_realm(h), &h->image_path_auto);
if (r < 0)
return json_log(h->json, json_flags, r, "Failed to determine default image path: %m");
}
return 0;

View File

@ -349,6 +349,8 @@ usec_t user_record_ratelimit_interval_usec(UserRecord *h);
uint64_t user_record_ratelimit_burst(UserRecord *h);
bool user_record_can_authenticate(UserRecord *h);
int user_record_build_image_path(UserStorage storage, const char *user_name_and_realm, char **ret);
bool user_record_equal(UserRecord *a, UserRecord *b);
bool user_record_compatible(UserRecord *a, UserRecord *b);
int user_record_compare_last_change(UserRecord *a, UserRecord *b);

View File

@ -846,6 +846,28 @@ static void test_chmod_and_chown_unsafe(void) {
assert_se(S_ISLNK(st.st_mode));
}
static void test_path_is_encrypted_one(const char *p, int expect) {
int r;
r = path_is_encrypted(p);
assert_se(r >= 0);
printf("%s encrypted: %s\n", p, yes_no(r));
assert_se(expect < 0 || ((r > 0) == (expect > 0)));
}
static void test_path_is_encrypted(void) {
log_info("/* %s */", __func__);
test_path_is_encrypted_one("/home", -1);
test_path_is_encrypted_one("/var", -1);
test_path_is_encrypted_one("/", -1);
test_path_is_encrypted_one("/proc", false);
test_path_is_encrypted_one("/sys", false);
test_path_is_encrypted_one("/dev", false);
}
int main(int argc, char *argv[]) {
test_setup_logging(LOG_INFO);
@ -864,6 +886,7 @@ int main(int argc, char *argv[]) {
test_rename_noreplace();
test_chmod_and_chown();
test_chmod_and_chown_unsafe();
test_path_is_encrypted();
return 0;
}