1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include <linux/magic.h>
6 #include <openssl/pem.h>
12 #include "btrfs-util.h"
13 #include "bus-common-errors.h"
14 #include "bus-error.h"
15 #include "bus-log-control-api.h"
16 #include "bus-polkit.h"
17 #include "clean-ipc.h"
18 #include "conf-files.h"
19 #include "device-util.h"
20 #include "dirent-util.h"
23 #include "format-util.h"
26 #include "home-util.h"
27 #include "homed-conf.h"
28 #include "homed-home-bus.h"
29 #include "homed-home.h"
30 #include "homed-manager-bus.h"
31 #include "homed-manager.h"
32 #include "homed-varlink.h"
35 #include "process-util.h"
36 #include "quota-util.h"
37 #include "random-util.h"
38 #include "socket-util.h"
39 #include "stat-util.h"
41 #include "tmpfile-util.h"
42 #include "udev-util.h"
43 #include "user-record-sign.h"
44 #include "user-record-util.h"
45 #include "user-record.h"
46 #include "user-util.h"
48 /* Where to look for private/public keys that are used to sign the user records. We are not using
49 * CONF_PATHS_NULSTR() here since we want to insert /var/lib/systemd/home/ in the middle. And we insert that
50 * since we want to auto-generate a persistent private/public key pair if we need to. */
51 #define KEY_PATHS_NULSTR \
52 "/etc/systemd/home/\0" \
53 "/run/systemd/home/\0" \
54 "/var/lib/systemd/home/\0" \
55 "/usr/local/lib/systemd/home/\0" \
56 "/usr/lib/systemd/home/\0"
58 static bool uid_is_home(uid_t uid
) {
59 return uid
>= HOME_UID_MIN
&& uid
<= HOME_UID_MAX
;
61 /* Takes a value generated randomly or by hashing and turns it into a UID in the right range */
63 #define UID_CLAMP_INTO_HOME_RANGE(rnd) (((uid_t) (rnd) % (HOME_UID_MAX - HOME_UID_MIN + 1)) + HOME_UID_MIN)
65 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_uid_hash_ops
, void, trivial_hash_func
, trivial_compare_func
, Home
, home_free
);
66 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_name_hash_ops
, char, string_hash_func
, string_compare_func
, Home
, home_free
);
67 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_worker_pid_hash_ops
, void, trivial_hash_func
, trivial_compare_func
, Home
, home_free
);
68 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops
, char, path_hash_func
, path_compare
, Home
, home_free
);
70 static int on_home_inotify(sd_event_source
*s
, const struct inotify_event
*event
, void *userdata
);
71 static int manager_gc_images(Manager
*m
);
72 static int manager_enumerate_images(Manager
*m
);
73 static int manager_assess_image(Manager
*m
, int dir_fd
, const char *dir_path
, const char *dentry_name
);
74 static void manager_revalidate_image(Manager
*m
, Home
*h
);
76 static void manager_watch_home(Manager
*m
) {
82 m
->inotify_event_source
= sd_event_source_unref(m
->inotify_event_source
);
83 m
->scan_slash_home
= false;
85 if (statfs("/home/", &sfs
) < 0) {
86 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_WARNING
, errno
,
87 "Failed to statfs() /home/ directory, disabling automatic scanning.");
91 if (is_network_fs(&sfs
)) {
92 log_info("/home/ is a network file system, disabling automatic scanning.");
96 if (is_fs_type(&sfs
, AUTOFS_SUPER_MAGIC
)) {
97 log_info("/home/ is on autofs, disabling automatic scanning.");
101 m
->scan_slash_home
= true;
103 r
= sd_event_add_inotify(m
->event
, &m
->inotify_event_source
, "/home/", IN_CREATE
|IN_CLOSE_WRITE
|IN_DELETE_SELF
|IN_MOVE_SELF
|IN_ONLYDIR
|IN_MOVED_TO
|IN_MOVED_FROM
|IN_DELETE
, on_home_inotify
, m
);
105 log_full_errno(r
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
, r
,
106 "Failed to create inotify watch on /home/, ignoring.");
108 (void) sd_event_source_set_description(m
->inotify_event_source
, "home-inotify");
111 static int on_home_inotify(sd_event_source
*s
, const struct inotify_event
*event
, void *userdata
) {
112 Manager
*m
= userdata
;
118 if ((event
->mask
& (IN_Q_OVERFLOW
|IN_MOVE_SELF
|IN_DELETE_SELF
|IN_IGNORED
|IN_UNMOUNT
)) != 0) {
120 if (FLAGS_SET(event
->mask
, IN_Q_OVERFLOW
))
121 log_debug("/home/ inotify queue overflow, rescanning.");
122 else if (FLAGS_SET(event
->mask
, IN_MOVE_SELF
))
123 log_info("/home/ moved or renamed, recreating watch and rescanning.");
124 else if (FLAGS_SET(event
->mask
, IN_DELETE_SELF
))
125 log_info("/home/ deleted, recreating watch and rescanning.");
126 else if (FLAGS_SET(event
->mask
, IN_UNMOUNT
))
127 log_info("/home/ unmounted, recreating watch and rescanning.");
128 else if (FLAGS_SET(event
->mask
, IN_IGNORED
))
129 log_info("/home/ watch invalidated, recreating watch and rescanning.");
131 manager_watch_home(m
);
132 (void) manager_gc_images(m
);
133 (void) manager_enumerate_images(m
);
134 (void) bus_manager_emit_auto_login_changed(m
);
138 /* For the other inotify events, let's ignore all events for file names that don't match our
140 if (isempty(event
->name
))
142 e
= endswith(event
->name
, FLAGS_SET(event
->mask
, IN_ISDIR
) ? ".homedir" : ".home");
146 n
= strndupa(event
->name
, e
- event
->name
);
147 if (!suitable_user_name(n
))
150 if ((event
->mask
& (IN_CREATE
|IN_CLOSE_WRITE
|IN_MOVED_TO
)) != 0) {
151 if (FLAGS_SET(event
->mask
, IN_CREATE
))
152 log_debug("/home/%s has been created, having a look.", event
->name
);
153 else if (FLAGS_SET(event
->mask
, IN_CLOSE_WRITE
))
154 log_debug("/home/%s has been modified, having a look.", event
->name
);
155 else if (FLAGS_SET(event
->mask
, IN_MOVED_TO
))
156 log_debug("/home/%s has been moved in, having a look.", event
->name
);
158 (void) manager_assess_image(m
, -1, "/home/", event
->name
);
159 (void) bus_manager_emit_auto_login_changed(m
);
162 if ((event
->mask
& (IN_DELETE
|IN_MOVED_FROM
|IN_DELETE
)) != 0) {
165 if (FLAGS_SET(event
->mask
, IN_DELETE
))
166 log_debug("/home/%s has been deleted, revalidating.", event
->name
);
167 else if (FLAGS_SET(event
->mask
, IN_CLOSE_WRITE
))
168 log_debug("/home/%s has been closed after writing, revalidating.", event
->name
);
169 else if (FLAGS_SET(event
->mask
, IN_MOVED_FROM
))
170 log_debug("/home/%s has been moved away, revalidating.", event
->name
);
172 h
= hashmap_get(m
->homes_by_name
, n
);
174 manager_revalidate_image(m
, h
);
175 (void) bus_manager_emit_auto_login_changed(m
);
182 int manager_new(Manager
**ret
) {
183 _cleanup_(manager_freep
) Manager
*m
= NULL
;
193 .default_storage
= _USER_STORAGE_INVALID
,
196 r
= manager_parse_config_file(m
);
200 r
= sd_event_default(&m
->event
);
204 r
= sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
208 r
= sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
212 (void) sd_event_set_watchdog(m
->event
, true);
214 m
->homes_by_uid
= hashmap_new(&homes_by_uid_hash_ops
);
215 if (!m
->homes_by_uid
)
218 m
->homes_by_name
= hashmap_new(&homes_by_name_hash_ops
);
219 if (!m
->homes_by_name
)
222 m
->homes_by_worker_pid
= hashmap_new(&homes_by_worker_pid_hash_ops
);
223 if (!m
->homes_by_worker_pid
)
226 m
->homes_by_sysfs
= hashmap_new(&homes_by_sysfs_hash_ops
);
227 if (!m
->homes_by_sysfs
)
234 Manager
* manager_free(Manager
*m
) {
237 hashmap_free(m
->homes_by_uid
);
238 hashmap_free(m
->homes_by_name
);
239 hashmap_free(m
->homes_by_worker_pid
);
240 hashmap_free(m
->homes_by_sysfs
);
242 m
->inotify_event_source
= sd_event_source_unref(m
->inotify_event_source
);
244 bus_verify_polkit_async_registry_free(m
->polkit_registry
);
246 sd_bus_flush_close_unref(m
->bus
);
247 sd_event_unref(m
->event
);
249 m
->notify_socket_event_source
= sd_event_source_unref(m
->notify_socket_event_source
);
250 m
->device_monitor
= sd_device_monitor_unref(m
->device_monitor
);
252 m
->deferred_rescan_event_source
= sd_event_source_unref(m
->deferred_rescan_event_source
);
253 m
->deferred_gc_event_source
= sd_event_source_unref(m
->deferred_gc_event_source
);
254 m
->deferred_auto_login_event_source
= sd_event_source_unref(m
->deferred_auto_login_event_source
);
257 EVP_PKEY_free(m
->private_key
);
259 hashmap_free(m
->public_keys
);
261 varlink_server_unref(m
->varlink_server
);
263 free(m
->default_file_system_type
);
268 int manager_verify_user_record(Manager
*m
, UserRecord
*hr
) {
275 if (!m
->private_key
&& hashmap_isempty(m
->public_keys
)) {
276 r
= user_record_has_signature(hr
);
280 return r
? -ENOKEY
: USER_RECORD_UNSIGNED
;
284 if (m
->private_key
) {
285 r
= user_record_verify(hr
, m
->private_key
);
288 case USER_RECORD_FOREIGN
:
289 /* This record is not signed by this key, but let's see below */
292 case USER_RECORD_SIGNED
: /* Signed by us, but also by others, let's propagate that */
293 case USER_RECORD_SIGNED_EXCLUSIVE
: /* Signed by us, and nothing else, ditto */
294 case USER_RECORD_UNSIGNED
: /* Not signed at all, ditto */
300 HASHMAP_FOREACH(pkey
, m
->public_keys
) {
301 r
= user_record_verify(hr
, pkey
);
304 case USER_RECORD_FOREIGN
:
305 /* This record is not signed by this key, but let's see our other keys */
308 case USER_RECORD_SIGNED
: /* It's signed by this key we are happy with, but which is not our own. */
309 case USER_RECORD_SIGNED_EXCLUSIVE
:
310 return USER_RECORD_FOREIGN
;
312 case USER_RECORD_UNSIGNED
: /* It's not signed at all */
321 static int manager_add_home_by_record(
327 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
328 _cleanup_(user_record_unrefp
) UserRecord
*hr
= NULL
;
329 unsigned line
, column
;
338 if (fstatat(dir_fd
, fname
, &st
, 0) < 0)
339 return log_error_errno(errno
, "Failed to stat identity record %s: %m", fname
);
341 if (!S_ISREG(st
.st_mode
)) {
342 log_debug("Identity record file %s is not a regular file, ignoring.", fname
);
347 goto unlink_this_file
;
349 r
= json_parse_file_at(NULL
, dir_fd
, fname
, JSON_PARSE_SENSITIVE
, &v
, &line
, &column
);
351 return log_error_errno(r
, "Failed to parse identity record at %s:%u%u: %m", fname
, line
, column
);
353 if (json_variant_is_blank_object(v
))
354 goto unlink_this_file
;
356 hr
= user_record_new();
360 r
= user_record_load(hr
, v
, USER_RECORD_LOAD_REFUSE_SECRET
|USER_RECORD_LOG
);
364 if (!streq_ptr(hr
->user_name
, name
))
365 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Identity's user name %s does not match file name %s, refusing.", hr
->user_name
, name
);
367 is_signed
= manager_verify_user_record(m
, hr
);
371 return log_warning_errno(is_signed
, "User record %s is not signed by any accepted key, ignoring.", fname
);
372 case USER_RECORD_UNSIGNED
:
373 return log_warning_errno(SYNTHETIC_ERRNO(EPERM
), "User record %s is not signed at all, ignoring.", fname
);
374 case USER_RECORD_SIGNED
:
375 log_info("User record %s is signed by us (and others), accepting.", fname
);
377 case USER_RECORD_SIGNED_EXCLUSIVE
:
378 log_info("User record %s is signed only by us, accepting.", fname
);
380 case USER_RECORD_FOREIGN
:
381 log_info("User record %s is signed by registered key from others, accepting.", fname
);
384 assert(is_signed
< 0);
385 return log_error_errno(is_signed
, "Failed to verify signature of user record in %s: %m", fname
);
388 h
= hashmap_get(m
->homes_by_name
, name
);
390 r
= home_set_record(h
, hr
);
392 return log_error_errno(r
, "Failed to update home record for %s: %m", name
);
394 /* If we acquired a record now for a previously unallocated entry, then reset the state. This
395 * makes sure home_get_state() will check for the availability of the image file dynamically
396 * in order to detect to distinguish HOME_INACTIVE and HOME_ABSENT. */
397 if (h
->state
== HOME_UNFIXATED
)
398 h
->state
= _HOME_STATE_INVALID
;
400 r
= home_new(m
, hr
, NULL
, &h
);
402 return log_error_errno(r
, "Failed to allocate new home object: %m");
404 log_info("Added registered home for user %s.", hr
->user_name
);
407 /* Only entries we exclusively signed are writable to us, hence remember the result */
408 h
->signed_locally
= is_signed
== USER_RECORD_SIGNED_EXCLUSIVE
;
413 /* If this is an empty file, then let's just remove it. An empty file is not useful in any case, and
414 * apparently xfs likes to leave empty files around when not unmounted cleanly (see
415 * https://github.com/systemd/systemd/issues/15178 for example). Note that we don't delete non-empty
416 * files even if they are invalid, because that's just too risky, we might delete data the user still
417 * needs. But empty files are never useful, hence let's just remove them. */
419 if (unlinkat(dir_fd
, fname
, 0) < 0)
420 return log_error_errno(errno
, "Failed to remove empty user record file %s: %m", fname
);
422 log_notice("Discovered empty user record file /var/lib/systemd/home/%s, removed automatically.", fname
);
426 static int manager_enumerate_records(Manager
*m
) {
427 _cleanup_closedir_
DIR *d
= NULL
;
432 d
= opendir("/var/lib/systemd/home/");
434 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
435 "Failed to open /var/lib/systemd/home/: %m");
437 FOREACH_DIRENT(de
, d
, return log_error_errno(errno
, "Failed to read record directory: %m")) {
438 _cleanup_free_
char *n
= NULL
;
441 if (!dirent_is_file(de
))
444 e
= endswith(de
->d_name
, ".identity");
448 n
= strndup(de
->d_name
, e
- de
->d_name
);
452 if (!suitable_user_name(n
))
455 (void) manager_add_home_by_record(m
, n
, dirfd(d
), de
->d_name
);
461 static int search_quota(uid_t uid
, const char *exclude_quota_path
) {
462 struct stat exclude_st
= {};
463 dev_t previous_devno
= 0;
467 /* Checks whether the specified UID owns any files on the files system, but ignore any file system
468 * backing the specified file. The file is used when operating on home directories, where it's OK if
469 * the UID of them already owns files. */
471 if (exclude_quota_path
&& stat(exclude_quota_path
, &exclude_st
) < 0) {
473 return log_warning_errno(errno
, "Failed to stat %s, ignoring: %m", exclude_quota_path
);
476 /* Check a few usual suspects where regular users might own files. Note that this is by no means
477 * comprehensive, but should cover most cases. Note that in an ideal world every user would be
478 * registered in NSS and avoid our own UID range, but for all other cases, it's a good idea to be
479 * paranoid and check quota if we can. */
480 FOREACH_STRING(where
, "/home/", "/tmp/", "/var/", "/var/mail/", "/var/tmp/", "/var/spool/") {
484 if (stat(where
, &st
) < 0) {
485 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
486 "Failed to stat %s, ignoring: %m", where
);
490 if (major(st
.st_dev
) == 0) {
491 log_debug("Directory %s is not on a real block device, not checking quota for UID use.", where
);
495 if (st
.st_dev
== exclude_st
.st_dev
) { /* If an exclude path is specified, then ignore quota
496 * reported on the same block device as that path. */
497 log_debug("Directory %s is where the home directory is located, not checking quota for UID use.", where
);
501 if (st
.st_dev
== previous_devno
) { /* Does this directory have the same devno as the previous
502 * one we tested? If so, there's no point in testing this
504 log_debug("Directory %s is on same device as previous tested directory, not checking quota for UID use a second time.", where
);
508 previous_devno
= st
.st_dev
;
510 r
= quotactl_devno(QCMD_FIXED(Q_GETQUOTA
, USRQUOTA
), st
.st_dev
, uid
, &req
);
512 if (ERRNO_IS_NOT_SUPPORTED(r
))
513 log_debug_errno(r
, "No UID quota support on %s, ignoring.", where
);
514 else if (ERRNO_IS_PRIVILEGE(r
))
515 log_debug_errno(r
, "UID quota support for %s prohibited, ignoring.", where
);
517 log_warning_errno(r
, "Failed to query quota on %s, ignoring: %m", where
);
522 if ((FLAGS_SET(req
.dqb_valid
, QIF_SPACE
) && req
.dqb_curspace
> 0) ||
523 (FLAGS_SET(req
.dqb_valid
, QIF_INODES
) && req
.dqb_curinodes
> 0)) {
524 log_debug_errno(errno
, "Quota reports UID " UID_FMT
" occupies disk space on %s.", uid
, where
);
532 static int manager_acquire_uid(
535 const char *user_name
,
536 const char *exclude_quota_path
,
539 static const uint8_t hash_key
[] = {
540 0xa3, 0xb8, 0x82, 0x69, 0x9a, 0x71, 0xf7, 0xa9,
541 0xe0, 0x7c, 0xf6, 0xf1, 0x21, 0x69, 0xd2, 0x1e
548 } phase
= PHASE_SUGGESTED
;
550 unsigned n_tries
= 100;
567 case PHASE_SUGGESTED
:
568 phase
= PHASE_HASHED
;
570 if (!uid_is_home(start_uid
))
573 candidate
= start_uid
;
577 phase
= PHASE_RANDOM
;
582 candidate
= UID_CLAMP_INTO_HOME_RANGE(siphash24(user_name
, strlen(user_name
), hash_key
));
586 random_bytes(&candidate
, sizeof(candidate
));
587 candidate
= UID_CLAMP_INTO_HOME_RANGE(candidate
);
591 assert_not_reached("unknown phase");
594 other
= hashmap_get(m
->homes_by_uid
, UID_TO_PTR(candidate
));
596 log_debug("Candidate UID " UID_FMT
" already used by another home directory (%s), let's try another.", candidate
, other
->user_name
);
600 pw
= getpwuid(candidate
);
602 log_debug("Candidate UID " UID_FMT
" already registered by another user in NSS (%s), let's try another.", candidate
, pw
->pw_name
);
606 gr
= getgrgid((gid_t
) candidate
);
608 log_debug("Candidate UID " UID_FMT
" already registered by another group in NSS (%s), let's try another.", candidate
, gr
->gr_name
);
612 r
= search_ipc(candidate
, (gid_t
) candidate
);
616 log_debug_errno(r
, "Candidate UID " UID_FMT
" already owns IPC objects, let's try another: %m", candidate
);
620 r
= search_quota(candidate
, exclude_quota_path
);
629 static int manager_add_home_by_image(
631 const char *user_name
,
633 const char *image_path
,
638 _cleanup_(user_record_unrefp
) UserRecord
*hr
= NULL
;
648 assert(storage
>= 0);
649 assert(storage
< _USER_STORAGE_MAX
);
651 h
= hashmap_get(m
->homes_by_name
, user_name
);
655 if (h
->state
!= HOME_UNFIXATED
) {
656 log_debug("Found an image for user %s which already has a record, skipping.", user_name
);
657 return 0; /* ignore images that synthesize a user we already have a record for */
660 same
= user_record_storage(h
->record
) == storage
;
662 if (h
->sysfs
&& sysfs
)
663 same
= path_equal(h
->sysfs
, sysfs
);
664 else if (!!h
->sysfs
!= !!sysfs
)
669 p
= user_record_image_path(h
->record
);
670 same
= p
&& path_equal(p
, image_path
);
675 log_debug("Found multiple images for user '%s', ignoring image '%s'.", user_name
, image_path
);
679 /* Check NSS, in case there's another user or group by this name */
680 if (getpwnam(user_name
) || getgrnam(user_name
)) {
681 log_debug("Found an existing user or group by name '%s', ignoring image '%s'.", user_name
, image_path
);
686 if (h
&& uid_is_valid(h
->uid
))
689 r
= manager_acquire_uid(m
, start_uid
, user_name
, IN_SET(storage
, USER_SUBVOLUME
, USER_DIRECTORY
, USER_FSCRYPT
) ? image_path
: NULL
, &uid
);
691 return log_warning_errno(r
, "Failed to acquire unused UID for %s: %m", user_name
);
694 hr
= user_record_new();
698 r
= user_record_synthesize(hr
, user_name
, realm
, image_path
, storage
, uid
, (gid_t
) uid
);
700 return log_error_errno(r
, "Failed to synthesize home record for %s (image %s): %m", user_name
, image_path
);
703 r
= home_set_record(h
, hr
);
705 return log_error_errno(r
, "Failed to update home record for %s: %m", user_name
);
707 r
= home_new(m
, hr
, sysfs
, &h
);
709 return log_error_errno(r
, "Failed to allocate new home object: %m");
711 h
->state
= HOME_UNFIXATED
;
713 log_info("Discovered new home for user %s through image %s.", user_name
, image_path
);
719 int manager_augment_record_with_uid(
723 const char *exclude_quota_path
= NULL
;
724 uid_t start_uid
= UID_INVALID
, uid
;
730 if (uid_is_valid(hr
->uid
))
733 if (IN_SET(hr
->storage
, USER_CLASSIC
, USER_SUBVOLUME
, USER_DIRECTORY
, USER_FSCRYPT
)) {
736 ip
= user_record_image_path(hr
);
740 if (stat(ip
, &st
) < 0) {
742 log_warning_errno(errno
, "Failed to stat(%s): %m", ip
);
743 } else if (uid_is_home(st
.st_uid
)) {
744 start_uid
= st
.st_uid
;
745 exclude_quota_path
= ip
;
750 r
= manager_acquire_uid(m
, start_uid
, hr
->user_name
, exclude_quota_path
, &uid
);
754 log_debug("Acquired new UID " UID_FMT
" for %s.", uid
, hr
->user_name
);
756 r
= user_record_add_binding(
758 _USER_STORAGE_INVALID
,
776 static int manager_assess_image(
779 const char *dir_path
,
780 const char *dentry_name
) {
782 char *luks_suffix
, *directory_suffix
;
783 _cleanup_free_
char *path
= NULL
;
791 luks_suffix
= endswith(dentry_name
, ".home");
793 directory_suffix
= NULL
;
795 directory_suffix
= endswith(dentry_name
, ".homedir");
797 /* Early filter out: by name */
798 if (!luks_suffix
&& !directory_suffix
)
801 path
= path_join(dir_path
, dentry_name
);
805 /* Follow symlinks here, to allow people to link in stuff to make them available locally. */
807 r
= fstatat(dir_fd
, dentry_name
, &st
, 0);
811 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_WARNING
, errno
,
812 "Failed to stat() directory entry '%s', ignoring: %m", dentry_name
);
814 if (S_ISREG(st
.st_mode
)) {
815 _cleanup_free_
char *n
= NULL
, *user_name
= NULL
, *realm
= NULL
;
820 n
= strndup(dentry_name
, luks_suffix
- dentry_name
);
824 r
= split_user_name_realm(n
, &user_name
, &realm
);
825 if (r
== -EINVAL
) /* Not the right format: ignore */
828 return log_error_errno(r
, "Failed to split image name into user name/realm: %m");
830 return manager_add_home_by_image(m
, user_name
, realm
, path
, NULL
, USER_LUKS
, UID_INVALID
);
833 if (S_ISDIR(st
.st_mode
)) {
834 _cleanup_free_
char *n
= NULL
, *user_name
= NULL
, *realm
= NULL
;
835 _cleanup_close_
int fd
= -1;
838 if (!directory_suffix
)
841 n
= strndup(dentry_name
, directory_suffix
- dentry_name
);
845 r
= split_user_name_realm(n
, &user_name
, &realm
);
846 if (r
== -EINVAL
) /* Not the right format: ignore */
849 return log_error_errno(r
, "Failed to split image name into user name/realm: %m");
852 fd
= openat(dir_fd
, dentry_name
, O_DIRECTORY
|O_RDONLY
|O_CLOEXEC
);
854 fd
= open(path
, O_DIRECTORY
|O_RDONLY
|O_CLOEXEC
);
856 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_WARNING
, errno
,
857 "Failed to open directory '%s', ignoring: %m", path
);
859 if (fstat(fd
, &st
) < 0)
860 return log_warning_errno(errno
, "Failed to fstat() %s, ignoring: %m", path
);
862 assert(S_ISDIR(st
.st_mode
)); /* Must hold, we used O_DIRECTORY above */
864 r
= btrfs_is_subvol_fd(fd
);
866 return log_warning_errno(errno
, "Failed to determine whether %s is a btrfs subvolume: %m", path
);
868 storage
= USER_SUBVOLUME
;
870 struct fscrypt_policy policy
;
872 if (ioctl(fd
, FS_IOC_GET_ENCRYPTION_POLICY
, &policy
) < 0) {
874 if (errno
== ENODATA
)
875 log_debug_errno(errno
, "Determined %s is not fscrypt encrypted.", path
);
876 else if (ERRNO_IS_NOT_SUPPORTED(errno
))
877 log_debug_errno(errno
, "Determined %s is not fscrypt encrypted because kernel or file system doesn't support it.", path
);
879 log_debug_errno(errno
, "FS_IOC_GET_ENCRYPTION_POLICY failed with unexpected error code on %s, ignoring: %m", path
);
881 storage
= USER_DIRECTORY
;
883 storage
= USER_FSCRYPT
;
886 return manager_add_home_by_image(m
, user_name
, realm
, path
, NULL
, storage
, st
.st_uid
);
892 int manager_enumerate_images(Manager
*m
) {
893 _cleanup_closedir_
DIR *d
= NULL
;
898 if (!m
->scan_slash_home
)
901 d
= opendir("/home/");
903 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
904 "Failed to open /home/: %m");
906 FOREACH_DIRENT(de
, d
, return log_error_errno(errno
, "Failed to read /home/ directory: %m"))
907 (void) manager_assess_image(m
, dirfd(d
), "/home", de
->d_name
);
912 static int manager_connect_bus(Manager
*m
) {
918 r
= sd_bus_default_system(&m
->bus
);
920 return log_error_errno(r
, "Failed to connect to system bus: %m");
922 r
= bus_add_implementation(m
->bus
, &manager_object
, m
);
926 r
= sd_bus_request_name_async(m
->bus
, NULL
, "org.freedesktop.home1", 0, NULL
, NULL
);
928 return log_error_errno(r
, "Failed to request name: %m");
930 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
932 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
934 (void) sd_bus_set_exit_on_disconnect(m
->bus
, true);
939 static int manager_bind_varlink(Manager
*m
) {
943 assert(!m
->varlink_server
);
945 r
= varlink_server_new(&m
->varlink_server
, VARLINK_SERVER_ACCOUNT_UID
);
947 return log_error_errno(r
, "Failed to allocate varlink server object: %m");
949 varlink_server_set_userdata(m
->varlink_server
, m
);
951 r
= varlink_server_bind_method_many(
953 "io.systemd.UserDatabase.GetUserRecord", vl_method_get_user_record
,
954 "io.systemd.UserDatabase.GetGroupRecord", vl_method_get_group_record
,
955 "io.systemd.UserDatabase.GetMemberships", vl_method_get_memberships
);
957 return log_error_errno(r
, "Failed to register varlink methods: %m");
959 (void) mkdir_p("/run/systemd/userdb", 0755);
961 r
= varlink_server_listen_address(m
->varlink_server
, "/run/systemd/userdb/io.systemd.Home", 0666);
963 return log_error_errno(r
, "Failed to bind to varlink socket: %m");
965 r
= varlink_server_attach_event(m
->varlink_server
, m
->event
, SD_EVENT_PRIORITY_NORMAL
);
967 return log_error_errno(r
, "Failed to attach varlink connection to event loop: %m");
972 static ssize_t
read_datagram(int fd
, struct ucred
*ret_sender
, void **ret
) {
973 _cleanup_free_
void *buffer
= NULL
;
980 n
= next_datagram_size_fd(fd
);
984 buffer
= malloc(n
+ 2);
989 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred
))) control
;
990 bool found_ucred
= false;
991 struct cmsghdr
*cmsg
;
995 /* Pass one extra byte, as a size check */
996 iov
= IOVEC_MAKE(buffer
, n
+ 1);
998 mh
= (struct msghdr
) {
1001 .msg_control
= &control
,
1002 .msg_controllen
= sizeof(control
),
1005 m
= recvmsg_safe(fd
, &mh
, MSG_DONTWAIT
|MSG_CMSG_CLOEXEC
);
1009 cmsg_close_all(&mh
);
1011 /* Ensure the size matches what we determined before */
1015 CMSG_FOREACH(cmsg
, &mh
)
1016 if (cmsg
->cmsg_level
== SOL_SOCKET
&&
1017 cmsg
->cmsg_type
== SCM_CREDENTIALS
&&
1018 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct ucred
))) {
1020 memcpy(ret_sender
, CMSG_DATA(cmsg
), sizeof(struct ucred
));
1025 *ret_sender
= (struct ucred
) {
1031 m
= recv(fd
, buffer
, n
+ 1, MSG_DONTWAIT
);
1035 /* Ensure the size matches what we determined before */
1040 /* For safety reasons: let's always NUL terminate. */
1041 ((char*) buffer
)[n
] = 0;
1042 *ret
= TAKE_PTR(buffer
);
1047 static int on_notify_socket(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
1048 _cleanup_strv_free_
char **l
= NULL
;
1049 _cleanup_free_
void *datagram
= NULL
;
1050 struct ucred sender
;
1051 Manager
*m
= userdata
;
1058 n
= read_datagram(fd
, &sender
, &datagram
);
1059 if (IN_SET(n
, -EAGAIN
, -EINTR
))
1062 return log_error_errno(n
, "Failed to read notify datagram: %m");
1064 if (sender
.pid
<= 0) {
1065 log_warning("Received notify datagram without valid sender PID, ignoring.");
1069 h
= hashmap_get(m
->homes_by_worker_pid
, PID_TO_PTR(sender
.pid
));
1071 log_warning("Received notify datagram of unknown process, ignoring.");
1075 l
= strv_split(datagram
, "\n");
1079 home_process_notify(h
, l
);
1083 static int manager_listen_notify(Manager
*m
) {
1084 _cleanup_close_
int fd
= -1;
1085 union sockaddr_union sa
= {
1086 .un
.sun_family
= AF_UNIX
,
1087 .un
.sun_path
= "/run/systemd/home/notify",
1092 assert(!m
->notify_socket_event_source
);
1094 fd
= socket(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
1096 return log_error_errno(errno
, "Failed to create listening socket: %m");
1098 (void) mkdir_parents(sa
.un
.sun_path
, 0755);
1099 (void) sockaddr_un_unlink(&sa
.un
);
1101 if (bind(fd
, &sa
.sa
, SOCKADDR_UN_LEN(sa
.un
)) < 0)
1102 return log_error_errno(errno
, "Failed to bind to socket: %m");
1104 r
= setsockopt_int(fd
, SOL_SOCKET
, SO_PASSCRED
, true);
1108 r
= sd_event_add_io(m
->event
, &m
->notify_socket_event_source
, fd
, EPOLLIN
, on_notify_socket
, m
);
1110 return log_error_errno(r
, "Failed to allocate event source for notify socket: %m");
1112 (void) sd_event_source_set_description(m
->notify_socket_event_source
, "notify-socket");
1114 /* Make sure we process sd_notify() before SIGCHLD for any worker, so that we always know the error
1115 * number of a client before it exits. */
1116 r
= sd_event_source_set_priority(m
->notify_socket_event_source
, SD_EVENT_PRIORITY_NORMAL
- 5);
1118 return log_error_errno(r
, "Failed to alter priority of NOTIFY_SOCKET event source: %m");
1120 r
= sd_event_source_set_io_fd_own(m
->notify_socket_event_source
, true);
1122 return log_error_errno(r
, "Failed to pass ownership of notify socket: %m");
1127 static int manager_add_device(Manager
*m
, sd_device
*d
) {
1128 _cleanup_free_
char *user_name
= NULL
, *realm
= NULL
, *node
= NULL
;
1129 const char *tabletype
, *parttype
, *partname
, *partuuid
, *sysfs
;
1136 r
= sd_device_get_syspath(d
, &sysfs
);
1138 return log_error_errno(r
, "Failed to acquire sysfs path of device: %m");
1140 r
= sd_device_get_property_value(d
, "ID_PART_TABLE_TYPE", &tabletype
);
1144 return log_error_errno(r
, "Failed to acquire ID_PART_TABLE_TYPE device property, ignoring: %m");
1146 if (!streq(tabletype
, "gpt")) {
1147 log_debug("Found partition (%s) on non-GPT table, ignoring.", sysfs
);
1151 r
= sd_device_get_property_value(d
, "ID_PART_ENTRY_TYPE", &parttype
);
1155 return log_error_errno(r
, "Failed to acquire ID_PART_ENTRY_TYPE device property, ignoring: %m");
1156 r
= sd_id128_from_string(parttype
, &id
);
1158 return log_debug_errno(r
, "Failed to parse ID_PART_ENTRY_TYPE field '%s', ignoring: %m", parttype
);
1159 if (!sd_id128_equal(id
, GPT_USER_HOME
)) {
1160 log_debug("Found partition (%s) we don't care about, ignoring.", sysfs
);
1164 r
= sd_device_get_property_value(d
, "ID_PART_ENTRY_NAME", &partname
);
1166 return log_warning_errno(r
, "Failed to acquire ID_PART_ENTRY_NAME device property, ignoring: %m");
1168 r
= split_user_name_realm(partname
, &user_name
, &realm
);
1170 return log_warning_errno(r
, "Found partition with correct partition type but a non-parsable partition name '%s', ignoring.", partname
);
1172 return log_error_errno(r
, "Failed to validate partition name '%s': %m", partname
);
1174 r
= sd_device_get_property_value(d
, "ID_FS_UUID", &partuuid
);
1176 return log_warning_errno(r
, "Failed to acquire ID_FS_UUID device property, ignoring: %m");
1178 r
= sd_id128_from_string(partuuid
, &id
);
1180 return log_warning_errno(r
, "Failed to parse ID_FS_UUID field '%s', ignoring: %m", partuuid
);
1182 if (asprintf(&node
, "/dev/disk/by-uuid/" SD_ID128_UUID_FORMAT_STR
, SD_ID128_FORMAT_VAL(id
)) < 0)
1185 return manager_add_home_by_image(m
, user_name
, realm
, node
, sysfs
, USER_LUKS
, UID_INVALID
);
1188 static int manager_on_device(sd_device_monitor
*monitor
, sd_device
*d
, void *userdata
) {
1189 Manager
*m
= userdata
;
1195 if (device_for_action(d
, DEVICE_ACTION_REMOVE
)) {
1199 r
= sd_device_get_syspath(d
, &sysfs
);
1201 log_warning_errno(r
, "Failed to acquire sysfs path from device: %m");
1205 log_info("block device %s has been removed.", sysfs
);
1207 /* Let's see if we previously synthesized a home record from this device, if so, let's just
1208 * revalidate that. Otherwise let's revalidate them all, but asynchronously. */
1209 h
= hashmap_get(m
->homes_by_sysfs
, sysfs
);
1211 manager_revalidate_image(m
, h
);
1213 manager_enqueue_gc(m
, NULL
);
1215 (void) manager_add_device(m
, d
);
1217 (void) bus_manager_emit_auto_login_changed(m
);
1221 static int manager_watch_devices(Manager
*m
) {
1225 assert(!m
->device_monitor
);
1227 r
= sd_device_monitor_new(&m
->device_monitor
);
1229 return log_error_errno(r
, "Failed to allocate device monitor: %m");
1231 r
= sd_device_monitor_filter_add_match_subsystem_devtype(m
->device_monitor
, "block", NULL
);
1233 return log_error_errno(r
, "Failed to configure device monitor match: %m");
1235 r
= sd_device_monitor_attach_event(m
->device_monitor
, m
->event
);
1237 return log_error_errno(r
, "Failed to attach device monitor to event loop: %m");
1239 r
= sd_device_monitor_start(m
->device_monitor
, manager_on_device
, m
);
1241 return log_error_errno(r
, "Failed to start device monitor: %m");
1246 static int manager_enumerate_devices(Manager
*m
) {
1247 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*e
= NULL
;
1253 r
= sd_device_enumerator_new(&e
);
1257 r
= sd_device_enumerator_add_match_subsystem(e
, "block", true);
1261 FOREACH_DEVICE(e
, d
)
1262 (void) manager_add_device(m
, d
);
1267 static int manager_load_key_pair(Manager
*m
) {
1268 _cleanup_(fclosep
) FILE *f
= NULL
;
1274 if (m
->private_key
) {
1275 EVP_PKEY_free(m
->private_key
);
1276 m
->private_key
= NULL
;
1279 r
= search_and_fopen_nulstr("local.private", "re", NULL
, KEY_PATHS_NULSTR
, &f
);
1283 return log_error_errno(r
, "Failed to read private key file: %m");
1285 if (fstat(fileno(f
), &st
) < 0)
1286 return log_error_errno(errno
, "Failed to stat private key file: %m");
1288 r
= stat_verify_regular(&st
);
1290 return log_error_errno(r
, "Private key file is not regular: %m");
1292 if (st
.st_uid
!= 0 || (st
.st_mode
& 0077) != 0)
1293 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Private key file is readable by more than the root user");
1295 m
->private_key
= PEM_read_PrivateKey(f
, NULL
, NULL
, NULL
);
1296 if (!m
->private_key
)
1297 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to load private key pair");
1299 log_info("Successfully loaded private key pair.");
1304 DEFINE_TRIVIAL_CLEANUP_FUNC(EVP_PKEY_CTX
*, EVP_PKEY_CTX_free
);
1306 static int manager_generate_key_pair(Manager
*m
) {
1307 _cleanup_(EVP_PKEY_CTX_freep
) EVP_PKEY_CTX
*ctx
= NULL
;
1308 _cleanup_(unlink_and_freep
) char *temp_public
= NULL
, *temp_private
= NULL
;
1309 _cleanup_fclose_
FILE *fpublic
= NULL
, *fprivate
= NULL
;
1312 if (m
->private_key
) {
1313 EVP_PKEY_free(m
->private_key
);
1314 m
->private_key
= NULL
;
1317 ctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519
, NULL
);
1319 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to allocate Ed25519 key generation context.");
1321 if (EVP_PKEY_keygen_init(ctx
) <= 0)
1322 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to initialize Ed25519 key generation context.");
1324 log_info("Generating key pair for signing local user identity records.");
1326 if (EVP_PKEY_keygen(ctx
, &m
->private_key
) <= 0)
1327 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to generate Ed25519 key pair");
1329 log_info("Successfully created Ed25519 key pair.");
1331 (void) mkdir_p("/var/lib/systemd/home", 0755);
1333 /* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */
1334 r
= fopen_temporary("/var/lib/systemd/home/local.public", &fpublic
, &temp_public
);
1336 return log_error_errno(errno
, "Failed to open key file for writing: %m");
1338 if (PEM_write_PUBKEY(fpublic
, m
->private_key
) <= 0)
1339 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to write public key.");
1341 r
= fflush_sync_and_check(fpublic
);
1343 return log_error_errno(r
, "Failed to write private key: %m");
1345 fpublic
= safe_fclose(fpublic
);
1347 /* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */
1348 r
= fopen_temporary("/var/lib/systemd/home/local.private", &fprivate
, &temp_private
);
1350 return log_error_errno(errno
, "Failed to open key file for writing: %m");
1352 if (PEM_write_PrivateKey(fprivate
, m
->private_key
, NULL
, NULL
, 0, NULL
, 0) <= 0)
1353 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to write private key pair.");
1355 r
= fflush_sync_and_check(fprivate
);
1357 return log_error_errno(r
, "Failed to write private key: %m");
1359 fprivate
= safe_fclose(fprivate
);
1361 /* Both are written now, move them into place */
1363 if (rename(temp_public
, "/var/lib/systemd/home/local.public") < 0)
1364 return log_error_errno(errno
, "Failed to move public key file into place: %m");
1365 temp_public
= mfree(temp_public
);
1367 if (rename(temp_private
, "/var/lib/systemd/home/local.private") < 0) {
1368 (void) unlink_noerrno("/var/lib/systemd/home/local.public"); /* try to remove the file we already created */
1369 return log_error_errno(errno
, "Failed to move private key file into place: %m");
1371 temp_private
= mfree(temp_private
);
1373 r
= fsync_path_at(AT_FDCWD
, "/var/lib/systemd/home/");
1375 log_warning_errno(r
, "Failed to sync /var/lib/systemd/home/, ignoring: %m");
1380 int manager_acquire_key_pair(Manager
*m
) {
1385 /* Already there? */
1389 /* First try to load key off disk */
1390 r
= manager_load_key_pair(m
);
1394 /* Didn't work, generate a new one */
1395 return manager_generate_key_pair(m
);
1398 int manager_sign_user_record(Manager
*m
, UserRecord
*u
, UserRecord
**ret
, sd_bus_error
*error
) {
1405 r
= manager_acquire_key_pair(m
);
1409 return sd_bus_error_setf(error
, BUS_ERROR_NO_PRIVATE_KEY
, "Can't sign without local key.");
1411 return user_record_sign(u
, m
->private_key
, ret
);
1414 DEFINE_PRIVATE_HASH_OPS_FULL(public_key_hash_ops
, char, string_hash_func
, string_compare_func
, free
, EVP_PKEY
, EVP_PKEY_free
);
1415 DEFINE_TRIVIAL_CLEANUP_FUNC(EVP_PKEY
*, EVP_PKEY_free
);
1417 static int manager_load_public_key_one(Manager
*m
, const char *path
) {
1418 _cleanup_(EVP_PKEY_freep
) EVP_PKEY
*pkey
= NULL
;
1419 _cleanup_fclose_
FILE *f
= NULL
;
1420 _cleanup_free_
char *fn
= NULL
;
1426 if (streq(basename(path
), "local.public")) /* we already loaded the private key, which includes the public one */
1429 f
= fopen(path
, "re");
1431 if (errno
== ENOENT
)
1434 return log_error_errno(errno
, "Failed to open public key %s: %m", path
);
1437 if (fstat(fileno(f
), &st
) < 0)
1438 return log_error_errno(errno
, "Failed to stat public key %s: %m", path
);
1440 r
= stat_verify_regular(&st
);
1442 return log_error_errno(r
, "Public key file %s is not a regular file: %m", path
);
1444 if (st
.st_uid
!= 0 || (st
.st_mode
& 0022) != 0)
1445 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Public key file %s is writable by more than the root user, refusing.", path
);
1447 r
= hashmap_ensure_allocated(&m
->public_keys
, &public_key_hash_ops
);
1451 pkey
= PEM_read_PUBKEY(f
, &pkey
, NULL
, NULL
);
1453 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to parse public key file %s.", path
);
1455 fn
= strdup(basename(path
));
1459 r
= hashmap_put(m
->public_keys
, fn
, pkey
);
1461 return log_error_errno(r
, "Failed to add public key to set: %m");
1469 static int manager_load_public_keys(Manager
*m
) {
1470 _cleanup_strv_free_
char **files
= NULL
;
1476 m
->public_keys
= hashmap_free(m
->public_keys
);
1478 r
= conf_files_list_nulstr(
1482 CONF_FILES_REGULAR
|CONF_FILES_FILTER_MASKED
,
1485 return log_error_errno(r
, "Failed to assemble list of public key directories: %m");
1487 STRV_FOREACH(i
, files
)
1488 (void) manager_load_public_key_one(m
, *i
);
1493 int manager_startup(Manager
*m
) {
1498 r
= manager_listen_notify(m
);
1502 r
= manager_connect_bus(m
);
1506 r
= manager_bind_varlink(m
);
1510 r
= manager_load_key_pair(m
); /* only try to load it, don't generate any */
1514 r
= manager_load_public_keys(m
);
1518 manager_watch_home(m
);
1519 (void) manager_watch_devices(m
);
1521 (void) manager_enumerate_records(m
);
1522 (void) manager_enumerate_images(m
);
1523 (void) manager_enumerate_devices(m
);
1525 /* Let's clean up home directories whose devices got removed while we were not running */
1526 (void) manager_enqueue_gc(m
, NULL
);
1531 void manager_revalidate_image(Manager
*m
, Home
*h
) {
1537 /* Frees an automatically discovered image, if it's synthetic and its image disappeared. Unmounts any
1538 * image if it's mounted but it's image vanished. */
1540 if (h
->current_operation
|| !ordered_set_isempty(h
->pending_operations
))
1543 if (h
->state
== HOME_UNFIXATED
) {
1544 r
= user_record_test_image_path(h
->record
);
1546 log_warning_errno(r
, "Can't determine if image of %s exists, freeing unfixated user: %m", h
->user_name
);
1547 else if (r
== USER_TEST_ABSENT
)
1548 log_info("Image for %s disappeared, freeing unfixated user.", h
->user_name
);
1554 } else if (h
->state
< 0) {
1556 r
= user_record_test_home_directory(h
->record
);
1558 log_warning_errno(r
, "Unable to determine state of home directory, ignoring: %m");
1562 if (r
== USER_TEST_MOUNTED
) {
1563 r
= user_record_test_image_path(h
->record
);
1565 log_warning_errno(r
, "Unable to determine state of image path, ignoring: %m");
1569 if (r
== USER_TEST_ABSENT
) {
1570 _cleanup_(operation_unrefp
) Operation
*o
= NULL
;
1572 log_notice("Backing image disappeared while home directory %s was mounted, unmounting it forcibly.", h
->user_name
);
1573 /* Wowza, the thing is mounted, but the device is gone? Act on it. */
1575 r
= home_killall(h
);
1577 log_warning_errno(r
, "Failed to kill processes of user %s, ignoring: %m", h
->user_name
);
1579 /* We enqueue the operation here, after all the home directory might
1580 * currently already run some operation, and we can deactivate it only after
1581 * that's complete. */
1582 o
= operation_new(OPERATION_DEACTIVATE_FORCE
, NULL
);
1588 r
= home_schedule_operation(h
, o
, NULL
);
1590 log_warning_errno(r
, "Failed to enqueue forced home directory %s deactivation, ignoring: %m", h
->user_name
);
1596 int manager_gc_images(Manager
*m
) {
1602 /* Focus on a specific home */
1604 h
= TAKE_PTR(m
->gc_focus
);
1605 manager_revalidate_image(m
, h
);
1609 HASHMAP_FOREACH(h
, m
->homes_by_name
)
1610 manager_revalidate_image(m
, h
);
1616 static int on_deferred_rescan(sd_event_source
*s
, void *userdata
) {
1617 Manager
*m
= userdata
;
1621 m
->deferred_rescan_event_source
= sd_event_source_unref(m
->deferred_rescan_event_source
);
1623 manager_enumerate_devices(m
);
1624 manager_enumerate_images(m
);
1628 int manager_enqueue_rescan(Manager
*m
) {
1633 if (m
->deferred_rescan_event_source
)
1639 if (IN_SET(sd_event_get_state(m
->event
), SD_EVENT_FINISHED
, SD_EVENT_EXITING
))
1642 r
= sd_event_add_defer(m
->event
, &m
->deferred_rescan_event_source
, on_deferred_rescan
, m
);
1644 return log_error_errno(r
, "Failed to allocate rescan event source: %m");
1646 r
= sd_event_source_set_priority(m
->deferred_rescan_event_source
, SD_EVENT_PRIORITY_IDLE
+1);
1648 log_warning_errno(r
, "Failed to tweak priority of event source, ignoring: %m");
1650 (void) sd_event_source_set_description(m
->deferred_rescan_event_source
, "deferred-rescan");
1654 static int on_deferred_gc(sd_event_source
*s
, void *userdata
) {
1655 Manager
*m
= userdata
;
1659 m
->deferred_gc_event_source
= sd_event_source_unref(m
->deferred_gc_event_source
);
1661 manager_gc_images(m
);
1665 int manager_enqueue_gc(Manager
*m
, Home
*focus
) {
1670 /* This enqueues a request to GC dead homes. It may be called with focus=NULL in which case all homes
1671 * will be scanned, or with the parameter set, in which case only that home is checked. */
1676 if (IN_SET(sd_event_get_state(m
->event
), SD_EVENT_FINISHED
, SD_EVENT_EXITING
))
1679 /* If a focus home is specified, then remember to focus just on this home. Otherwise invalidate any
1680 * focus that might be set to look at all homes. */
1682 if (m
->deferred_gc_event_source
) {
1683 if (m
->gc_focus
!= focus
) /* not the same focus, then look at everything */
1688 m
->gc_focus
= focus
; /* start focused */
1690 r
= sd_event_add_defer(m
->event
, &m
->deferred_gc_event_source
, on_deferred_gc
, m
);
1692 return log_error_errno(r
, "Failed to allocate GC event source: %m");
1694 r
= sd_event_source_set_priority(m
->deferred_gc_event_source
, SD_EVENT_PRIORITY_IDLE
);
1696 log_warning_errno(r
, "Failed to tweak priority of event source, ignoring: %m");
1698 (void) sd_event_source_set_description(m
->deferred_gc_event_source
, "deferred-gc");