1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/fscrypt.h>
5 #include <linux/magic.h>
7 #include <openssl/pem.h>
9 #include <sys/inotify.h>
10 #include <sys/ioctl.h>
19 #include "alloc-util.h"
20 #include "btrfs-util.h"
21 #include "bus-common-errors.h"
22 #include "bus-error.h"
23 #include "bus-log-control-api.h"
24 #include "bus-object.h"
25 #include "clean-ipc.h"
26 #include "common-signal.h"
27 #include "conf-files.h"
28 #include "device-util.h"
29 #include "dirent-util.h"
30 #include "errno-util.h"
34 #include "format-util.h"
36 #include "glyph-util.h"
37 #include "home-util.h"
38 #include "homed-conf.h"
39 #include "homed-home.h"
40 #include "homed-manager.h"
41 #include "homed-manager-bus.h"
42 #include "homed-operation.h"
43 #include "homed-varlink.h"
45 #include "notify-recv.h"
46 #include "openssl-util.h"
47 #include "ordered-set.h"
48 #include "quota-util.h"
49 #include "random-util.h"
50 #include "resize-fs.h"
53 #include "siphash24.h"
54 #include "sort-util.h"
55 #include "stat-util.h"
56 #include "string-util.h"
58 #include "sync-util.h"
59 #include "time-util.h"
60 #include "tmpfile-util.h"
61 #include "udev-util.h"
62 #include "user-record.h"
63 #include "user-record-sign.h"
64 #include "user-record-util.h"
65 #include "user-util.h"
66 #include "varlink-io.systemd.UserDatabase.h"
67 #include "varlink-io.systemd.service.h"
68 #include "varlink-util.h"
70 /* Where to look for private/public keys that are used to sign the user records. We are not using
71 * CONF_PATHS_NULSTR() here since we want to insert /var/lib/systemd/home/ in the middle. And we insert that
72 * since we want to auto-generate a persistent private/public key pair if we need to. */
73 #define KEY_PATHS_NULSTR \
74 "/etc/systemd/home/\0" \
75 "/run/systemd/home/\0" \
76 "/var/lib/systemd/home/\0" \
77 "/usr/local/lib/systemd/home/\0" \
78 "/usr/lib/systemd/home/\0"
80 static bool uid_is_home(uid_t uid
) {
81 return uid
>= HOME_UID_MIN
&& uid
<= HOME_UID_MAX
;
83 /* Takes a value generated randomly or by hashing and turns it into a UID in the right range */
85 #define UID_CLAMP_INTO_HOME_RANGE(rnd) (((uid_t) (rnd) % (HOME_UID_MAX - HOME_UID_MIN + 1)) + HOME_UID_MIN)
87 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_uid_hash_ops
, void, trivial_hash_func
, trivial_compare_func
, Home
, home_free
);
88 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_worker_pid_hash_ops
, PidRef
, pidref_hash_func
, pidref_compare_func
, Home
, home_free
);
89 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops
, char, path_hash_func
, path_compare
, Home
, home_free
);
91 static int on_home_inotify(sd_event_source
*s
, const struct inotify_event
*event
, void *userdata
);
92 static int manager_gc_images(Manager
*m
);
93 static int manager_gc_blob(Manager
*m
);
94 static int manager_enumerate_images(Manager
*m
);
95 static int manager_assess_image(Manager
*m
, int dir_fd
, const char *dir_path
, const char *dentry_name
);
96 static void manager_revalidate_image(Manager
*m
, Home
*h
);
98 static void manager_watch_home(Manager
*m
) {
104 m
->inotify_event_source
= sd_event_source_disable_unref(m
->inotify_event_source
);
105 m
->scan_slash_home
= false;
107 if (statfs(get_home_root(), &sfs
) < 0) {
108 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_WARNING
, errno
,
109 "Failed to statfs() %s directory, disabling automatic scanning.", get_home_root());
113 if (is_network_fs(&sfs
)) {
114 log_info("%s is a network file system, disabling automatic scanning.", get_home_root());
118 if (is_fs_type(&sfs
, AUTOFS_SUPER_MAGIC
)) {
119 log_info("%s is on autofs, disabling automatic scanning.", get_home_root());
123 m
->scan_slash_home
= true;
125 r
= sd_event_add_inotify(m
->event
, &m
->inotify_event_source
, get_home_root(),
126 IN_CREATE
|IN_CLOSE_WRITE
|IN_DELETE_SELF
|IN_MOVE_SELF
|IN_ONLYDIR
|IN_MOVED_TO
|IN_MOVED_FROM
|IN_DELETE
,
129 log_full_errno(r
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
, r
,
130 "Failed to create inotify watch on %s, ignoring.", get_home_root());
132 (void) sd_event_source_set_description(m
->inotify_event_source
, "home-inotify");
134 log_info("Watching %s.", get_home_root());
137 static int on_home_inotify(sd_event_source
*s
, const struct inotify_event
*event
, void *userdata
) {
138 _cleanup_free_
char *j
= NULL
;
139 Manager
*m
= ASSERT_PTR(userdata
);
144 if ((event
->mask
& (IN_Q_OVERFLOW
|IN_MOVE_SELF
|IN_DELETE_SELF
|IN_IGNORED
|IN_UNMOUNT
)) != 0) {
146 if (FLAGS_SET(event
->mask
, IN_Q_OVERFLOW
))
147 log_debug("%s inotify queue overflow, rescanning.", get_home_root());
148 else if (FLAGS_SET(event
->mask
, IN_MOVE_SELF
))
149 log_info("%s moved or renamed, recreating watch and rescanning.", get_home_root());
150 else if (FLAGS_SET(event
->mask
, IN_DELETE_SELF
))
151 log_info("%s deleted, recreating watch and rescanning.", get_home_root());
152 else if (FLAGS_SET(event
->mask
, IN_UNMOUNT
))
153 log_info("%s unmounted, recreating watch and rescanning.", get_home_root());
154 else if (FLAGS_SET(event
->mask
, IN_IGNORED
))
155 log_info("%s watch invalidated, recreating watch and rescanning.", get_home_root());
157 manager_watch_home(m
);
158 (void) manager_gc_images(m
);
159 (void) manager_enumerate_images(m
);
160 (void) bus_manager_emit_auto_login_changed(m
);
164 /* For the other inotify events, let's ignore all events for file names that don't match our
166 if (isempty(event
->name
))
168 e
= endswith(event
->name
, FLAGS_SET(event
->mask
, IN_ISDIR
) ? ".homedir" : ".home");
172 n
= strndupa_safe(event
->name
, e
- event
->name
);
173 if (!suitable_user_name(n
))
176 j
= path_join(get_home_root(), event
->name
);
180 if ((event
->mask
& (IN_CREATE
|IN_CLOSE_WRITE
|IN_MOVED_TO
)) != 0) {
181 if (FLAGS_SET(event
->mask
, IN_CREATE
))
182 log_debug("%s has been created, having a look.", j
);
183 else if (FLAGS_SET(event
->mask
, IN_CLOSE_WRITE
))
184 log_debug("%s has been modified, having a look.", j
);
185 else if (FLAGS_SET(event
->mask
, IN_MOVED_TO
))
186 log_debug("%s has been moved in, having a look.", j
);
188 (void) manager_assess_image(m
, /* dir_fd= */ -EBADF
, get_home_root(), event
->name
);
189 (void) bus_manager_emit_auto_login_changed(m
);
192 if ((event
->mask
& (IN_DELETE
| IN_CLOSE_WRITE
| IN_MOVED_FROM
)) != 0) {
195 if (FLAGS_SET(event
->mask
, IN_DELETE
))
196 log_debug("%s has been deleted, revalidating.", j
);
197 else if (FLAGS_SET(event
->mask
, IN_CLOSE_WRITE
))
198 log_debug("%s has been closed after writing, revalidating.", j
);
199 else if (FLAGS_SET(event
->mask
, IN_MOVED_FROM
))
200 log_debug("%s has been moved away, revalidating.", j
);
202 h
= hashmap_get(m
->homes_by_name
, n
);
203 if (h
&& streq(h
->user_name
, n
)) {
204 manager_revalidate_image(m
, h
);
205 (void) bus_manager_emit_auto_login_changed(m
);
212 static int sigusr1_handler(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
213 Manager
*m
= ASSERT_PTR(userdata
);
216 /* If clients send use SIGUSR1 we'll explicitly rescan for home directories. This is useful in some
217 * cases where inotify isn't good enough, for example if /home/ is overmunted. */
218 manager_watch_home(m
);
219 (void) manager_gc_images(m
);
220 (void) manager_enumerate_images(m
);
221 (void) bus_manager_emit_auto_login_changed(m
);
226 int manager_new(Manager
**ret
) {
227 _cleanup_(manager_freep
) Manager
*m
= NULL
;
237 .default_storage
= _USER_STORAGE_INVALID
,
238 .rebalance_interval_usec
= 2 * USEC_PER_MINUTE
, /* initially, rebalance every 2min */
241 r
= manager_parse_config_file(m
);
245 r
= sd_event_default(&m
->event
);
249 r
= sd_event_set_signal_exit(m
->event
, true);
253 r
= sd_event_add_memory_pressure(m
->event
, /* ret= */ NULL
, /* callback= */ NULL
, /* userdata= */ NULL
);
255 log_full_errno(ERRNO_IS_NOT_SUPPORTED(r
) || ERRNO_IS_PRIVILEGE(r
) || (r
== -EHOSTDOWN
) ? LOG_DEBUG
: LOG_WARNING
, r
,
256 "Failed to allocate memory pressure watch, ignoring: %m");
258 r
= sd_event_add_signal(m
->event
, /* ret= */ NULL
, (SIGRTMIN
+18)|SD_EVENT_SIGNAL_PROCMASK
, sigrtmin18_handler
, /* userdata = */ NULL
);
262 r
= sd_event_add_signal(m
->event
, /* ret= */ NULL
, SIGUSR1
|SD_EVENT_SIGNAL_PROCMASK
, sigusr1_handler
, m
);
266 (void) sd_event_set_watchdog(m
->event
, true);
268 m
->homes_by_uid
= hashmap_new(&homes_by_uid_hash_ops
);
269 if (!m
->homes_by_uid
)
272 m
->homes_by_name
= hashmap_new(&string_hash_ops
);
273 if (!m
->homes_by_name
)
276 m
->homes_by_worker_pid
= hashmap_new(&homes_by_worker_pid_hash_ops
);
277 if (!m
->homes_by_worker_pid
)
280 m
->homes_by_sysfs
= hashmap_new(&homes_by_sysfs_hash_ops
);
281 if (!m
->homes_by_sysfs
)
288 Manager
* manager_free(Manager
*m
) {
293 HASHMAP_FOREACH(h
, m
->homes_by_worker_pid
)
294 (void) home_wait_for_worker(h
);
296 m
->bus
= sd_bus_flush_close_unref(m
->bus
);
297 m
->polkit_registry
= hashmap_free(m
->polkit_registry
);
299 m
->device_monitor
= sd_device_monitor_unref(m
->device_monitor
);
301 m
->inotify_event_source
= sd_event_source_unref(m
->inotify_event_source
);
302 m
->notify_socket_path
= mfree(m
->notify_socket_path
);
303 m
->deferred_rescan_event_source
= sd_event_source_unref(m
->deferred_rescan_event_source
);
304 m
->deferred_gc_event_source
= sd_event_source_unref(m
->deferred_gc_event_source
);
305 m
->deferred_auto_login_event_source
= sd_event_source_unref(m
->deferred_auto_login_event_source
);
306 m
->rebalance_event_source
= sd_event_source_unref(m
->rebalance_event_source
);
308 m
->event
= sd_event_unref(m
->event
);
310 m
->homes_by_uid
= hashmap_free(m
->homes_by_uid
);
311 m
->homes_by_name
= hashmap_free(m
->homes_by_name
);
312 m
->homes_by_worker_pid
= hashmap_free(m
->homes_by_worker_pid
);
313 m
->homes_by_sysfs
= hashmap_free(m
->homes_by_sysfs
);
316 EVP_PKEY_free(m
->private_key
);
318 hashmap_free(m
->public_keys
);
320 sd_varlink_server_unref(m
->varlink_server
);
321 free(m
->userdb_service
);
323 free(m
->default_file_system_type
);
328 int manager_verify_user_record(Manager
*m
, UserRecord
*hr
) {
335 if (!m
->private_key
&& hashmap_isempty(m
->public_keys
)) {
336 r
= user_record_has_signature(hr
);
340 return r
? -ENOKEY
: USER_RECORD_UNSIGNED
;
344 if (m
->private_key
) {
345 r
= user_record_verify(hr
, m
->private_key
);
348 case USER_RECORD_FOREIGN
:
349 /* This record is not signed by this key, but let's see below */
352 case USER_RECORD_SIGNED
: /* Signed by us, but also by others, let's propagate that */
353 case USER_RECORD_SIGNED_EXCLUSIVE
: /* Signed by us, and nothing else, ditto */
354 case USER_RECORD_UNSIGNED
: /* Not signed at all, ditto */
360 HASHMAP_FOREACH(pkey
, m
->public_keys
) {
361 r
= user_record_verify(hr
, pkey
);
364 case USER_RECORD_FOREIGN
:
365 /* This record is not signed by this key, but let's see our other keys */
368 case USER_RECORD_SIGNED
: /* It's signed by this key we are happy with, but which is not our own. */
369 case USER_RECORD_SIGNED_EXCLUSIVE
:
370 return USER_RECORD_FOREIGN
;
372 case USER_RECORD_UNSIGNED
: /* It's not signed at all */
381 static int manager_add_home_by_record(
387 _cleanup_(sd_json_variant_unrefp
) sd_json_variant
*v
= NULL
;
388 _cleanup_(user_record_unrefp
) UserRecord
*hr
= NULL
;
397 if (fstatat(dir_fd
, fname
, &st
, 0) < 0)
398 return log_error_errno(errno
, "Failed to stat identity record %s: %m", fname
);
400 if (!S_ISREG(st
.st_mode
)) {
401 log_debug("Identity record file %s is not a regular file, ignoring.", fname
);
406 goto unlink_this_file
;
408 unsigned line
= 0, column
= 0;
409 r
= sd_json_parse_file_at(NULL
, dir_fd
, fname
, SD_JSON_PARSE_SENSITIVE
, &v
, &line
, &column
);
411 return log_error_errno(r
, "Failed to parse identity record at %s:%u%u: %m", fname
, line
, column
);
413 if (sd_json_variant_is_blank_object(v
))
414 goto unlink_this_file
;
416 hr
= user_record_new();
420 r
= user_record_load(hr
, v
, USER_RECORD_LOAD_REFUSE_SECRET
|USER_RECORD_LOG
|USER_RECORD_PERMISSIVE
);
424 if (!streq_ptr(hr
->user_name
, name
))
425 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
426 "Identity's user name %s does not match file name %s, refusing.",
427 hr
->user_name
, name
);
429 is_signed
= manager_verify_user_record(m
, hr
);
433 return log_warning_errno(is_signed
, "User record %s is not signed by any accepted key, ignoring.", fname
);
434 case USER_RECORD_UNSIGNED
:
435 return log_warning_errno(SYNTHETIC_ERRNO(EPERM
), "User record %s is not signed at all, ignoring.", fname
);
436 case USER_RECORD_SIGNED
:
437 log_info("User record %s is signed by us (and others), accepting.", fname
);
439 case USER_RECORD_SIGNED_EXCLUSIVE
:
440 log_info("User record %s is signed only by us, accepting.", fname
);
442 case USER_RECORD_FOREIGN
:
443 log_info("User record %s is signed by registered key from others, accepting.", fname
);
446 assert(is_signed
< 0);
447 return log_error_errno(is_signed
, "Failed to verify signature of user record in %s: %m", fname
);
450 h
= hashmap_get(m
->homes_by_name
, name
);
452 r
= home_set_record(h
, hr
);
454 return log_error_errno(r
, "Failed to update home record for %s: %m", name
);
456 /* If we acquired a record now for a previously unallocated entry, then reset the state. This
457 * makes sure home_get_state() will check for the availability of the image file dynamically
458 * in order to detect to distinguish HOME_INACTIVE and HOME_ABSENT. */
459 if (h
->state
== HOME_UNFIXATED
)
460 h
->state
= _HOME_STATE_INVALID
;
462 r
= home_new(m
, hr
, NULL
, &h
);
464 return log_error_errno(r
, "Failed to allocate new home object: %m");
466 log_info("Added registered home for user %s.", hr
->user_name
);
469 /* Only entries we exclusively signed are writable to us, hence remember the result */
470 h
->signed_locally
= is_signed
== USER_RECORD_SIGNED_EXCLUSIVE
;
475 /* If this is an empty file, then let's just remove it. An empty file is not useful in any case, and
476 * apparently xfs likes to leave empty files around when not unmounted cleanly (see
477 * https://github.com/systemd/systemd/issues/15178 for example). Note that we don't delete non-empty
478 * files even if they are invalid, because that's just too risky, we might delete data the user still
479 * needs. But empty files are never useful, hence let's just remove them. */
481 if (unlinkat(dir_fd
, fname
, 0) < 0)
482 return log_error_errno(errno
, "Failed to remove empty user record file %s: %m", fname
);
484 log_notice("Discovered empty user record file %s/%s, removed automatically.", home_record_dir(), fname
);
488 static int manager_enumerate_records(Manager
*m
) {
489 _cleanup_closedir_
DIR *d
= NULL
;
493 d
= opendir(home_record_dir());
495 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
496 "Failed to open %s: %m", home_record_dir());
498 FOREACH_DIRENT(de
, d
, return log_error_errno(errno
, "Failed to read record directory: %m")) {
499 _cleanup_free_
char *n
= NULL
;
502 if (!dirent_is_file(de
))
505 e
= endswith(de
->d_name
, ".identity");
509 n
= strndup(de
->d_name
, e
- de
->d_name
);
513 if (!suitable_user_name(n
))
516 (void) manager_add_home_by_record(m
, n
, dirfd(d
), de
->d_name
);
522 static int search_quota(uid_t uid
, const char *exclude_quota_path
) {
523 struct stat exclude_st
= {};
524 dev_t previous_devno
= 0;
527 /* Checks whether the specified UID owns any files on the files system, but ignore any file system
528 * backing the specified file. The file is used when operating on home directories, where it's OK if
529 * the UID of them already owns files. */
531 if (exclude_quota_path
&& stat(exclude_quota_path
, &exclude_st
) < 0) {
533 return log_warning_errno(errno
, "Failed to stat %s, ignoring: %m", exclude_quota_path
);
536 /* Check a few usual suspects where regular users might own files. Note that this is by no means
537 * comprehensive, but should cover most cases. Note that in an ideal world every user would be
538 * registered in NSS and avoid our own UID range, but for all other cases, it's a good idea to be
539 * paranoid and check quota if we can. */
540 FOREACH_STRING(where
, get_home_root(), "/tmp/", "/var/", "/var/mail/", "/var/tmp/", "/var/spool/") {
544 _cleanup_close_
int fd
= open(where
, O_RDONLY
|O_CLOEXEC
|O_DIRECTORY
);
546 log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
547 "Failed to open '%s', ignoring: %m", where
);
551 if (fstat(fd
, &st
) < 0) {
552 log_error_errno(errno
, "Failed to stat '%s', ignoring: %m", where
);
556 if (st
.st_dev
== exclude_st
.st_dev
) { /* If an exclude path is specified, then ignore quota
557 * reported on the same block device as that path. */
558 log_debug("Directory %s is where the home directory is located, not checking quota for UID use.", where
);
562 if (st
.st_dev
== previous_devno
) { /* Does this directory have the same devno as the previous
563 * one we tested? If so, there's no point in testing this
565 log_debug("Directory %s is on same device as previous tested directory, not checking quota for UID use a second time.", where
);
569 previous_devno
= st
.st_dev
;
571 r
= quotactl_fd_with_fallback(fd
, QCMD_FIXED(Q_GETQUOTA
, USRQUOTA
), uid
, &req
);
573 if (ERRNO_IS_NOT_SUPPORTED(r
))
574 log_debug_errno(r
, "No UID quota support on %s, ignoring.", where
);
575 else if (r
== -ESRCH
)
576 log_debug_errno(r
, "UID quota not enabled on %s (for user " UID_FMT
"), ignoring.", where
, uid
);
577 else if (ERRNO_IS_PRIVILEGE(r
))
578 log_debug_errno(r
, "UID quota support for %s prohibited, ignoring.", where
);
580 log_warning_errno(r
, "Failed to query quota on %s, ignoring: %m", where
);
585 if ((FLAGS_SET(req
.dqb_valid
, QIF_SPACE
) && req
.dqb_curspace
> 0) ||
586 (FLAGS_SET(req
.dqb_valid
, QIF_INODES
) && req
.dqb_curinodes
> 0)) {
587 log_debug("Quota reports UID " UID_FMT
" occupies disk space on %s.", uid
, where
);
595 static int manager_acquire_uid(
598 const char *user_name
,
599 const char *exclude_quota_path
,
602 static const uint8_t hash_key
[] = {
603 0xa3, 0xb8, 0x82, 0x69, 0x9a, 0x71, 0xf7, 0xa9,
604 0xe0, 0x7c, 0xf6, 0xf1, 0x21, 0x69, 0xd2, 0x1e
611 } phase
= PHASE_SUGGESTED
;
613 unsigned n_tries
= 100;
620 _cleanup_free_
struct passwd
*pw
= NULL
;
621 _cleanup_free_
struct group
*gr
= NULL
;
630 case PHASE_SUGGESTED
:
631 phase
= PHASE_HASHED
;
633 if (!uid_is_home(start_uid
))
636 candidate
= start_uid
;
640 phase
= PHASE_RANDOM
;
645 candidate
= UID_CLAMP_INTO_HOME_RANGE(siphash24(user_name
, strlen(user_name
), hash_key
));
649 random_bytes(&candidate
, sizeof(candidate
));
650 candidate
= UID_CLAMP_INTO_HOME_RANGE(candidate
);
654 assert_not_reached();
657 other
= hashmap_get(m
->homes_by_uid
, UID_TO_PTR(candidate
));
659 log_debug("Candidate UID " UID_FMT
" already used by another home directory (%s), let's try another.",
660 candidate
, other
->user_name
);
664 r
= getpwuid_malloc(candidate
, &pw
);
666 log_debug("Candidate UID " UID_FMT
" already registered by another user in NSS (%s), let's try another.",
667 candidate
, pw
->pw_name
);
671 log_debug_errno(r
, "Failed to check if an NSS user is already registered for candidate UID " UID_FMT
", assuming there might be: %m", candidate
);
675 r
= getgrgid_malloc((gid_t
) candidate
, &gr
);
677 log_debug("Candidate UID " UID_FMT
" already registered by another group in NSS (%s), let's try another.",
678 candidate
, gr
->gr_name
);
682 log_debug_errno(r
, "Failed to check if an NSS group is already registered for candidate UID " UID_FMT
", assuming there might be: %m", candidate
);
686 r
= search_ipc(candidate
, (gid_t
) candidate
);
690 log_debug_errno(r
, "Candidate UID " UID_FMT
" already owns IPC objects, let's try another: %m",
695 r
= search_quota(candidate
, exclude_quota_path
);
704 static int manager_add_home_by_image(
706 const char *user_name
,
708 const char *image_path
,
713 _cleanup_(user_record_unrefp
) UserRecord
*hr
= NULL
;
723 assert(storage
>= 0);
724 assert(storage
< _USER_STORAGE_MAX
);
726 h
= hashmap_get(m
->homes_by_name
, user_name
);
730 if (!streq(h
->user_name
, user_name
)) {
731 log_debug("Found an image for user %s which already is an alias for another user, skipping.", user_name
);
732 return 0; /* Ignore images that would synthesize a user that conflicts with an alias of another user */
735 if (h
->state
!= HOME_UNFIXATED
) {
736 log_debug("Found an image for user %s which already has a record, skipping.", user_name
);
737 return 0; /* ignore images that synthesize a user we already have a record for */
740 same
= user_record_storage(h
->record
) == storage
;
742 if (h
->sysfs
&& sysfs
)
743 same
= path_equal(h
->sysfs
, sysfs
);
744 else if (!!h
->sysfs
!= !!sysfs
)
749 p
= user_record_image_path(h
->record
);
750 same
= p
&& path_equal(p
, image_path
);
755 log_debug("Found multiple images for user '%s', ignoring image '%s'.", user_name
, image_path
);
759 /* Check NSS, in case there's another user or group by this name */
760 if (getpwnam_malloc(user_name
, /* ret= */ NULL
) >= 0 || getgrnam_malloc(user_name
, /* ret= */ NULL
) >= 0) {
761 log_debug("Found an existing user or group by name '%s', ignoring image '%s'.", user_name
, image_path
);
766 if (h
&& uid_is_valid(h
->uid
))
769 r
= manager_acquire_uid(m
, start_uid
, user_name
,
770 IN_SET(storage
, USER_SUBVOLUME
, USER_DIRECTORY
, USER_FSCRYPT
) ? image_path
: NULL
,
773 return log_warning_errno(r
, "Failed to acquire unused UID for %s: %m", user_name
);
776 hr
= user_record_new();
780 r
= user_record_synthesize(hr
, user_name
, realm
, image_path
, storage
, uid
, (gid_t
) uid
);
782 return log_error_errno(r
, "Failed to synthesize home record for %s (image %s): %m", user_name
, image_path
);
785 r
= home_set_record(h
, hr
);
787 return log_error_errno(r
, "Failed to update home record for %s: %m", user_name
);
789 r
= home_new(m
, hr
, sysfs
, &h
);
791 return log_error_errno(r
, "Failed to allocate new home object: %m");
793 h
->state
= HOME_UNFIXATED
;
795 log_info("Discovered new home for user %s through image %s.", user_name
, image_path
);
801 int manager_augment_record_with_uid(
805 const char *exclude_quota_path
= NULL
;
806 uid_t start_uid
= UID_INVALID
, uid
;
812 if (uid_is_valid(hr
->uid
))
815 if (IN_SET(hr
->storage
, USER_CLASSIC
, USER_SUBVOLUME
, USER_DIRECTORY
, USER_FSCRYPT
)) {
818 ip
= user_record_image_path(hr
);
822 if (stat(ip
, &st
) < 0) {
824 log_warning_errno(errno
, "Failed to stat(%s): %m", ip
);
825 } else if (uid_is_home(st
.st_uid
)) {
826 start_uid
= st
.st_uid
;
827 exclude_quota_path
= ip
;
832 r
= manager_acquire_uid(m
, start_uid
, hr
->user_name
, exclude_quota_path
, &uid
);
836 log_debug("Acquired new UID " UID_FMT
" for %s.", uid
, hr
->user_name
);
838 r
= user_record_add_binding(
840 _USER_STORAGE_INVALID
,
858 static int manager_assess_image(
861 const char *dir_path
,
862 const char *dentry_name
) {
864 char *luks_suffix
, *directory_suffix
;
865 _cleanup_free_
char *path
= NULL
;
873 /* Maybe registers the specified .home or .homedir as a home we manage. Returns:
875 * -EMEDIUMTYPE: Not a dir with .homedir suffix or a file with .home suffix */
877 luks_suffix
= endswith(dentry_name
, ".home");
879 directory_suffix
= NULL
;
881 directory_suffix
= endswith(dentry_name
, ".homedir");
883 /* Early filter out: by name */
884 if (!luks_suffix
&& !directory_suffix
)
887 path
= path_join(dir_path
, dentry_name
);
891 /* Follow symlinks here, to allow people to link in stuff to make them available locally. */
893 r
= fstatat(dir_fd
, dentry_name
, &st
, 0);
897 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_WARNING
, errno
,
898 "Failed to stat() directory entry '%s', ignoring: %m", dentry_name
);
900 if (S_ISREG(st
.st_mode
)) {
901 _cleanup_free_
char *n
= NULL
, *user_name
= NULL
, *realm
= NULL
;
906 n
= strndup(dentry_name
, luks_suffix
- dentry_name
);
910 r
= split_user_name_realm(n
, &user_name
, &realm
);
911 if (r
== -EINVAL
) /* Not the right format: ignore */
914 return log_error_errno(r
, "Failed to split image name into user name/realm: %m");
916 return manager_add_home_by_image(m
, user_name
, realm
, path
, NULL
, USER_LUKS
, UID_INVALID
);
919 if (S_ISDIR(st
.st_mode
)) {
920 _cleanup_free_
char *n
= NULL
, *user_name
= NULL
, *realm
= NULL
;
921 _cleanup_close_
int fd
= -EBADF
;
924 if (!directory_suffix
)
927 n
= strndup(dentry_name
, directory_suffix
- dentry_name
);
931 r
= split_user_name_realm(n
, &user_name
, &realm
);
932 if (r
== -EINVAL
) /* Not the right format: ignore */
935 return log_error_errno(r
, "Failed to split image name into user name/realm: %m");
938 fd
= openat(dir_fd
, dentry_name
, O_DIRECTORY
|O_RDONLY
|O_CLOEXEC
);
940 fd
= open(path
, O_DIRECTORY
|O_RDONLY
|O_CLOEXEC
);
942 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_WARNING
, errno
,
943 "Failed to open directory '%s', ignoring: %m", path
);
945 if (fstat(fd
, &st
) < 0)
946 return log_warning_errno(errno
, "Failed to fstat() %s, ignoring: %m", path
);
948 assert(S_ISDIR(st
.st_mode
)); /* Must hold, we used O_DIRECTORY above */
950 r
= btrfs_is_subvol_fd(fd
);
952 return log_warning_errno(r
, "Failed to determine whether %s is a btrfs subvolume: %m", path
);
954 storage
= USER_SUBVOLUME
;
956 struct fscrypt_policy policy
;
958 if (ioctl(fd
, FS_IOC_GET_ENCRYPTION_POLICY
, &policy
) < 0) {
960 if (errno
== ENODATA
)
961 log_debug_errno(errno
, "Determined %s is not fscrypt encrypted.", path
);
962 else if (ERRNO_IS_NOT_SUPPORTED(errno
))
963 log_debug_errno(errno
, "Determined %s is not fscrypt encrypted because kernel or file system doesn't support it.", path
);
965 log_debug_errno(errno
, "FS_IOC_GET_ENCRYPTION_POLICY failed with unexpected error code on %s, ignoring: %m", path
);
967 storage
= USER_DIRECTORY
;
969 storage
= USER_FSCRYPT
;
972 return manager_add_home_by_image(m
, user_name
, realm
, path
, NULL
, storage
, st
.st_uid
);
978 int manager_adopt_home(Manager
*m
, const char *path
) {
984 _cleanup_free_
char *fn
= NULL
;
985 r
= path_extract_filename(path
, &fn
);
989 _cleanup_free_
char *dir
= NULL
;
990 r
= path_extract_directory(path
, &dir
);
994 return manager_assess_image(m
, /* dir_fd= */ -EBADF
, dir
, fn
);
997 int manager_enumerate_images(Manager
*m
) {
998 _cleanup_closedir_
DIR *d
= NULL
;
1002 if (!m
->scan_slash_home
)
1005 d
= opendir(get_home_root());
1007 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
1008 "Failed to open %s: %m", get_home_root());
1010 FOREACH_DIRENT(de
, d
, return log_error_errno(errno
, "Failed to read %s directory: %m", get_home_root()))
1011 (void) manager_assess_image(m
, dirfd(d
), get_home_root(), de
->d_name
);
1016 static int manager_connect_bus(Manager
*m
) {
1017 _cleanup_free_
char *b
= NULL
;
1018 const char *suffix
, *busname
;
1024 r
= sd_bus_default_system(&m
->bus
);
1026 return log_error_errno(r
, "Failed to connect to system bus: %m");
1028 r
= bus_add_implementation(m
->bus
, &manager_object
, m
);
1032 r
= bus_log_control_api_register(m
->bus
);
1036 suffix
= getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
1038 b
= strjoin("org.freedesktop.home1.", suffix
);
1043 busname
= "org.freedesktop.home1";
1045 r
= sd_bus_request_name_async(m
->bus
, NULL
, busname
, 0, NULL
, NULL
);
1047 return log_error_errno(r
, "Failed to request name: %m");
1049 r
= sd_bus_attach_event(m
->bus
, m
->event
, SD_EVENT_PRIORITY_NORMAL
);
1051 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
1053 (void) sd_bus_set_exit_on_disconnect(m
->bus
, true);
1058 static int manager_bind_varlink(Manager
*m
) {
1059 _cleanup_free_
char *p
= NULL
;
1060 const char *suffix
, *socket_path
;
1064 assert(!m
->varlink_server
);
1066 r
= varlink_server_new(
1068 SD_VARLINK_SERVER_ACCOUNT_UID
|SD_VARLINK_SERVER_INHERIT_USERDATA
|SD_VARLINK_SERVER_INPUT_SENSITIVE
,
1071 return log_error_errno(r
, "Failed to allocate varlink server: %m");
1073 r
= sd_varlink_server_add_interface_many(
1075 &vl_interface_io_systemd_UserDatabase
,
1076 &vl_interface_io_systemd_service
);
1078 return log_error_errno(r
, "Failed to add UserDatabase interface to varlink server: %m");
1080 r
= sd_varlink_server_bind_method_many(
1082 "io.systemd.UserDatabase.GetUserRecord", vl_method_get_user_record
,
1083 "io.systemd.UserDatabase.GetGroupRecord", vl_method_get_group_record
,
1084 "io.systemd.UserDatabase.GetMemberships", vl_method_get_memberships
,
1085 "io.systemd.service.Ping", varlink_method_ping
,
1086 "io.systemd.service.SetLogLevel", varlink_method_set_log_level
,
1087 "io.systemd.service.GetEnvironment", varlink_method_get_environment
);
1089 return log_error_errno(r
, "Failed to register varlink methods: %m");
1091 /* To make things easier to debug, when working from a homed managed home directory, let's optionally
1092 * use a different varlink socket name */
1093 suffix
= getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
1095 p
= strjoin("/run/systemd/userdb/io.systemd.Home.", suffix
);
1100 socket_path
= "/run/systemd/userdb/io.systemd.Home";
1102 r
= sd_varlink_server_listen_address(m
->varlink_server
, socket_path
, 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755
);
1104 return log_error_errno(r
, "Failed to bind to varlink socket: %m");
1106 r
= sd_varlink_server_attach_event(m
->varlink_server
, m
->event
, SD_EVENT_PRIORITY_NORMAL
);
1108 return log_error_errno(r
, "Failed to attach varlink connection to event loop: %m");
1110 assert(!m
->userdb_service
);
1111 r
= path_extract_filename(socket_path
, &m
->userdb_service
);
1113 return log_error_errno(r
, "Failed to extract filename from socket path '%s': %m", socket_path
);
1115 /* Avoid recursion */
1116 if (setenv("SYSTEMD_BYPASS_USERDB", m
->userdb_service
, 1) < 0)
1117 return log_error_errno(errno
, "Failed to set $SYSTEMD_BYPASS_USERDB: %m");
1122 static int on_notify_socket(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
1123 Manager
*m
= ASSERT_PTR(userdata
);
1128 _cleanup_(fdset_free_asyncp
) FDSet
*passed_fds
= NULL
;
1129 _cleanup_(pidref_done
) PidRef sender
= PIDREF_NULL
;
1130 _cleanup_strv_free_
char **l
= NULL
;
1131 r
= notify_recv_with_fds_strv(fd
, &l
, /* ret_ucred= */ NULL
, &sender
, &passed_fds
);
1137 if (fdset_size(passed_fds
) > 1) {
1138 log_warning("Received notify datagram with multiple fds, ignoring.");
1142 Home
*h
= hashmap_get(m
->homes_by_worker_pid
, &sender
);
1144 log_warning("Received notify datagram of unknown process, ignoring.");
1148 home_process_notify(h
, l
, fdset_steal_first(passed_fds
));
1152 static int manager_listen_notify(Manager
*m
) {
1156 assert(!m
->notify_socket_path
);
1158 r
= notify_socket_prepare_full(
1160 SD_EVENT_PRIORITY_NORMAL
- 5, /* Make sure we process sd_notify() before SIGCHLD for
1161 * any worker, so that we always know the error number
1162 * of a client before it exits. */
1165 /* accept_fds = */ true,
1166 &m
->notify_socket_path
,
1167 /* ret_event_source = */ NULL
);
1169 return log_error_errno(r
, "Failed to prepare notify socket: %m");
1174 static int manager_add_device(Manager
*m
, sd_device
*d
) {
1175 _cleanup_free_
char *user_name
= NULL
, *realm
= NULL
, *node
= NULL
;
1176 const char *tabletype
, *parttype
, *partname
, *partuuid
, *sysfs
;
1183 r
= sd_device_get_syspath(d
, &sysfs
);
1185 return log_error_errno(r
, "Failed to acquire sysfs path of device: %m");
1187 r
= sd_device_get_property_value(d
, "ID_PART_TABLE_TYPE", &tabletype
);
1191 return log_error_errno(r
, "Failed to acquire ID_PART_TABLE_TYPE device property, ignoring: %m");
1193 if (!streq(tabletype
, "gpt")) {
1194 log_debug("Found partition (%s) on non-GPT table, ignoring.", sysfs
);
1198 r
= sd_device_get_property_value(d
, "ID_PART_ENTRY_TYPE", &parttype
);
1202 return log_error_errno(r
, "Failed to acquire ID_PART_ENTRY_TYPE device property, ignoring: %m");
1203 if (sd_id128_string_equal(parttype
, SD_GPT_USER_HOME
) <= 0) {
1204 log_debug("Found partition (%s) we don't care about, ignoring.", sysfs
);
1208 r
= sd_device_get_property_value(d
, "ID_PART_ENTRY_NAME", &partname
);
1210 return log_warning_errno(r
, "Failed to acquire ID_PART_ENTRY_NAME device property, ignoring: %m");
1212 r
= split_user_name_realm(partname
, &user_name
, &realm
);
1214 return log_warning_errno(r
, "Found partition with correct partition type but a non-parsable partition name '%s', ignoring.", partname
);
1216 return log_error_errno(r
, "Failed to validate partition name '%s': %m", partname
);
1218 r
= sd_device_get_property_value(d
, "ID_FS_UUID", &partuuid
);
1220 return log_warning_errno(r
, "Failed to acquire ID_FS_UUID device property, ignoring: %m");
1222 r
= sd_id128_from_string(partuuid
, &id
);
1224 return log_warning_errno(r
, "Failed to parse ID_FS_UUID field '%s', ignoring: %m", partuuid
);
1226 if (asprintf(&node
, "/dev/disk/by-uuid/" SD_ID128_UUID_FORMAT_STR
, SD_ID128_FORMAT_VAL(id
)) < 0)
1229 return manager_add_home_by_image(m
, user_name
, realm
, node
, sysfs
, USER_LUKS
, UID_INVALID
);
1232 static int manager_on_device(sd_device_monitor
*monitor
, sd_device
*d
, void *userdata
) {
1233 Manager
*m
= ASSERT_PTR(userdata
);
1238 if (device_for_action(d
, SD_DEVICE_REMOVE
)) {
1242 r
= sd_device_get_syspath(d
, &sysfs
);
1244 log_warning_errno(r
, "Failed to acquire sysfs path from device: %m");
1248 log_info("block device %s has been removed.", sysfs
);
1250 /* Let's see if we previously synthesized a home record from this device, if so, let's just
1251 * revalidate that. Otherwise let's revalidate them all, but asynchronously. */
1252 h
= hashmap_get(m
->homes_by_sysfs
, sysfs
);
1254 manager_revalidate_image(m
, h
);
1256 manager_enqueue_gc(m
, NULL
);
1258 (void) manager_add_device(m
, d
);
1260 (void) bus_manager_emit_auto_login_changed(m
);
1264 static int manager_watch_devices(Manager
*m
) {
1268 assert(!m
->device_monitor
);
1270 r
= sd_device_monitor_new(&m
->device_monitor
);
1272 return log_error_errno(r
, "Failed to allocate device monitor: %m");
1274 r
= sd_device_monitor_filter_add_match_subsystem_devtype(m
->device_monitor
, "block", NULL
);
1276 return log_error_errno(r
, "Failed to configure device monitor match: %m");
1278 r
= sd_device_monitor_attach_event(m
->device_monitor
, m
->event
);
1280 return log_error_errno(r
, "Failed to attach device monitor to event loop: %m");
1282 r
= sd_device_monitor_start(m
->device_monitor
, manager_on_device
, m
);
1284 return log_error_errno(r
, "Failed to start device monitor: %m");
1289 static int manager_enumerate_devices(Manager
*m
) {
1290 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*e
= NULL
;
1295 r
= sd_device_enumerator_new(&e
);
1299 r
= sd_device_enumerator_add_match_subsystem(e
, "block", true);
1303 FOREACH_DEVICE(e
, d
) {
1304 if (device_is_processed(d
) <= 0)
1306 (void) manager_add_device(m
, d
);
1312 static int manager_load_key_pair(Manager
*m
) {
1313 _cleanup_fclose_
FILE *f
= NULL
;
1319 if (m
->private_key
) {
1320 EVP_PKEY_free(m
->private_key
);
1321 m
->private_key
= NULL
;
1324 r
= search_and_fopen_nulstr("local.private", "re", NULL
, KEY_PATHS_NULSTR
, &f
, NULL
);
1328 return log_error_errno(r
, "Failed to read private key file: %m");
1330 if (fstat(fileno(f
), &st
) < 0)
1331 return log_error_errno(errno
, "Failed to stat private key file: %m");
1333 r
= stat_verify_regular(&st
);
1335 return log_error_errno(r
, "Private key file is not regular: %m");
1337 if (st
.st_uid
!= 0 || (st
.st_mode
& 0077) != 0)
1338 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Private key file is readable by more than the root user");
1340 m
->private_key
= PEM_read_PrivateKey(f
, NULL
, NULL
, NULL
);
1341 if (!m
->private_key
)
1342 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to load private key pair");
1344 log_info("Successfully loaded private key pair.");
1349 static int manager_generate_key_pair(Manager
*m
) {
1350 _cleanup_(EVP_PKEY_CTX_freep
) EVP_PKEY_CTX
*ctx
= NULL
;
1351 _cleanup_(unlink_and_freep
) char *temp_public
= NULL
, *temp_private
= NULL
;
1352 _cleanup_fclose_
FILE *fpublic
= NULL
, *fprivate
= NULL
;
1355 if (m
->private_key
) {
1356 EVP_PKEY_free(m
->private_key
);
1357 m
->private_key
= NULL
;
1360 ctx
= EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519
, NULL
);
1362 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to allocate Ed25519 key generation context.");
1364 if (EVP_PKEY_keygen_init(ctx
) <= 0)
1365 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to initialize Ed25519 key generation context.");
1367 log_info("Generating key pair for signing local user identity records.");
1369 if (EVP_PKEY_keygen(ctx
, &m
->private_key
) <= 0)
1370 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to generate Ed25519 key pair");
1372 log_info("Successfully created Ed25519 key pair.");
1374 (void) mkdir_p("/var/lib/systemd/home", 0755);
1376 /* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */
1377 r
= fopen_temporary("/var/lib/systemd/home/local.public", &fpublic
, &temp_public
);
1379 return log_error_errno(r
, "Failed to open key file for writing: %m");
1381 if (PEM_write_PUBKEY(fpublic
, m
->private_key
) <= 0)
1382 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to write public key.");
1384 (void) fchmod(fileno(fpublic
), 0444); /* Make public key world readable */
1386 r
= fflush_sync_and_check(fpublic
);
1388 return log_error_errno(r
, "Failed to write private key: %m");
1390 fpublic
= safe_fclose(fpublic
);
1392 /* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */
1393 r
= fopen_temporary("/var/lib/systemd/home/local.private", &fprivate
, &temp_private
);
1395 return log_error_errno(r
, "Failed to open key file for writing: %m");
1397 if (PEM_write_PrivateKey(fprivate
, m
->private_key
, NULL
, NULL
, 0, NULL
, NULL
) <= 0)
1398 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to write private key pair.");
1400 (void) fchmod(fileno(fprivate
), 0400); /* Make private key root readable */
1402 r
= fflush_sync_and_check(fprivate
);
1404 return log_error_errno(r
, "Failed to write private key: %m");
1406 fprivate
= safe_fclose(fprivate
);
1408 /* Both are written now, move them into place */
1410 if (rename(temp_public
, "/var/lib/systemd/home/local.public") < 0)
1411 return log_error_errno(errno
, "Failed to move public key file into place: %m");
1412 temp_public
= mfree(temp_public
);
1414 r
= RET_NERRNO(rename(temp_private
, "/var/lib/systemd/home/local.private"));
1416 (void) unlink("/var/lib/systemd/home/local.public"); /* try to remove the file we already created */
1417 return log_error_errno(r
, "Failed to move private key file into place: %m");
1419 temp_private
= mfree(temp_private
);
1421 r
= fsync_path_at(AT_FDCWD
, "/var/lib/systemd/home/");
1423 log_warning_errno(r
, "Failed to sync /var/lib/systemd/home/, ignoring: %m");
1428 int manager_acquire_key_pair(Manager
*m
) {
1433 /* Already there? */
1437 /* First try to load key off disk */
1438 r
= manager_load_key_pair(m
);
1442 /* Didn't work, generate a new one */
1443 return manager_generate_key_pair(m
);
1446 int manager_sign_user_record(Manager
*m
, UserRecord
*u
, UserRecord
**ret
, sd_bus_error
*error
) {
1453 r
= manager_acquire_key_pair(m
);
1457 return sd_bus_error_set(error
, BUS_ERROR_NO_PRIVATE_KEY
, "Can't sign without local key.");
1459 return user_record_sign(u
, m
->private_key
, ret
);
1462 DEFINE_HASH_OPS_FULL(public_key_hash_ops
, char, string_hash_func
, string_compare_func
, free
, EVP_PKEY
, EVP_PKEY_free
);
1464 static int manager_load_public_key_one(Manager
*m
, const char *path
) {
1465 _cleanup_(EVP_PKEY_freep
) EVP_PKEY
*pkey
= NULL
;
1466 _cleanup_fclose_
FILE *f
= NULL
;
1467 _cleanup_free_
char *fn
= NULL
;
1473 r
= path_extract_filename(path
, &fn
);
1475 return log_error_errno(r
, "Failed to extract filename of path '%s': %m", path
);
1477 if (streq(fn
, "local.public")) /* we already loaded the private key, which includes the public one */
1480 f
= fopen(path
, "re");
1482 if (errno
== ENOENT
)
1485 return log_error_errno(errno
, "Failed to open public key %s: %m", path
);
1488 if (fstat(fileno(f
), &st
) < 0)
1489 return log_error_errno(errno
, "Failed to stat public key %s: %m", path
);
1491 r
= stat_verify_regular(&st
);
1493 return log_error_errno(r
, "Public key file %s is not a regular file: %m", path
);
1495 if (st
.st_uid
!= 0 || (st
.st_mode
& 0022) != 0)
1496 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Public key file %s is writable by more than the root user, refusing.", path
);
1498 pkey
= PEM_read_PUBKEY(f
, &pkey
, NULL
, NULL
);
1500 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to parse public key file %s.", path
);
1502 r
= hashmap_ensure_put(&m
->public_keys
, &public_key_hash_ops
, fn
, pkey
);
1504 return log_error_errno(r
, "Failed to add public key to set: %m");
1512 static int manager_load_public_keys(Manager
*m
) {
1513 _cleanup_strv_free_
char **files
= NULL
;
1518 m
->public_keys
= hashmap_free(m
->public_keys
);
1520 r
= conf_files_list_nulstr(
1524 CONF_FILES_REGULAR
|CONF_FILES_FILTER_MASKED
,
1527 return log_error_errno(r
, "Failed to assemble list of public key directories: %m");
1529 STRV_FOREACH(i
, files
)
1530 (void) manager_load_public_key_one(m
, *i
);
1535 int manager_startup(Manager
*m
) {
1540 r
= manager_listen_notify(m
);
1544 r
= manager_connect_bus(m
);
1548 r
= manager_bind_varlink(m
);
1552 r
= manager_load_key_pair(m
); /* only try to load it, don't generate any */
1556 r
= manager_load_public_keys(m
);
1560 manager_watch_home(m
);
1561 (void) manager_watch_devices(m
);
1563 (void) manager_enumerate_records(m
);
1564 (void) manager_enumerate_images(m
);
1565 (void) manager_enumerate_devices(m
);
1567 /* Let's clean up home directories whose devices got removed while we were not running */
1568 (void) manager_enqueue_gc(m
, NULL
);
1570 /* Let's clean up blob directories for home dirs that no longer exist */
1571 (void) manager_gc_blob(m
);
1576 void manager_revalidate_image(Manager
*m
, Home
*h
) {
1582 /* Frees an automatically discovered image, if it's synthetic and its image disappeared. Unmounts any
1583 * image if it's mounted but its image vanished. */
1585 if (h
->current_operation
|| !ordered_set_isempty(h
->pending_operations
))
1588 if (h
->state
== HOME_UNFIXATED
) {
1589 r
= user_record_test_image_path(h
->record
);
1591 log_warning_errno(r
, "Can't determine if image of %s exists, freeing unfixated user: %m", h
->user_name
);
1592 else if (r
== USER_TEST_ABSENT
)
1593 log_info("Image for %s disappeared, freeing unfixated user.", h
->user_name
);
1599 } else if (h
->state
< 0) {
1601 r
= user_record_test_home_directory(h
->record
);
1603 log_warning_errno(r
, "Unable to determine state of home directory, ignoring: %m");
1607 if (r
== USER_TEST_MOUNTED
) {
1608 r
= user_record_test_image_path(h
->record
);
1610 log_warning_errno(r
, "Unable to determine state of image path, ignoring: %m");
1614 if (r
== USER_TEST_ABSENT
) {
1615 _cleanup_(operation_unrefp
) Operation
*o
= NULL
;
1617 log_notice("Backing image disappeared while home directory %s was mounted, unmounting it forcibly.", h
->user_name
);
1618 /* Wowza, the thing is mounted, but the device is gone? Act on it. */
1620 r
= home_killall(h
);
1622 log_warning_errno(r
, "Failed to kill processes of user %s, ignoring: %m", h
->user_name
);
1624 /* We enqueue the operation here, after all the home directory might
1625 * currently already run some operation, and we can deactivate it only after
1626 * that's complete. */
1627 o
= operation_new(OPERATION_DEACTIVATE_FORCE
, NULL
);
1633 r
= home_schedule_operation(h
, o
, NULL
);
1635 log_warning_errno(r
, "Failed to enqueue forced home directory %s deactivation, ignoring: %m", h
->user_name
);
1641 int manager_gc_images(Manager
*m
) {
1647 /* Focus on a specific home */
1649 h
= TAKE_PTR(m
->gc_focus
);
1650 manager_revalidate_image(m
, h
);
1654 HASHMAP_FOREACH(h
, m
->homes_by_uid
)
1655 manager_revalidate_image(m
, h
);
1661 static int manager_gc_blob(Manager
*m
) {
1662 _cleanup_closedir_
DIR *d
= NULL
;
1667 d
= opendir(home_system_blob_dir());
1669 if (errno
== ENOENT
)
1671 return log_error_errno(errno
, "Failed to open %s: %m", home_system_blob_dir());
1674 FOREACH_DIRENT(de
, d
, return log_error_errno(errno
, "Failed to read system blob directory: %m")) {
1675 Home
*found
= hashmap_get(m
->homes_by_name
, de
->d_name
);
1676 if (!found
|| !streq(found
->user_name
, de
->d_name
)) {
1677 r
= rm_rf_at(dirfd(d
), de
->d_name
, REMOVE_ROOT
|REMOVE_PHYSICAL
|REMOVE_SUBVOLUME
);
1679 log_warning_errno(r
, "Failed to delete blob dir for missing user '%s', ignoring: %m", de
->d_name
);
1686 static int on_deferred_rescan(sd_event_source
*s
, void *userdata
) {
1687 Manager
*m
= ASSERT_PTR(userdata
);
1689 m
->deferred_rescan_event_source
= sd_event_source_disable_unref(m
->deferred_rescan_event_source
);
1691 manager_enumerate_devices(m
);
1692 manager_enumerate_images(m
);
1696 int manager_enqueue_rescan(Manager
*m
) {
1701 if (m
->deferred_rescan_event_source
)
1707 if (IN_SET(sd_event_get_state(m
->event
), SD_EVENT_FINISHED
, SD_EVENT_EXITING
))
1710 r
= sd_event_add_defer(m
->event
, &m
->deferred_rescan_event_source
, on_deferred_rescan
, m
);
1712 return log_error_errno(r
, "Failed to allocate rescan event source: %m");
1714 r
= sd_event_source_set_priority(m
->deferred_rescan_event_source
, SD_EVENT_PRIORITY_IDLE
+1);
1716 log_warning_errno(r
, "Failed to tweak priority of event source, ignoring: %m");
1718 (void) sd_event_source_set_description(m
->deferred_rescan_event_source
, "deferred-rescan");
1722 static int on_deferred_gc(sd_event_source
*s
, void *userdata
) {
1723 Manager
*m
= ASSERT_PTR(userdata
);
1725 m
->deferred_gc_event_source
= sd_event_source_disable_unref(m
->deferred_gc_event_source
);
1727 manager_gc_images(m
);
1731 int manager_enqueue_gc(Manager
*m
, Home
*focus
) {
1736 /* This enqueues a request to GC dead homes. It may be called with focus=NULL in which case all homes
1737 * will be scanned, or with the parameter set, in which case only that home is checked. */
1742 if (IN_SET(sd_event_get_state(m
->event
), SD_EVENT_FINISHED
, SD_EVENT_EXITING
))
1745 /* If a focus home is specified, then remember to focus just on this home. Otherwise invalidate any
1746 * focus that might be set to look at all homes. */
1748 if (m
->deferred_gc_event_source
) {
1749 if (m
->gc_focus
!= focus
) /* not the same focus, then look at everything */
1754 m
->gc_focus
= focus
; /* start focused */
1756 r
= sd_event_add_defer(m
->event
, &m
->deferred_gc_event_source
, on_deferred_gc
, m
);
1758 return log_error_errno(r
, "Failed to allocate GC event source: %m");
1760 r
= sd_event_source_set_priority(m
->deferred_gc_event_source
, SD_EVENT_PRIORITY_IDLE
);
1762 log_warning_errno(r
, "Failed to tweak priority of event source, ignoring: %m");
1764 (void) sd_event_source_set_description(m
->deferred_gc_event_source
, "deferred-gc");
1768 static bool manager_shall_rebalance(Manager
*m
) {
1773 if (IN_SET(m
->rebalance_state
, REBALANCE_PENDING
, REBALANCE_SHRINKING
, REBALANCE_GROWING
))
1776 HASHMAP_FOREACH(h
, m
->homes_by_uid
)
1777 if (home_shall_rebalance(h
))
1783 static int home_cmp(Home
*const*a
, Home
*const*b
) {
1791 /* Order user records by their weight (and by their name, to make things stable). We put the records
1792 * with the highest weight last, since we distribute space from the beginning and round down, hence
1793 * later entries tend to get slightly more than earlier entries. */
1795 r
= CMP(user_record_rebalance_weight((*a
)->record
), user_record_rebalance_weight((*b
)->record
));
1799 return strcmp((*a
)->user_name
, (*b
)->user_name
);
1802 static int manager_rebalance_calculate(Manager
*m
) {
1803 uint64_t weight_sum
, free_sum
, usage_sum
= 0, min_free
= UINT64_MAX
;
1804 _cleanup_free_ Home
**array
= NULL
;
1805 bool relevant
= false;
1812 if (statfs(get_home_root(), &sfs
) < 0)
1813 return log_error_errno(errno
, "Failed to statfs() /home: %m");
1815 free_sum
= (uint64_t) sfs
.f_bsize
* sfs
.f_bavail
; /* This much free space is available on the
1816 * underlying pool directory */
1818 weight_sum
= REBALANCE_WEIGHT_BACKING
; /* Grant the underlying pool directory a fixed weight of 20
1819 * (home dirs get 100 by default, i.e. 5x more). This weight
1820 * is not configurable, the per-home weights are. */
1822 HASHMAP_FOREACH(h
, m
->homes_by_uid
) {
1823 statfs_f_type_t fstype
;
1824 h
->rebalance_pending
= false; /* First, reset the flag, we only want it to be true for the
1825 * homes that qualify for rebalancing */
1827 if (!home_shall_rebalance(h
)) /* Only look at actual candidates */
1830 if (home_is_busy(h
))
1831 return -EBUSY
; /* Let's not rebalance if there's a busy home directory. */
1833 r
= home_get_disk_status(
1836 &h
->rebalance_usage
,
1843 log_warning_errno(r
, "Failed to get free space of home '%s', ignoring.", h
->user_name
);
1847 if (h
->rebalance_free
> UINT64_MAX
- free_sum
)
1848 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW
), "Rebalance free overflow");
1849 free_sum
+= h
->rebalance_free
;
1851 if (h
->rebalance_usage
> UINT64_MAX
- usage_sum
)
1852 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW
), "Rebalance usage overflow");
1853 usage_sum
+= h
->rebalance_usage
;
1855 h
->rebalance_weight
= user_record_rebalance_weight(h
->record
);
1856 if (h
->rebalance_weight
> UINT64_MAX
- weight_sum
)
1857 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW
), "Rebalance weight overflow");
1858 weight_sum
+= h
->rebalance_weight
;
1860 h
->rebalance_min
= minimal_size_by_fs_magic(fstype
);
1862 if (!GREEDY_REALLOC(array
, c
+1))
1869 log_debug("No homes to rebalance.");
1873 assert(weight_sum
> 0);
1875 log_debug("Disk space usage by all home directories to rebalance: %s — available disk space: %s",
1876 FORMAT_BYTES(usage_sum
), FORMAT_BYTES(free_sum
));
1878 /* Bring the home directories in a well-defined order, so that we distribute space in a reproducible
1879 * way for the same parameters. */
1880 typesafe_qsort(array
, c
, home_cmp
);
1882 for (int i
= 0; i
< c
; i
++) {
1888 assert(h
->rebalance_free
<= free_sum
);
1889 assert(h
->rebalance_usage
<= usage_sum
);
1890 assert(h
->rebalance_weight
<= weight_sum
);
1892 d
= ((double) (free_sum
/ 4096) * (double) h
->rebalance_weight
) / (double) weight_sum
; /* Calculate new space for this home in units of 4K */
1894 /* Convert from units of 4K back to bytes */
1895 if (d
>= (double) (UINT64_MAX
/4096))
1896 new_free
= UINT64_MAX
;
1898 new_free
= (uint64_t) d
* 4096;
1900 /* Subtract the weight and assigned space from the sums now, to distribute the rounding noise
1901 * to the remaining home dirs */
1902 free_sum
= LESS_BY(free_sum
, new_free
);
1903 weight_sum
= LESS_BY(weight_sum
, h
->rebalance_weight
);
1905 /* Keep track of home directory with the least amount of space left: we want to schedule the
1906 * next rebalance more quickly if this is low */
1907 if (new_free
< min_free
)
1908 min_free
= h
->rebalance_size
;
1910 if (new_free
> UINT64_MAX
- h
->rebalance_usage
)
1911 h
->rebalance_goal
= UINT64_MAX
-1; /* maximum size */
1913 h
->rebalance_goal
= h
->rebalance_usage
+ new_free
;
1915 if (h
->rebalance_min
!= UINT64_MAX
&& h
->rebalance_goal
< h
->rebalance_min
)
1916 h
->rebalance_goal
= h
->rebalance_min
;
1919 /* Skip over this home if the state doesn't match the operation */
1920 if ((m
->rebalance_state
== REBALANCE_SHRINKING
&& h
->rebalance_goal
> h
->rebalance_size
) ||
1921 (m
->rebalance_state
== REBALANCE_GROWING
&& h
->rebalance_goal
< h
->rebalance_size
))
1922 h
->rebalance_pending
= false;
1924 log_debug("Rebalancing home directory '%s' %s %s %s.", h
->user_name
,
1925 FORMAT_BYTES(h
->rebalance_size
),
1926 glyph(GLYPH_ARROW_RIGHT
),
1927 FORMAT_BYTES(h
->rebalance_goal
));
1928 h
->rebalance_pending
= true;
1931 if ((fabs((double) h
->rebalance_size
- (double) h
->rebalance_goal
) * 100 / (double) h
->rebalance_size
) >= 5.0)
1935 /* Scale next rebalancing interval based on the least amount of space of any of the home
1936 * directories. We pick a time in the range 1min … 15min, scaled by log2(min_free), so that:
1937 * 10M → ~0.7min, 100M → ~2.7min, 1G → ~4.6min, 10G → ~6.5min, 100G ~8.4 */
1938 m
->rebalance_interval_usec
= (usec_t
) CLAMP((LESS_BY(log2(min_free
), 22)*15*USEC_PER_MINUTE
)/26,
1939 1 * USEC_PER_MINUTE
,
1940 15 * USEC_PER_MINUTE
);
1942 log_debug("Rebalancing interval set to %s.", FORMAT_TIMESPAN(m
->rebalance_interval_usec
, USEC_PER_MSEC
));
1944 /* Let's suppress small resizes, growing/shrinking file systems isn't free after all */
1946 log_debug("Skipping rebalancing, since all calculated size changes are below ±5%%.");
1953 static int manager_rebalance_apply(Manager
*m
) {
1959 HASHMAP_FOREACH(h
, m
->homes_by_uid
) {
1960 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1962 if (!h
->rebalance_pending
)
1965 h
->rebalance_pending
= false;
1967 r
= home_resize(h
, h
->rebalance_goal
, /* secret= */ NULL
, &error
);
1969 log_warning_errno(r
, "Failed to resize home '%s' for rebalancing, ignoring: %s",
1970 h
->user_name
, bus_error_message(&error
, r
));
1978 static void manager_rebalance_reply_messages(Manager
*m
) {
1984 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*msg
=
1985 set_steal_first(m
->rebalance_pending_method_calls
);
1990 r
= sd_bus_reply_method_return(msg
, NULL
);
1992 log_debug_errno(r
, "Failed to reply to rebalance method call, ignoring: %m");
1996 static int manager_rebalance_now(Manager
*m
) {
1997 RebalanceState busy_state
; /* the state to revert to when operation fails if busy */
2002 log_debug("Rebalancing now...");
2004 /* We maintain a simple state engine here to keep track of what we are doing. We'll first shrink all
2005 * homes that shall be shrunk and then grow all homes that shall be grown, so that they can take up
2006 * the space now freed. */
2009 switch (m
->rebalance_state
) {
2011 case REBALANCE_IDLE
:
2012 case REBALANCE_PENDING
:
2013 case REBALANCE_WAITING
:
2014 /* First shrink large home dirs */
2015 m
->rebalance_state
= REBALANCE_SHRINKING
;
2016 busy_state
= REBALANCE_PENDING
;
2018 /* We are initiating the next rebalancing cycle now, let's make the queued methods
2019 * calls the pending ones, and flush out any pending ones (which shouldn't exist at
2020 * this time anyway) */
2021 set_clear(m
->rebalance_pending_method_calls
);
2022 SWAP_TWO(m
->rebalance_pending_method_calls
, m
->rebalance_queued_method_calls
);
2024 log_debug("Shrinking phase..");
2027 case REBALANCE_SHRINKING
:
2028 /* Then grow small home dirs */
2029 m
->rebalance_state
= REBALANCE_GROWING
;
2030 busy_state
= REBALANCE_SHRINKING
;
2031 log_debug("Growing phase..");
2034 case REBALANCE_GROWING
:
2035 /* Finally, we are done */
2036 log_info("Rebalancing complete.");
2037 m
->rebalance_state
= REBALANCE_IDLE
;
2043 assert_not_reached();
2046 r
= manager_rebalance_calculate(m
);
2048 /* Calculations failed because one home directory is currently busy. Revert to a state that
2049 * tells us what to do next. */
2050 log_debug("Can't enter phase, busy.");
2051 m
->rebalance_state
= busy_state
;
2057 continue; /* got to next step immediately, if there's nothing to do */
2059 r
= manager_rebalance_apply(m
);
2063 break; /* At least one resize operation is now pending, we are done for now */
2065 /* If there was nothing to apply, go for next state right-away */
2071 /* Reset state and schedule next rebalance */
2072 m
->rebalance_state
= REBALANCE_IDLE
;
2073 manager_rebalance_reply_messages(m
);
2074 (void) manager_schedule_rebalance(m
, /* immediately= */ false);
2078 static int on_rebalance_timer(sd_event_source
*s
, usec_t t
, void *userdata
) {
2079 Manager
*m
= ASSERT_PTR(userdata
);
2082 assert(IN_SET(m
->rebalance_state
, REBALANCE_WAITING
, REBALANCE_PENDING
, REBALANCE_SHRINKING
, REBALANCE_GROWING
));
2084 (void) manager_rebalance_now(m
);
2088 int manager_schedule_rebalance(Manager
*m
, bool immediately
) {
2093 /* Check if there are any records where rebalancing is requested */
2094 if (!manager_shall_rebalance(m
)) {
2095 log_debug("Not scheduling rebalancing, not needed.");
2096 r
= 0; /* report that we didn't schedule anything because nothing needed it */
2101 /* If we are told to rebalance immediately, then mark a rebalance as pending (even if we area
2102 * already running one) */
2104 if (m
->rebalance_event_source
) {
2105 r
= sd_event_source_set_time(m
->rebalance_event_source
, 0);
2107 log_error_errno(r
, "Failed to schedule immediate rebalancing: %m");
2111 r
= sd_event_source_set_enabled(m
->rebalance_event_source
, SD_EVENT_ONESHOT
);
2113 log_error_errno(r
, "Failed to enable rebalancing event source: %m");
2117 r
= sd_event_add_time(m
->event
, &m
->rebalance_event_source
, CLOCK_MONOTONIC
, 0, USEC_PER_SEC
, on_rebalance_timer
, m
);
2119 log_error_errno(r
, "Failed to allocate rebalance event source: %m");
2123 r
= sd_event_source_set_priority(m
->rebalance_event_source
, SD_EVENT_PRIORITY_IDLE
+ 10);
2125 log_error_errno(r
, "Failed to set rebalance event source priority: %m");
2129 (void) sd_event_source_set_description(m
->rebalance_event_source
, "rebalance");
2133 if (!IN_SET(m
->rebalance_state
, REBALANCE_PENDING
, REBALANCE_SHRINKING
, REBALANCE_GROWING
))
2134 m
->rebalance_state
= REBALANCE_PENDING
;
2136 log_debug("Scheduled immediate rebalancing...");
2137 return 1; /* report that we scheduled something */
2140 /* If we are told to schedule a rebalancing eventually, then do so only if we are not executing
2141 * anything yet. Also if we have something scheduled already, leave it in place */
2142 if (!IN_SET(m
->rebalance_state
, REBALANCE_OFF
, REBALANCE_IDLE
))
2143 return 1; /* report that there's already something scheduled */
2145 if (m
->rebalance_event_source
) {
2146 r
= sd_event_source_set_time_relative(m
->rebalance_event_source
, m
->rebalance_interval_usec
);
2148 log_error_errno(r
, "Failed to schedule immediate rebalancing: %m");
2152 r
= sd_event_source_set_enabled(m
->rebalance_event_source
, SD_EVENT_ONESHOT
);
2154 log_error_errno(r
, "Failed to enable rebalancing event source: %m");
2158 r
= sd_event_add_time_relative(m
->event
, &m
->rebalance_event_source
, CLOCK_MONOTONIC
, m
->rebalance_interval_usec
, USEC_PER_SEC
, on_rebalance_timer
, m
);
2160 log_error_errno(r
, "Failed to allocate rebalance event source: %m");
2164 r
= sd_event_source_set_priority(m
->rebalance_event_source
, SD_EVENT_PRIORITY_IDLE
+ 10);
2166 log_error_errno(r
, "Failed to set rebalance event source priority: %m");
2170 (void) sd_event_source_set_description(m
->rebalance_event_source
, "rebalance");
2173 m
->rebalance_state
= REBALANCE_WAITING
; /* We managed to enqueue a timer event, we now wait until it fires */
2174 log_debug("Scheduled rebalancing in %s...", FORMAT_TIMESPAN(m
->rebalance_interval_usec
, 0));
2175 return 1; /* report that we scheduled something */
2178 m
->rebalance_event_source
= sd_event_source_disable_unref(m
->rebalance_event_source
);
2179 m
->rebalance_state
= REBALANCE_OFF
;
2180 manager_rebalance_reply_messages(m
);
2184 int manager_reschedule_rebalance(Manager
*m
) {
2189 /* If a rebalance is pending reschedules it so it gets executed immediately */
2191 if (!IN_SET(m
->rebalance_state
, REBALANCE_PENDING
, REBALANCE_SHRINKING
, REBALANCE_GROWING
))
2194 r
= manager_schedule_rebalance(m
, /* immediately= */ true);
2201 int manager_get_home_by_name(Manager
*m
, const char *user_name
, Home
**ret
) {
2205 Home
*h
= hashmap_get(m
->homes_by_name
, user_name
);
2207 /* Also search by username and realm. For that simply chop off realm, then look for the home, and verify it afterwards. */
2208 const char *realm
= strrchr(user_name
, '@');
2210 _cleanup_free_
char *prefix
= strndup(user_name
, realm
- user_name
);
2215 j
= hashmap_get(m
->homes_by_name
, prefix
);
2216 if (j
&& user_record_matches_user_name(j
->record
, user_name
))